alpha/85346: PREEMPTION causes unstability in Alpha4000 SMP
kernel
John Baldwin
jhb at FreeBSD.org
Wed Sep 21 12:20:12 PDT 2005
The following reply was made to PR alpha/85346; it has been noted by GNATS.
From: John Baldwin <jhb at FreeBSD.org>
To: bug-followup at FreeBSD.org,
ken at alicorntech.com
Cc:
Subject: Re: alpha/85346: PREEMPTION causes unstability in Alpha4000 SMP kernel
Date: Wed, 21 Sep 2005 15:17:01 -0400
Hmm, I still don't run with PREEMPTION enabled on my DS20 on HEAD. In my
experience I haven't gotten any panics, just hard locks when I have enabled
PREEMPTION and SMP on Alpha. You can try testing this patch to see if it
helps things at all though:
--- //depot/projects/smpng/sys/alpha/alpha/interrupt.c 2005/04/14 18:55:16
+++ //depot/user/jhb/preemption/alpha/alpha/interrupt.c 2005/04/14 19:32:16
@@ -427,6 +427,13 @@
atomic_add_long(i->cntp, 1);
/*
+ * It seems that we need to return from an interrupt back to PAL
+ * on the same CPU that received the interrupt, so pin the interrupted
+ * thread to the current CPU until we return from the interrupt.
+ */
+ sched_pin();
+
+ /*
* Handle a fast interrupt if there is no actual thread for this
* interrupt by calling the handler directly without Giant. Note
* that this means that any fast interrupt handler must be MP safe.
@@ -435,26 +442,18 @@
if ((ih->ih_flags & IH_FAST) != 0) {
critical_enter();
ih->ih_handler(ih->ih_argument);
- /* XXX */
- curthread->td_owepreempt = 0;
critical_exit();
- return;
- }
+ } else {
+ if (ithd->it_disable) {
+ CTR1(KTR_INTR,
+ "alpha_dispatch_intr: disabling vector 0x%x",
+ i->vector);
+ ithd->it_disable(ithd->it_vector);
+ }
- if (ithd->it_disable) {
- CTR1(KTR_INTR,
- "alpha_dispatch_intr: disabling vector 0x%x", i->vector);
- ithd->it_disable(ithd->it_vector);
+ error = ithread_schedule(ithd);
+ KASSERT(error == 0, ("got an impossible stray interrupt"));
}
-
- /*
- * It seems that we need to return from an interrupt back to PAL
- * on the same CPU that received the interrupt, so pin the interrupted
- * thread to the current CPU until we return from the interrupt.
- */
- sched_pin();
- error = ithread_schedule(ithd);
- KASSERT(error == 0, ("got an impossible stray interrupt"));
sched_unpin();
}
--- //depot/projects/smpng/sys/kern/kern_thread.c 2005/05/27 14:58:46
+++ //depot/user/jhb/preemption/kern/kern_thread.c 2005/05/27 19:03:12
@@ -955,9 +957,11 @@
mtx_assert(&sched_lock, MA_OWNED);
PROC_LOCK_ASSERT(p, MA_OWNED);
if (!P_SHOULDSTOP(p)) {
+ critical_enter();
while ((td = TAILQ_FIRST(&p->p_suspended))) {
thread_unsuspend_one(td);
}
+ critical_exit();
} else if ((P_SHOULDSTOP(p) == P_STOPPED_SINGLE) &&
(p->p_numthreads == p->p_suspcount)) {
/*
@@ -992,9 +996,11 @@
* to continue however as this is a bad place to stop.
*/
if ((p->p_numthreads != 1) && (!P_SHOULDSTOP(p))) {
+ critical_enter();
while ((td = TAILQ_FIRST(&p->p_suspended))) {
thread_unsuspend_one(td);
}
+ critical_exit();
}
mtx_unlock_spin(&sched_lock);
}
--- //depot/projects/smpng/sys/kern/subr_sleepqueue.c 2005/09/15 19:40:43
+++ //depot/user/jhb/preemption/kern/subr_sleepqueue.c 2005/09/15 20:09:55
@@ -410,9 +410,10 @@
* just return.
*/
if (td->td_sleepqueue != NULL) {
- MPASS(!TD_ON_SLEEPQ(td));
mtx_unlock_spin(&sc->sc_lock);
mtx_lock_spin(&sched_lock);
+ MPASS(!TD_ON_SLEEPQ(td));
+ MPASS(!TD_IS_SLEEPING(td));
return;
}
--- //depot/projects/smpng/sys/vm/vm_glue.c 2005/05/27 14:58:46
+++ //depot/user/jhb/preemption/vm/vm_glue.c 2005/05/27 19:03:12
@@ -556,6 +556,7 @@
vm_thread_swapin(td);
PROC_LOCK(p);
+ critical_enter();
mtx_lock_spin(&sched_lock);
p->p_sflag &= ~PS_SWAPPINGIN;
p->p_sflag |= PS_INMEM;
@@ -570,6 +571,7 @@
/* Allow other threads to swap p out now. */
--p->p_lock;
+ critical_exit();
}
#endif /* NO_SWAPPING */
}
--
John Baldwin <jhb at FreeBSD.org> <>< http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve" = http://www.FreeBSD.org
More information about the freebsd-alpha
mailing list