summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2011-04-26 07:30:52 +0000
committerjeff <jeff@FreeBSD.org>2011-04-26 07:30:52 +0000
commit14f1aafe263cef021807fa3a80daaf36c99f71ca (patch)
tree2267a46d180b7475ad2d2f0ebec4fe8fa136c1c3 /sys/kern
parentb539365333e14c681a58929107c3212cbbb5bc69 (diff)
downloadFreeBSD-src-14f1aafe263cef021807fa3a80daaf36c99f71ca.zip
FreeBSD-src-14f1aafe263cef021807fa3a80daaf36c99f71ca.tar.gz
- 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().
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 daeb2dc..9cde590 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;
}
OpenPOWER on IntegriCloud