Thanks to the evil Intel AMT serial, I've been able to figure out what
made my x220 hang when suspending.  Turns out that the fix matthew@
committed almost two weeks ago uncovered another bug that made
sched_stop_secondary_cpus() spin forever if there was a processing
running on a secondary cpu but nothing left on the run qeueue.  In
that case sched_choosecpu() short-circuits and returns the current
cpu.  The fix is obvious: don't short-circuit when we're on a cpu that
should stop.

ok?


Index: kern_sched.c
===================================================================
RCS file: /home/cvs/src/sys/kern/kern_sched.c,v
retrieving revision 1.33
diff -u -p -r1.33 kern_sched.c
--- kern_sched.c        13 Jul 2014 21:44:58 -0000      1.33
+++ kern_sched.c        26 Jul 2014 11:44:26 -0000
@@ -275,6 +275,7 @@ sched_chooseproc(void)
                                while ((p = TAILQ_FIRST(&spc->spc_qs[queue]))) {
                                        remrunqueue(p);
                                        p->p_cpu = sched_choosecpu(p);
+                                       KASSERT(p->p_cpu != curcpu());
                                        setrunqueue(p);
                                }
                        }
@@ -408,6 +409,7 @@ sched_choosecpu(struct proc *p)
         */
        if (cpuset_isset(&set, p->p_cpu) ||
            (p->p_cpu == curcpu() && p->p_cpu->ci_schedstate.spc_nrun == 0 &&
+           (p->p_cpu->ci_schedstate.spc_schedflags & SPCF_SHOULDHALT) == 0 &&
            curproc == p)) {
                sched_wasidle++;
                return (p->p_cpu);

Reply via email to