Fix zio_taskq_dispatch to use TQ_NOSLEEP
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 26 Aug 2010 17:32:23 +0000 (10:32 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 31 Aug 2010 15:38:46 +0000 (08:38 -0700)
The zio_taskq_dispatch() function may be called at interrupt time
and it is critical that we never sleep.

Additionally, wrap taskq_dispatch() in a while loop because it may
fail.  This is non optimal but is OK for now.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
module/zfs/zio.c

index 2d8c7e9..e434cf0 100644 (file)
@@ -1049,7 +1049,7 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline)
 {
        spa_t *spa = zio->io_spa;
        zio_type_t t = zio->io_type;
-       int flags = TQ_SLEEP | (cutinline ? TQ_FRONT : 0);
+       int flags = TQ_NOSLEEP | (cutinline ? TQ_FRONT : 0);
 
        /*
         * If we're a config writer or a probe, the normal issue and
@@ -1073,8 +1073,9 @@ zio_taskq_dispatch(zio_t *zio, enum zio_taskq_type q, boolean_t cutinline)
                q++;
 
        ASSERT3U(q, <, ZIO_TASKQ_TYPES);
-       (void) taskq_dispatch(spa->spa_zio_taskq[t][q],
-           (task_func_t *)zio_execute, zio, flags);
+
+       while (taskq_dispatch(spa->spa_zio_taskq[t][q],
+           (task_func_t *)zio_execute, zio, flags) == 0); /* do nothing */
 }
 
 static boolean_t