]> granicus.if.org Git - zfs/commitdiff
Fix CPU_SEQID use in preemptible context
authorBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 7 Oct 2014 20:20:49 +0000 (13:20 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 7 Oct 2014 23:40:29 +0000 (16:40 -0700)
Commit e022864 introduced a regression for kernels which are built
with CONFIG_DEBUG_PREEMPT.  The use of CPU_SEQID in a preemptible
context causes zio_nowait() to trigger the BUG.  Since CPU_SEQID
is simply being used as a random index the usage here is safe. To
resolve the issue preempt is disable while calling CPU_SEQID.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ned Bass <bass6@llnl.gov>
Closes #2769

module/zfs/zio.c

index 844b909fba8b559d717de9b6581b29886d7e2f83..0ba167c62b59dbd89b586baba781664cb10dd95d 100644 (file)
@@ -1467,14 +1467,19 @@ zio_nowait(zio_t *zio)
 
        if (zio->io_child_type == ZIO_CHILD_LOGICAL &&
            zio_unique_parent(zio) == NULL) {
+               zio_t *pio;
+
                /*
                 * This is a logical async I/O with no parent to wait for it.
                 * We add it to the spa_async_root_zio "Godfather" I/O which
                 * will ensure they complete prior to unloading the pool.
                 */
                spa_t *spa = zio->io_spa;
+               kpreempt_disable();
+               pio = spa->spa_async_zio_root[CPU_SEQID];
+               kpreempt_enable();
 
-               zio_add_child(spa->spa_async_zio_root[CPU_SEQID], zio);
+               zio_add_child(pio, zio);
        }
 
        __zio_execute(zio);