Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 480523fe authored by NeilBrown's avatar NeilBrown Committed by Song Liu
Browse files

md: only call set_in_sync() when it is expected to succeed.



Since commit 4ad23a97 ("MD: use per-cpu counter for
writes_pending"), set_in_sync() is substantially more expensive: it
can wait for a full RCU grace period which can be 10s of milliseconds.

So we should only call it when the cost is justified.

md_check_recovery() currently calls set_in_sync() every time it finds
anything to do (on non-external active arrays).  For an array
performing resync or recovery, this will be quite often.
Each call will introduce a delay to the md thread, which can noticeable
affect IO submission latency.

In md_check_recovery() we only need to call set_in_sync() if
'safemode' was non-zero at entry, meaning that there has been not
recent IO.  So we save this "safemode was nonzero" state, and only
call set_in_sync() if it was non-zero.

This measurably reduces mean and maximum IO submission latency during
resync/recovery.

Reported-and-tested-by: default avatarJack Wang <jinpu.wang@cloud.ionos.com>
Fixes: 4ad23a97 ("MD: use per-cpu counter for writes_pending")
Cc: stable@vger.kernel.org (v4.12+)
Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
parent 97b27821
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -8932,6 +8932,7 @@ void md_check_recovery(struct mddev *mddev)

	if (mddev_trylock(mddev)) {
		int spares = 0;
		bool try_set_sync = mddev->safemode != 0;

		if (!mddev->external && mddev->safemode == 1)
			mddev->safemode = 0;
@@ -8977,7 +8978,7 @@ void md_check_recovery(struct mddev *mddev)
			}
		}

		if (!mddev->external && !mddev->in_sync) {
		if (try_set_sync && !mddev->external && !mddev->in_sync) {
			spin_lock(&mddev->lock);
			set_in_sync(mddev);
			spin_unlock(&mddev->lock);