From 9c3a7fce372b4b18ba67dfcd86b3444d95db0b43 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Wed, 19 Feb 2003 21:58:34 +0000 Subject: [PATCH] Make the aac driver be INTR_MPSAFE. Once the interrupt handler determines that a command completion happened, all further processing is deferred to a taskqueue. The taskqueue itself runs implicetely under Giant, but we already used a taskqueue for the biodone() processing, so this at least saves the contesting of Giant in the interrupt handler. --- sys/dev/aac/aac.c | 60 +++++++++++++------------------------------ sys/dev/aac/aac_pci.c | 5 ++-- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index b25286ed62bc..28bb8a067f03 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -83,7 +83,6 @@ static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp); static void aac_bio_complete(struct aac_command *cm); static int aac_wait_command(struct aac_command *cm, int timeout); static void aac_command_thread(struct aac_softc *sc); -static void aac_host_response(struct aac_softc *sc); /* Command Buffer Management */ static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs, @@ -661,7 +660,8 @@ aac_intr(void *arg) /* It's not ok to return here because of races with the previous step */ if (reason & AAC_DB_RESPONSE_READY) - aac_host_response(sc); + /* handle completion processing */ + taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); /* controller wants to talk to the log */ if (reason & AAC_DB_PRINTF) { @@ -844,43 +844,6 @@ aac_command_thread(struct aac_softc *sc) kthread_exit(0); } -/* - * Handle notification of one or more FIBs completed by the controller - */ -static void -aac_host_response(struct aac_softc *sc) -{ - struct aac_command *cm; - struct aac_fib *fib; - u_int32_t fib_size; - - debug_called(2); - - for (;;) { - /* look for completed FIBs on our queue */ - if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, - &fib)) - break; /* nothing to do */ - - /* get the command, unmap and queue for later processing */ - cm = (struct aac_command *)fib->Header.SenderData; - if (cm == NULL) { - AAC_PRINT_FIB(sc, fib); - } else { - aac_remove_busy(cm); - aac_unmap_command(cm); /* XXX defer? */ - aac_enqueue_complete(cm); - } - } - - /* handle completion processing */ -#if __FreeBSD_version >= 500005 - taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete); -#else - aac_complete(sc, 0); -#endif -} - /* * Process completed commands. */ @@ -889,16 +852,29 @@ aac_complete(void *context, int pending) { struct aac_softc *sc; struct aac_command *cm; - + struct aac_fib *fib; + u_int32_t fib_size; + debug_called(2); sc = (struct aac_softc *)context; /* pull completed commands off the queue */ for (;;) { - cm = aac_dequeue_complete(sc); - if (cm == NULL) + /* look for completed FIBs on our queue */ + if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, + &fib)) + break; /* nothing to do */ + + /* get the command, unmap and queue for later processing */ + cm = (struct aac_command *)fib->Header.SenderData; + if (cm == NULL) { + AAC_PRINT_FIB(sc, fib); break; + } + + aac_remove_busy(cm); + aac_unmap_command(cm); /* XXX defer? */ cm->cm_flags |= AAC_CMD_COMPLETED; /* is there a completion handler? */ diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c index 6f6b7e356826..85bd529a94b3 100644 --- a/sys/dev/aac/aac_pci.c +++ b/sys/dev/aac/aac_pci.c @@ -223,8 +223,9 @@ aac_pci_attach(device_t dev) #ifndef INTR_ENTROPY #define INTR_ENTROPY 0 #endif - if (bus_setup_intr(sc->aac_dev, sc->aac_irq, INTR_TYPE_BIO|INTR_ENTROPY, - aac_intr, sc, &sc->aac_intr)) { + if (bus_setup_intr(sc->aac_dev, sc->aac_irq, + INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY, aac_intr, + sc, &sc->aac_intr)) { device_printf(sc->aac_dev, "can't set up interrupt\n"); goto out; }