aboutsummaryrefslogtreecommitdiff
path: root/sys/cddl/contrib
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2019-06-13 01:21:32 +0000
committerAlexander Motin <mav@FreeBSD.org>2019-06-13 01:21:32 +0000
commit913095dc56e084fd3ac195284c720c5d58045f88 (patch)
treeda49daa05b00b014d90998f4d8cd913000e2f3a3 /sys/cddl/contrib
parent61b54f34a3c97e204a682f6f29fe81e81a888cc0 (diff)
Move write aggregation memory copy out of vq_lock.
Memory copy is too heavy operation to do under the congested lock. Moving it out reduces congestion by many times to almost invisible. Since the original zio removed from the queue, and the child zio is not executed yet, I don't see why would the copy need protection. My guess it just remained like this from the time when lock was not dropped here, which was added later to fix lock ordering issue. Multi-threaded sequential write tests with both HDD and SSD pools with ZVOL block sizes of 4KB, 16KB, 64KB and 128KB all show major reduction of lock congestion, saving from 15% to 35% of CPU time and increasing throughput from 10% to 40%. Reviewed by: ahrens, behlendorf, ryao MFC after: 2 weeks Sponsored by: iXsystems, Inc.
Notes
Notes: svn path=/head/; revision=349006
Diffstat (limited to 'sys/cddl/contrib')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
index b53ec7ffafc8..ef2d2008e458 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
@@ -815,6 +815,18 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
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) {
@@ -826,16 +838,6 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
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);
}