summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2001-02-05 19:34:25 +0000
committerjhb <jhb@FreeBSD.org>2001-02-05 19:34:25 +0000
commitc490404e3ccc97cafbca72dbea4d6d91c451780c (patch)
tree82c03714cfc13cafe85b853be1eba8b8a105f5c6
parent86cb214594355ba9efe9aa0205cb878a8e8f3ecd (diff)
downloadFreeBSD-src-c490404e3ccc97cafbca72dbea4d6d91c451780c.zip
FreeBSD-src-c490404e3ccc97cafbca72dbea4d6d91c451780c.tar.gz
- Minimize the amount of duplicated code for the PREEMPTION #ifdef, it now
only covers about 3-4 lines. - Don't lower the IPL while we are on the interrupt stack. Instead, save the raised IPL and change the saved IPL in sched_lock to IPL_0 before calling mi_switch(). When we are resumed, restore the saved IPL in sched_lock to the saved raised IPL so that when we release sched_lock we won't lower the IPL. Without this, we would get nested interrupts that would overflow the kernel stack. Tested by: mjacob
-rw-r--r--sys/alpha/alpha/interrupt.c36
1 files changed, 9 insertions, 27 deletions
diff --git a/sys/alpha/alpha/interrupt.c b/sys/alpha/alpha/interrupt.c
index 3df42e9..57d0da5 100644
--- a/sys/alpha/alpha/interrupt.c
+++ b/sys/alpha/alpha/interrupt.c
@@ -504,6 +504,7 @@ alpha_dispatch_intr(void *frame, unsigned long vector)
int h = HASHVEC(vector);
struct alpha_intr *i;
struct ithd *ithd; /* our interrupt thread */
+ int saveintr;
/*
* Walk the hash bucket for this vector looking for this vector's
@@ -554,14 +555,11 @@ alpha_dispatch_intr(void *frame, unsigned long vector)
* is higher priority than their current thread, it gets run now.
*/
ithd->it_need = 1;
-#ifdef PREEMPTION
- /* Does not work on 4100 and PC164 */
if (i->disable) {
CTR1(KTR_INTR,
"alpha_dispatch_intr: disabling vector 0x%x", i->vector);
i->disable(i->vector);
}
- enable_intr();
mtx_enter(&sched_lock, MTX_SPIN);
if (ithd->it_proc->p_stat == SWAIT) {
/* not on the run queue and not running */
@@ -571,41 +569,25 @@ alpha_dispatch_intr(void *frame, unsigned long vector)
alpha_mb(); /* XXX - ??? */
ithd->it_proc->p_stat = SRUN;
setrunqueue(ithd->it_proc);
+#ifdef PREEMPTION
+ /* Does not work on 4100 and PC164 */
if (!cold) {
+ saveintr = sched_lock.mtx_saveintr;
+ sched_lock.mtx_saveintr = ALPHA_PSL_IPL_0;
if (curproc != PCPU_GET(idleproc))
setrunqueue(curproc);
mi_switch();
+ sched_lock.mtx_saveintr = saveintr;
}
- } else {
- CTR3(KTR_INTR, "alpha_dispatch_intr: %d: it_need %d, state %d",
- ithd->it_proc->p_pid, ithd->it_need, ithd->it_proc->p_stat);
- need_resched();
- }
- mtx_exit(&sched_lock, MTX_SPIN);
#else
- mtx_enter(&sched_lock, MTX_SPIN);
- if (ithd->it_proc->p_stat == SWAIT) {
- /* not on the run queue and not running */
- CTR1(KTR_INTR, "alpha_dispatch_intr: setrunqueue %d",
- ithd->it_proc->p_pid);
-
- alpha_mb(); /* XXX - ??? */
- ithd->it_proc->p_stat = SRUN;
- setrunqueue(ithd->it_proc);
- aston();
+ need_resched();
+#endif
} else {
CTR3(KTR_INTR, "alpha_dispatch_intr: %d: it_need %d, state %d",
ithd->it_proc->p_pid, ithd->it_need, ithd->it_proc->p_stat);
- }
- if (i->disable) {
- CTR1(KTR_INTR,
- "alpha_dispatch_intr: disabling vector 0x%x", i->vector);
- i->disable(i->vector);
+ need_resched();
}
mtx_exit(&sched_lock, MTX_SPIN);
-
- need_resched();
-#endif
}
void
OpenPOWER on IntegriCloud