@@ -4574,8 +4574,29 @@ zio_vdev_io_start(zio_t *zio)
4574
4574
ASSERT0 (zio -> io_child_error [ZIO_CHILD_VDEV ]);
4575
4575
4576
4576
if (vd == NULL ) {
4577
- if (!(zio -> io_flags & ZIO_FLAG_CONFIG_WRITER ))
4578
- spa_config_enter (spa , SCL_ZIO , zio , RW_READER );
4577
+ if (!(zio -> io_flags & ZIO_FLAG_CONFIG_WRITER )) {
4578
+ /*
4579
+ * A deadlock workaround. The ddt_prune_unique_entries()
4580
+ * -> prune_candidates_sync() code path takes the
4581
+ * SCL_ZIO reader lock and may request it again here.
4582
+ * If there is another thread who wants the SCL_ZIO
4583
+ * writer lock, then scl_write_wanted will be set.
4584
+ * Thus, the spa_config_enter_priority() is used to
4585
+ * ignore pending writer requests.
4586
+ *
4587
+ * The locking should be revised to remove the need
4588
+ * for this workaround. If that's not workable then
4589
+ * it should only be applied to the zios involved in
4590
+ * the pruning process. This impacts the read/write
4591
+ * I/O balance while pruning.
4592
+ */
4593
+ if (spa -> spa_active_ddt_prune )
4594
+ spa_config_enter_priority (spa , SCL_ZIO , zio ,
4595
+ RW_READER );
4596
+ else
4597
+ spa_config_enter (spa , SCL_ZIO , zio ,
4598
+ RW_READER );
4599
+ }
4579
4600
4580
4601
/*
4581
4602
* The mirror_ops handle multiple DVAs in a single BP.
0 commit comments