Fix CPU_SEQID use in preemptible context

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
This commit is contained in:
Brian Behlendorf 2014-10-07 13:20:49 -07:00
parent a215ee16c0
commit 8878261fc9

View File

@ -1467,14 +1467,19 @@ zio_nowait(zio_t *zio)
if (zio->io_child_type == ZIO_CHILD_LOGICAL && if (zio->io_child_type == ZIO_CHILD_LOGICAL &&
zio_unique_parent(zio) == NULL) { zio_unique_parent(zio) == NULL) {
zio_t *pio;
/* /*
* This is a logical async I/O with no parent to wait for it. * 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 * We add it to the spa_async_root_zio "Godfather" I/O which
* will ensure they complete prior to unloading the pool. * will ensure they complete prior to unloading the pool.
*/ */
spa_t *spa = zio->io_spa; 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); __zio_execute(zio);