diff options
author | NeilBrown <neilb@suse.com> | 2019-08-20 10:21:09 +1000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-10-05 13:10:10 +0200 |
commit | 5dc86e9574a1292e5669ef4be1be60efcb312b27 (patch) | |
tree | 8f76c86e3abcb308c291d84bd2b710754b3a1a8a /drivers/md | |
parent | 598a2cda62d3748da7ca62105fb3180be654bfe4 (diff) | |
download | linux-stable-5dc86e9574a1292e5669ef4be1be60efcb312b27.tar.gz linux-stable-5dc86e9574a1292e5669ef4be1be60efcb312b27.tar.bz2 linux-stable-5dc86e9574a1292e5669ef4be1be60efcb312b27.zip |
md: only call set_in_sync() when it is expected to succeed.
commit 480523feae581ab714ba6610388a3b4619a2f695 upstream.
Since commit 4ad23a976413 ("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: Jack Wang <jinpu.wang@cloud.ionos.com>
Fixes: 4ad23a976413 ("MD: use per-cpu counter for writes_pending")
Cc: stable@vger.kernel.org (v4.12+)
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 22786878b9d8..a8fbaa384e9a 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -8807,6 +8807,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; @@ -8852,7 +8853,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); |