do {
dio = nio;
nio = AVL_NEXT(t, dio);
+ zio_add_child(dio, aio);
+ vdev_queue_io_remove(vq, dio);
+ } while (dio != last);
+
+ /*
+ * We need to drop the vdev queue's lock during zio_execute() to
+ * avoid a deadlock that we could encounter due to lock order
+ * reversal between vq_lock and io_lock in zio_change_priority().
+ * Use the dropped lock to do memory copy without congestion.
+ */
+ mutex_exit(&vq->vq_lock);
+ while ((dio = zio_walk_parents(aio, &zl)) != NULL) {
ASSERT3U(dio->io_type, ==, aio->io_type);
if (dio->io_flags & ZIO_FLAG_NODATA) {
dio->io_offset - aio->io_offset, 0, dio->io_size);
}
- zio_add_child(dio, aio);
- vdev_queue_io_remove(vq, dio);
- } while (dio != last);
-
- /*
- * We need to drop the vdev queue's lock to avoid a deadlock that we
- * could encounter since this I/O will complete immediately.
- */
- mutex_exit(&vq->vq_lock);
- while ((dio = zio_walk_parents(aio, &zl)) != NULL) {
zio_vdev_io_bypass(dio);
zio_execute(dio);
}