summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2004-02-07 03:26:38 +0000
committerscottl <scottl@FreeBSD.org>2004-02-07 03:26:38 +0000
commit03c17dd8925ab3cd17375d7db3e1236a7ff2e95e (patch)
treecc2d83d8dc9eaf9e0985ec40e0852cc1dc91aace /sys/dev/aac
parent29c3ba6eb5bcbeb15a3c63fac11e552962eb3ec9 (diff)
downloadFreeBSD-src-03c17dd8925ab3cd17375d7db3e1236a7ff2e95e.zip
FreeBSD-src-03c17dd8925ab3cd17375d7db3e1236a7ff2e95e.tar.gz
- Broaden the scope of locking in aac_command_thread() again to catch some
edge cases in the loop. - Try to grab a command before dequeueing the bio from the bioq. The old behaviour of requeuing deferred bios to the end of the bioq is arguably wrong. This should be fixed in the future to check the bioq head without automatically dequeueing the bio.
Diffstat (limited to 'sys/dev/aac')
-rw-r--r--sys/dev/aac/aac.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 9d6e115..b799808 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -632,7 +632,7 @@ aac_intr(void *arg)
/*
* This might miss doing the actual wakeup. However, the
- * tsleep that this is waking up has a timeout, so it will
+ * msleep that this is waking up has a timeout, so it will
* wake up eventually. AIFs and printfs are low enough
* priority that they can handle hanging out for a few seconds
* if needed.
@@ -731,11 +731,15 @@ aac_command_thread(struct aac_softc *sc)
debug_called(2);
- sc->aifflags |= AAC_AIFFLAGS_RUNNING;
+ AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+ sc->aifflags = AAC_AIFFLAGS_RUNNING;
+
+ while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
- while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
- retval = tsleep(sc->aifthread, PRIBIO, "aifthd",
- AAC_PERIODIC_INTERVAL * hz);
+ retval = 0;
+ if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
+ retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO,
+ "aifthd", AAC_PERIODIC_INTERVAL * hz);
/*
* First see if any FIBs need to be allocated. This needs
@@ -743,12 +747,13 @@ aac_command_thread(struct aac_softc *sc)
* will grab Giant, and would result in an LOR.
*/
if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
- aac_alloc_commands(sc);
sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
+ AAC_LOCK_RELEASE(&sc->aac_io_lock);
+ aac_alloc_commands(sc);
+ AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+ aac_startio(sc);
}
- AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
-
/*
* While we're here, check to see if any commands are stuck.
* This is pretty low-priority, so it's ok if it doesn't
@@ -802,9 +807,9 @@ aac_command_thread(struct aac_softc *sc)
fib);
}
}
- AAC_LOCK_RELEASE(&sc->aac_io_lock);
}
sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
+ AAC_LOCK_RELEASE(&sc->aac_io_lock);
wakeup(sc->aac_dev);
mtx_lock(&Giant);
@@ -896,10 +901,11 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
/* get the resources we will need */
cm = NULL;
- if ((bp = aac_dequeue_bio(sc)) == NULL)
- goto fail;
+ bp = NULL;
if (aac_alloc_command(sc, &cm)) /* get a command */
goto fail;
+ if ((bp = aac_dequeue_bio(sc)) == NULL)
+ goto fail;
/* fill out the command */
cm->cm_data = (void *)bp->bio_data;
OpenPOWER on IntegriCloud