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