[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191003154602.119302446@linuxfoundation.org>
Date: Thu, 3 Oct 2019 17:54:32 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, NeilBrown <neilb@...e.com>,
Song Liu <songliubraving@...com>,
Jack Wang <jinpu.wang@...ud.ionos.com>
Subject: [PATCH 5.2 294/313] md: only call set_in_sync() when it is expected to succeed.
From: NeilBrown <neilb@...e.com>
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@...ud.ionos.com>
Fixes: 4ad23a976413 ("MD: use per-cpu counter for writes_pending")
Cc: stable@...r.kernel.org (v4.12+)
Signed-off-by: NeilBrown <neilb@...e.com>
Signed-off-by: Song Liu <songliubraving@...com>
Signed-off-by: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
---
drivers/md/md.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -8811,6 +8811,7 @@ void md_check_recovery(struct mddev *mdd
if (mddev_trylock(mddev)) {
int spares = 0;
+ bool try_set_sync = mddev->safemode != 0;
if (!mddev->external && mddev->safemode == 1)
mddev->safemode = 0;
@@ -8856,7 +8857,7 @@ void md_check_recovery(struct mddev *mdd
}
}
- 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);
Powered by blists - more mailing lists