diff options
author | marcel <marcel@FreeBSD.org> | 2010-03-15 16:53:09 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2010-03-15 16:53:09 +0000 |
commit | 38cee4c83776b6f4640b4208f3664e106e2bfc5d (patch) | |
tree | c51cc5032a4e3717845532356522fc71f4db5051 /sys/ia64 | |
parent | ea8a7d9989118e36e5add07b1f158efe5e5782d0 (diff) | |
download | FreeBSD-src-38cee4c83776b6f4640b4208f3664e106e2bfc5d.zip FreeBSD-src-38cee4c83776b6f4640b4208f3664e106e2bfc5d.tar.gz |
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 <machine/clock.h>, remove
totally bogus inclusion of <i386/include/specialreg.h>.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/machdep.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index cb64f7f..ed7a288 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_pager.h> #include <machine/bootinfo.h> -#include <machine/clock.h> #include <machine/cpu.h> #include <machine/efi.h> #include <machine/elf.h> @@ -100,8 +99,6 @@ __FBSDID("$FreeBSD$"); #include <machine/unwind.h> #include <machine/vmparam.h> -#include <i386/include/specialreg.h> - 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"); |