From 8136b9d73bda48771ab49b32272b7870b463e6fd Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sun, 6 Dec 2020 12:55:02 -0500 Subject: [PATCH] Avoid some spa_has_pending_synctask() calls. Since 8c4fb36a24 (PR #7795) spa_has_pending_synctask() started to take two more locks per write inside txg_all_lists_empty(). I am surprised those pool-wide locks are not contended, but still their operations are visible in CPU profiles under contended vdev lock. This commit slightly changes vdev_queue_max_async_writes() flow to not call the function if we are going to return max_active any way due to high amount of dirty data. It allows to save some CPU time exactly when the pool is busy. Reviewed-by: Ryan Moeller Reviewed-by: Brian Behlendorf Reviewed-By: Tom Caputi Signed-off-by: Alexander Motin Closes #11280 --- module/zfs/vdev_queue.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index 6f3c4208a..02040c3ee 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -338,14 +338,12 @@ vdev_queue_max_async_writes(spa_t *spa) * Sync tasks correspond to interactive user actions. To reduce the * execution time of those actions we push data out as fast as possible. */ - if (spa_has_pending_synctask(spa)) + dirty = dp->dp_dirty_total; + if (dirty > max_bytes || spa_has_pending_synctask(spa)) return (zfs_vdev_async_write_max_active); - dirty = dp->dp_dirty_total; if (dirty < min_bytes) return (zfs_vdev_async_write_min_active); - if (dirty > max_bytes) - return (zfs_vdev_async_write_max_active); /* * linear interpolation: