aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorJeff Roberson <jeff@FreeBSD.org>2011-04-26 07:30:52 +0000
committerJeff Roberson <jeff@FreeBSD.org>2011-04-26 07:30:52 +0000
commit5bd186a65a73cb4554d330595fa5138f9dade29f (patch)
tree2267a46d180b7475ad2d2f0ebec4fe8fa136c1c3 /sys/kern
parent37508ef3ebe5fc0078cef39829fc49b6354cdab9 (diff)
downloadsrc-5bd186a65a73cb4554d330595fa5138f9dade29f.tar.gz
src-5bd186a65a73cb4554d330595fa5138f9dade29f.zip
- Catch up to falloc() changes.
- PHOLD() before using a task structure on the stack. - Fix a LOR between the sleepq lock and thread lock in _intr_drain().
Notes
Notes: svn path=/head/; revision=221055
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_intr.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index daeb2dcbee1a..9cde5903f475 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -746,7 +746,6 @@ intr_handler_source(void *cookie)
void
_intr_drain(int irq)
{
- struct mtx *mtx;
struct intr_event *ie;
struct intr_thread *ithd;
struct thread *td;
@@ -758,13 +757,21 @@ _intr_drain(int irq)
return;
ithd = ie->ie_thread;
td = ithd->it_thread;
+ /*
+ * We set the flag and wait for it to be cleared to avoid
+ * long delays with potentially busy interrupt handlers
+ * were we to only sample TD_AWAITING_INTR() every tick.
+ */
thread_lock(td);
- mtx = td->td_lock;
if (!TD_AWAITING_INTR(td)) {
ithd->it_flags |= IT_WAIT;
- msleep_spin(ithd, mtx, "isync", 0);
+ while (ithd->it_flags & IT_WAIT) {
+ thread_unlock(td);
+ pause("idrain", 1);
+ thread_lock(td);
+ }
}
- mtx_unlock_spin(mtx);
+ thread_unlock(td);
return;
}