tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: API change request. Was => Re: Time accounting on statclock()



Cherry G.Mathew <cherry%zyx.in@localhost> writes:

> matthew green <mrg%eterna.com.au@localhost> writes:
>
> [...]
>
>>
>> what problem are you actually trying to solve?
>>
>
> Ok, so I think I now have enough info to compose everything into a
> coherent question.
>
> Motivation:
>
> Unifying XEN vector.S entry points with x86/ native ones.
>
> The catch here is that in PV mode, the interrupt entry point is a single
> address, which serves as a demultiplexer for one or more interrupts that
> have to be routed to this domain since the last time the hypervisor
> noticed.
>
> What needs to happen is that the demultiplexing function needs to scan a
> bitmap which contains the set of pending interrupts, and then do the
> regular mask/eoi/service/unmask dance which is time sensitive in ways
> that I haven't got my head around fully yet.
>
> Design:
>
> What I've done therefore is to use the queue/despatch pattern that other
> OSs use (OpenBSD's implementation is the closest to our codebase) so
> that the bitscan queues up handlers to be executed later, and when the
> demultiplexer is done, it can despatch the queued up handlers.
>
> What I quickly realised is that the spl(9) api is effectively a
> scheduler for pending interrupts, and can be effectively abused to do
> the queue/schedule dance.
>
> Implementation:
>
> Here's a snippet:
>
> +/* This is essentially a despatch function for queued interrupts */
> +static void
> +xen_despatch_events(struct cpu_info *ci)
> +{
> +       int i, spl;
> +       u_long psl;
> +
> +       spl = splraise(IPL_HYPERVISOR);
> +       /*
> +        * This bit uses spl(9) magic to brute force calling every
> +        * pending handler at every SPL level down to the interuptee.
> +        */
> +
> +       for (i = IPL_HYPERVISOR;ci->ci_ipending && i >= spl;i--) {
> +               psl = x86_read_psl();
> +
> +               x86_enable_intr();
> +               spllower(i);
> +               x86_write_psl(psl);
> +       }
> +       spllower(spl);
> +}
> +
> +static void
> +xen_queue_event(struct cpu_info *ci, unsigned long port)
> +{
> +
> +       /* Set pending bit for spl code 
> +        * effectively atomic_or_32(&ci->ci_ipending,
> +        * evtsource[port]->ev_imask);
> +        * + some xen glue
> +        */
> +
> +       hypervisor_set_ipending(evtsource[port]->ev_imask,
> +           port >> LONG_SHIFT, port & LONG_MASK);
> +
> +}
> +
>
> Problem:
>
> This works nicely - I tried it on -current and everything just works.
>
> EXCEPT
>
> hardclock(9) and friends inspect the trapframe for various queries. The
> ones I enumerated in our kernel are:
>
> CLKF_USERMODE(frame)
> CLKF_PC(frame)
> CLKF_INTR(frame)
>
> spllower(9) however invents its own stackframe based on the caller's
> stack context. This is problematic for the above abuse because
> spllower(9) is always called from kernel mode, the spllower() code
> returns via regular vector.S interrupt return mechanisms which means
> that we can't just mess with the stack frame here to fake what we want
> for, say a frame we want hardclock() to think came from usermode. (It
> will effectively return to kernel in user mode).
>
> Proposed solution:
>
> change hardclock(9) , statclock(9) and dtrace related hooks that use the
> interrupt frame to have the info they need passed in explicitly.
>
> For eg:
>
> void
> hardclock(struct clockframe *); changes to
>
> changes to:
>
> void
> hardclock(vaddr_t pc, bool usermode, bool intrp);
>
> Hope this makes sense.
>
> Many Thanks,

For now, I did a little arch specific (XEN) hack:
https://mail-index.netbsd.org/source-changes/2018/11/18/msg100702.html~

-- 
~cherry


Home | Main Index | Thread Index | Old Index