summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2010-03-15 16:53:09 +0000
committermarcel <marcel@FreeBSD.org>2010-03-15 16:53:09 +0000
commit38cee4c83776b6f4640b4208f3664e106e2bfc5d (patch)
treec51cc5032a4e3717845532356522fc71f4db5051 /sys/ia64
parentea8a7d9989118e36e5add07b1f158efe5e5782d0 (diff)
downloadFreeBSD-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.c25
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");
OpenPOWER on IntegriCloud