From 5bd186a65a73cb4554d330595fa5138f9dade29f Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Tue, 26 Apr 2011 07:30:52 +0000 Subject: [PATCH] - 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(). --- sys/kern/kern_intr.c | 15 +++++++++++---- sys/ofed/include/linux/file.h | 2 +- sys/ofed/include/linux/workqueue.h | 2 ++ 3 files changed, 14 insertions(+), 5 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; } diff --git a/sys/ofed/include/linux/file.h b/sys/ofed/include/linux/file.h index 12858d7648be..cbeec399cf25 100644 --- a/sys/ofed/include/linux/file.h +++ b/sys/ofed/include/linux/file.h @@ -92,7 +92,7 @@ get_unused_fd(void) int error; int fd; - error = falloc(curthread, &file, &fd); + error = falloc(curthread, &file, &fd, 0); if (error) return -error; return fd; diff --git a/sys/ofed/include/linux/workqueue.h b/sys/ofed/include/linux/workqueue.h index 6b48f9c3de6a..c59b4ae3ce9d 100644 --- a/sys/ofed/include/linux/workqueue.h +++ b/sys/ofed/include/linux/workqueue.h @@ -160,9 +160,11 @@ flush_taskqueue(struct taskqueue *tq) { struct task flushtask; + PHOLD(curproc); TASK_INIT(&flushtask, 0, _flush_fn, NULL); taskqueue_enqueue(tq, &flushtask); taskqueue_drain(tq, &flushtask); + PRELE(curproc); } static inline int