lkml.org 
[lkml]   [2019]   [Oct]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 322/344] md: only call set_in_sync() when it is expected to succeed.
    Date
    From: NeilBrown <neilb@suse.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@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>

    ---
    drivers/md/md.c | 3 ++-
    1 file changed, 2 insertions(+), 1 deletion(-)

    --- a/drivers/md/md.c
    +++ b/drivers/md/md.c
    @@ -8910,6 +8910,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;
    @@ -8955,7 +8956,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);

    \
     
     \ /
      Last update: 2019-10-03 18:53    [W:3.730 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site