aboutsummaryrefslogtreecommitdiff
path: root/sys/powerpc
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2007-11-21 04:03:51 +0000
committerScott Long <scottl@FreeBSD.org>2007-11-21 04:03:51 +0000
commit8611774e5e4a1e037443719e938df6f3c9d39fc5 (patch)
tree1c728d282e4c2d3e4989c71f176b996bc9fbb90d /sys/powerpc
parent3e636fa0e52ac77bf7e60c592426065c0acf9db5 (diff)
downloadsrc-8611774e5e4a1e037443719e938df6f3c9d39fc5.tar.gz
src-8611774e5e4a1e037443719e938df6f3c9d39fc5.zip
Extend critical section coverage in the low-level interrupt handlers to
include the ithread scheduling step. Without this, a preemption might occur in between the interrupt getting masked and the ithread getting scheduled. Since the interrupt handler runs in the context of curthread, the scheudler might see it as having a such a low priority on a busy system that it doesn't get to run for a _long_ time, leaving the interrupt stranded in a disabled state. The only way that the preemption can happen is by a fast/filter handler triggering a schduling event earlier in the handler, so this problem can only happen for cases where an interrupt is being shared by both a fast/filter handler and an ithread handler. Unfortunately, it seems to be common for this sharing to happen with network and USB devices, for example. This fixes many of the mysterious TCP session timeouts and NIC watchdogs that were being reported. Many thanks to Sam Lefler for getting to the bottom of this problem. Reviewed by: jhb, jeff, silby
Notes
Notes: svn path=/head/; revision=173799
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/powerpc/intr_machdep.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c
index 7daaf232c068..7653347579f3 100644
--- a/sys/powerpc/powerpc/intr_machdep.c
+++ b/sys/powerpc/powerpc/intr_machdep.c
@@ -280,7 +280,6 @@ powerpc_dispatch_intr(u_int vector, struct trapframe *tf)
sched = 1;
}
}
- critical_exit();
if (sched) {
PIC_MASK(pic, i->irq);
@@ -289,6 +288,7 @@ powerpc_dispatch_intr(u_int vector, struct trapframe *tf)
__func__));
} else
PIC_EOI(pic, i->irq);
+ critical_exit();
#endif
return;