svn commit: r297746 - head/sys/dev/ioat
Conrad E. Meyer
cem at FreeBSD.org
Sat Apr 9 13:15:35 UTC 2016
Author: cem
Date: Sat Apr 9 13:15:34 2016
New Revision: 297746
URL: https://svnweb.freebsd.org/changeset/base/297746
Log:
ioat(4): ioat_get_dmaengine(): Add M_WAITOK mode
Sponsored by: EMC / Isilon Storage Division
Modified:
head/sys/dev/ioat/ioat.c
head/sys/dev/ioat/ioat.h
head/sys/dev/ioat/ioat_internal.h
head/sys/dev/ioat/ioat_test.c
Modified: head/sys/dev/ioat/ioat.c
==============================================================================
--- head/sys/dev/ioat/ioat.c Sat Apr 9 13:01:40 2016 (r297745)
+++ head/sys/dev/ioat/ioat.c Sat Apr 9 13:15:34 2016 (r297746)
@@ -314,6 +314,9 @@ ioat_detach(device_t device)
mtx_lock(IOAT_REFLK);
ioat->quiescing = TRUE;
+ ioat->destroying = TRUE;
+ wakeup(&ioat->quiescing);
+
ioat_channel[ioat->chan_idx] = NULL;
ioat_drain_locked(ioat);
@@ -739,18 +742,40 @@ ioat_reset_hw_task(void *ctx, int pendin
* User API functions
*/
bus_dmaengine_t
-ioat_get_dmaengine(uint32_t index)
+ioat_get_dmaengine(uint32_t index, int flags)
{
- struct ioat_softc *sc;
+ struct ioat_softc *ioat;
+
+ KASSERT((flags & ~(M_NOWAIT | M_WAITOK)) == 0,
+ ("invalid flags: 0x%08x", flags));
+ KASSERT((flags & (M_NOWAIT | M_WAITOK)) != (M_NOWAIT | M_WAITOK),
+ ("invalid wait | nowait"));
if (index >= ioat_channel_index)
return (NULL);
- sc = ioat_channel[index];
- if (sc == NULL || sc->quiescing)
+ ioat = ioat_channel[index];
+ if (ioat == NULL || ioat->destroying)
return (NULL);
- return (&ioat_get(sc, IOAT_DMAENGINE_REF)->dmaengine);
+ if (ioat->quiescing) {
+ if ((flags & M_NOWAIT) != 0)
+ return (NULL);
+
+ mtx_lock(IOAT_REFLK);
+ while (ioat->quiescing && !ioat->destroying)
+ msleep(&ioat->quiescing, IOAT_REFLK, 0, "getdma", 0);
+ mtx_unlock(IOAT_REFLK);
+
+ if (ioat->destroying)
+ return (NULL);
+ }
+
+ /*
+ * There's a race here between the quiescing check and HW reset or
+ * module destroy.
+ */
+ return (&ioat_get(ioat, IOAT_DMAENGINE_REF)->dmaengine);
}
void
@@ -1571,6 +1596,7 @@ ioat_reset_hw(struct ioat_softc *ioat)
out:
mtx_lock(IOAT_REFLK);
ioat->quiescing = FALSE;
+ wakeup(&ioat->quiescing);
mtx_unlock(IOAT_REFLK);
if (error == 0)
Modified: head/sys/dev/ioat/ioat.h
==============================================================================
--- head/sys/dev/ioat/ioat.h Sat Apr 9 13:01:40 2016 (r297745)
+++ head/sys/dev/ioat/ioat.h Sat Apr 9 13:15:34 2016 (r297746)
@@ -68,8 +68,10 @@ typedef void (*bus_dmaengine_callback_t)
/*
* Called first to acquire a reference to the DMA channel
+ *
+ * Flags may be M_WAITOK or M_NOWAIT.
*/
-bus_dmaengine_t ioat_get_dmaengine(uint32_t channel_index);
+bus_dmaengine_t ioat_get_dmaengine(uint32_t channel_index, int flags);
/* Release the DMA channel */
void ioat_put_dmaengine(bus_dmaengine_t dmaengine);
Modified: head/sys/dev/ioat/ioat_internal.h
==============================================================================
--- head/sys/dev/ioat/ioat_internal.h Sat Apr 9 13:01:40 2016 (r297745)
+++ head/sys/dev/ioat/ioat_internal.h Sat Apr 9 13:15:34 2016 (r297746)
@@ -410,6 +410,7 @@ struct ioat_softc {
struct task reset_task;
boolean_t quiescing;
+ boolean_t destroying;
boolean_t is_resize_pending;
boolean_t is_completion_pending;
boolean_t is_reset_pending;
Modified: head/sys/dev/ioat/ioat_test.c
==============================================================================
--- head/sys/dev/ioat/ioat_test.c Sat Apr 9 13:01:40 2016 (r297745)
+++ head/sys/dev/ioat/ioat_test.c Sat Apr 9 13:15:34 2016 (r297746)
@@ -388,7 +388,7 @@ ioat_dma_test(void *arg)
return;
}
- dmaengine = ioat_get_dmaengine(test->channel_index);
+ dmaengine = ioat_get_dmaengine(test->channel_index, M_NOWAIT);
if (dmaengine == NULL) {
ioat_test_log(0, "Couldn't acquire dmaengine\n");
test->status[IOAT_TEST_NO_DMA_ENGINE]++;
More information about the svn-src-head
mailing list