Port-mips archive

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

matt-nb5-mips64 cpu_idle issue



Hi,
while working on a SMP platform using code based on the matt-nb5-mips64
branch, I ran in the following issue:
a lwp has been put to sleep on cpux, switching cpux to the idle lwp.
Another CPU wakes up the lwp while cpux is in mi_switch().
Now cpux is stuck in the idle loop, never noticing that another lwp is
runnable.

The reason is that cpu_idle() loops testing (ci->ci_want_resched),
but this is not enough to detect if another thread is ready to run
(several places do cpu_need_resched(ci, 0)). cpu_idle() is itself called
in a loop, which does more thing and especially call sched_curcpu_runnable_p()
to see if the idle lwp needs to switch to another lwp.
So cpu_idle() should do whatever is needed to put the CPU into sleep
waiting for an interrupt (if possible), but should not do so in a loop.
The attached patch still check for ci->ci_want_resched as x86 does, but
I'm not sure this is needed at all.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: cpu_subr.c
===================================================================
--- cpu_subr.c  (revision 66)
+++ cpu_subr.c  (working copy)
@@ -580,7 +580,7 @@
        void (*const mach_idle)(void) = mips_locoresw.lsw_cpu_idle;
        struct cpu_info * const ci = curcpu();
 
-       while (!ci->ci_want_resched) {
+       if (!__predict_false(ci->ci_want_resched)) {
                (*mach_idle)();
        }
 }


Home | Main Index | Thread Index | Old Index