Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Sep 2011 11:29:23 +0530
From:      "Jayachandran C." <c.jayachandran@gmail.com>
To:        Adrian Chadd <adrian@freebsd.org>
Cc:        freebsd-mips@freebsd.org
Subject:   Re: eventtimer issue on mips: temporary workaround
Message-ID:  <CA%2B7sy7BAeG4bhwGqUR825grmVhCTU8H7rdb3EeDzudtTUKaeqA@mail.gmail.com>
In-Reply-To: <CAJ-Vmo=qONOffCTgusWtbwuo43zKYyXDqqu5YEaL-MDQSbt-mQ@mail.gmail.com>
References:  <CAJ-Vmo=qONOffCTgusWtbwuo43zKYyXDqqu5YEaL-MDQSbt-mQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Sep 28, 2011 at 8:14 PM, Adrian Chadd <adrian@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=3Dsh
>
> .. 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 implemen=
t idle.
>
> I'd really appreciate some feedback on this and hopefully a correct solut=
ion. :)
>
>
>
> Adrian
>
> Index: mips/machdep.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- mips/machdep.c =A0 =A0 =A0(revision 225610)
> +++ mips/machdep.c =A0 =A0 =A0(working copy)
> @@ -497,7 +497,16 @@
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0critical_enter();
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cpu_idleclock();
> =A0 =A0 =A0 =A0}
> - =A0 =A0 =A0 __asm __volatile ("wait");
> +
> + =A0 =A0 =A0 intr_disable();
> + =A0 =A0 =A0 if (sched_runnable()) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 intr_enable();
> + =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* XXX this isn't atomic! */
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 intr_enable();
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 __asm __volatile ("wait");
> + =A0 =A0 =A0 }
> +
> =A0 =A0 =A0 =A0if (!busy) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0cpu_activeclock();
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0critical_exit();

JC.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CA%2B7sy7BAeG4bhwGqUR825grmVhCTU8H7rdb3EeDzudtTUKaeqA>