eventtimer issue on mips: temporary workaround
Jayachandran C.
c.jayachandran at gmail.com
Thu Sep 29 06:21:22 UTC 2011
On Wed, Sep 28, 2011 at 8:14 PM, Adrian Chadd <adrian at freebsd.org> wrote:
> Hi all,
>
> I've found that there's an issue with how mav@ shoehorned in event
> timer handling to mips.
>
> Basically, if a non-fast interrupt comes in after the critical_enter()
> call in cpu_idle() but before the wait instruction, it won't interrupt
> wait and it won't be serviced until the next interrupt ends the wait.
>
> For ath, since it's a netisr, this means the netisr won't be run until
> the next interrupt fires.
>
> Here's my temporary, not-quite-correct workaround. ray@ pointed out
> this from Linux:
>
> http://lxr.free-electrons.com/source/arch/mips/kernel/cpu-probe.c?a=sh
>
> .. which indicates that they're calling wait with interrupts masked.
> This apparently doesn't stop it breaking wait, it merely stops it from
> flipping to the interrupt handler.
Linux has many versions of wait, there is the r4k_wait in assembly
which keeps the interrupts enabled
http://lxr.free-electrons.com/source/arch/mips/kernel/genex.S#L131
The MIPS architecture manual says it is implementation-dependent
whether the non-enabled interrupt will make wait to continue.
> There are also a number of MIPS platform specific workarounds to implement idle.
>
> I'd really appreciate some feedback on this and hopefully a correct solution. :)
>
>
>
> Adrian
>
> Index: mips/machdep.c
> ===================================================================
> --- mips/machdep.c (revision 225610)
> +++ mips/machdep.c (working copy)
> @@ -497,7 +497,16 @@
> critical_enter();
> cpu_idleclock();
> }
> - __asm __volatile ("wait");
> +
> + intr_disable();
> + if (sched_runnable()) {
> + intr_enable();
> + } else {
> + /* XXX this isn't atomic! */
> + intr_enable();
> + __asm __volatile ("wait");
> + }
> +
> if (!busy) {
> cpu_activeclock();
> critical_exit();
JC.
More information about the freebsd-mips
mailing list