Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Jun 2019 01:21:33 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r349006 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201906130121.x5D1LXLB011500@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu Jun 13 01:21:32 2019
New Revision: 349006
URL: https://svnweb.freebsd.org/changeset/base/349006

Log:
  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.

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c	Wed Jun 12 23:09:10 2019	(r349005)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c	Thu Jun 13 01:21:32 2019	(r349006)
@@ -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);
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201906130121.x5D1LXLB011500>