From 510e1af7cb74588b5c24e74c89e4bf8572b39e47 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 15 Mar 2010 16:53:09 +0000 Subject: [PATCH] Have cpu_throw() loop on blocked_lock as well. This bug has existed a long time and has gone unnoticed just as long, because I kept using sched_4bsd (due to sched_ule not working with preemption), but GENERIC had sched_ule by default -- including SMP. While here, remove unused inclusion of , remove totally bogus inclusion of . --- sys/ia64/ia64/machdep.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index cb64f7fc804a..ed7a288e0c24 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -100,8 +99,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - SYSCTL_NODE(_hw, OID_AUTO, freq, CTLFLAG_RD, 0, ""); SYSCTL_NODE(_machdep, OID_AUTO, cpu, CTLFLAG_RD, 0, ""); @@ -450,18 +447,22 @@ cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx) old->td_frame->tf_special.psr |= IA64_PSR_DFH; if (!savectx(oldpcb)) { atomic_store_rel_ptr(&old->td_lock, mtx); -#if defined(SCHED_ULE) && defined(SMP) - /* td_lock is volatile */ - while (new->td_lock == &blocked_lock) - ; -#endif + newpcb = new->td_pcb; oldpcb->pcb_current_pmap = pmap_switch(newpcb->pcb_current_pmap); + +#if defined(SCHED_ULE) && defined(SMP) + while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock) + cpu_spinwait(); +#endif + PCPU_SET(curthread, new); + #ifdef COMPAT_FREEBSD32 ia32_restorectx(newpcb); #endif + if (PCPU_GET(fpcurthread) == new) new->td_frame->tf_special.psr &= ~IA64_PSR_DFH; restorectx(newpcb); @@ -478,10 +479,18 @@ cpu_throw(struct thread *old __unused, struct thread *new) newpcb = new->td_pcb; (void)pmap_switch(newpcb->pcb_current_pmap); + +#if defined(SCHED_ULE) && defined(SMP) + while (atomic_load_acq_ptr(&new->td_lock) == &blocked_lock) + cpu_spinwait(); +#endif + PCPU_SET(curthread, new); + #ifdef COMPAT_FREEBSD32 ia32_restorectx(newpcb); #endif + restorectx(newpcb); /* We should not get here. */ panic("cpu_throw: restorectx() returned");