Received: by 2002:ac0:a591:0:0:0:0:0 with SMTP id m17-v6csp1416855imm; Thu, 5 Jul 2018 23:01:21 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfMJMcyR2l/C44nf+oy3aQqdh9bvkQ6BrRsDAQNjE0mULpbjz4j5tsEKsrgkrZL6ftHFuBG X-Received: by 2002:a17:902:a518:: with SMTP id s24-v6mr9139991plq.144.1530856881579; Thu, 05 Jul 2018 23:01:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530856881; cv=none; d=google.com; s=arc-20160816; b=NySk5/mLCin+a1CyrN7KmGOlNqLAFqSyvuCRHckLTHZBAkhqvlrjtwvfmKvWKLFTgC SXHOh7tLtr3Z1qbb9oAhKcBNAgaql2Fe7m1IbGokn9J5G/fHFx5h3iWsrm44qPUlzj75 qa19UNOUpx1Sb9C4ITJ5dNj3XbkGW+8r8VPOEvhkNyUkbQU8c4J3b6fkiChi6k9/kTC2 xpNJCEr/kSwz5H1HfOPrcyDqGXr7jGWnzeDAEASjul7qEkbvaj0e4HpNL7XbdRThBzIH qz4NIJYiujv7rd0KMiISqfVENU8VTVOh4ugVJ876zTVVdEnsHS123HoFOUcCmWBMLjF1 nPkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=qBhy8gWxN8BOEiJYoSViv4nlU6xGa4hnVf0q6hG6q44=; b=v8wDVlUX6t56x79yc6CzRQ0ZaTbwgNx/HiAyFOn/B6xWlf3xZcl6UdbFvYQo56/Lmo vTvfhWP90llogw7IBk71fhUxX3OWT3vp0qqaggBULXB5PEVzuWctUEImDi5B2fhmq+sS t3hgTg5Wvpp0AZc2py4gvhDWvq3z/lGXNpqO+mJI+Ad3ILhrQ3yIKGnfbDgAWJ0rSR6F gdPi32qgzj8Uf9EjDGK5hlQUJFOFGOP0NsqhKVxeNjltOfMTD8QauxY/p+0JvHFX+HOv ciuri1O/InjRJ9wHUm4oprhUogS0jOQl//+s6vvmb/dX65Mljs7gVFXAqrntJtuq1SDW 0pdQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q14-v6si7478468pgm.512.2018.07.05.23.01.07; Thu, 05 Jul 2018 23:01:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934656AbeGFF7b (ORCPT + 99 others); Fri, 6 Jul 2018 01:59:31 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:33230 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934181AbeGFFvP (ORCPT ); Fri, 6 Jul 2018 01:51:15 -0400 Received: from localhost (D57D388D.static.ziggozakelijk.nl [213.125.56.141]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id B15F986A; Fri, 6 Jul 2018 05:51:14 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, NeilBrown , Shaohua Li , Jack Wang Subject: [PATCH 4.14 34/61] md: always hold reconfig_mutex when calling mddev_suspend() Date: Fri, 6 Jul 2018 07:46:58 +0200 Message-Id: <20180706054713.643779676@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180706054712.332416244@linuxfoundation.org> References: <20180706054712.332416244@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: NeilBrown commit 4d5324f760aacaefeb721b172aa14bf66045c332 upstream. Most often mddev_suspend() is called with reconfig_mutex held. Make this a requirement in preparation a subsequent patch. Also require reconfig_mutex to be held for mddev_resume(), partly for symmetry and partly to guarantee no races with incr/decr of mddev->suspend. Taking the mutex in r5c_disable_writeback_async() is a little tricky as this is called from a work queue via log->disable_writeback_work, and flush_work() is called on that while holding ->reconfig_mutex. If the work item hasn't run before flush_work() is called, the work function will not be able to get the mutex. So we use mddev_trylock() inside the wait_event() call, and have that abort when conf->log is set to NULL, which happens before flush_work() is called. We wait in mddev->sb_wait and ensure this is woken when any of the conditions change. This requires waking mddev->sb_wait in mddev_unlock(). This is only like to trigger extra wake_ups of threads that needn't be woken when metadata is being written, and that doesn't happen often enough that the cost would be noticeable. Signed-off-by: NeilBrown Signed-off-by: Shaohua Li Signed-off-by: Jack Wang Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-raid.c | 10 ++++++++-- drivers/md/md.c | 3 +++ drivers/md/raid5-cache.c | 18 +++++++++++++----- 3 files changed, 24 insertions(+), 7 deletions(-) --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3637,8 +3637,11 @@ static void raid_postsuspend(struct dm_t { struct raid_set *rs = ti->private; - if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) + if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) { + mddev_lock_nointr(&rs->md); mddev_suspend(&rs->md); + mddev_unlock(&rs->md); + } rs->md.ro = 1; } @@ -3898,8 +3901,11 @@ static void raid_resume(struct dm_target if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS)) clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); - if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) + if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) { + mddev_lock_nointr(mddev); mddev_resume(mddev); + mddev_unlock(mddev); + } } static struct target_type raid_target = { --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -344,6 +344,7 @@ static blk_qc_t md_make_request(struct r void mddev_suspend(struct mddev *mddev) { WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk); + lockdep_assert_held(&mddev->reconfig_mutex); if (mddev->suspended++) return; synchronize_rcu(); @@ -357,6 +358,7 @@ EXPORT_SYMBOL_GPL(mddev_suspend); void mddev_resume(struct mddev *mddev) { + lockdep_assert_held(&mddev->reconfig_mutex); if (--mddev->suspended) return; wake_up(&mddev->sb_wait); @@ -663,6 +665,7 @@ void mddev_unlock(struct mddev *mddev) */ spin_lock(&pers_lock); md_wakeup_thread(mddev->thread); + wake_up(&mddev->sb_wait); spin_unlock(&pers_lock); } EXPORT_SYMBOL_GPL(mddev_unlock); --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -693,6 +693,8 @@ static void r5c_disable_writeback_async( struct r5l_log *log = container_of(work, struct r5l_log, disable_writeback_work); struct mddev *mddev = log->rdev->mddev; + struct r5conf *conf = mddev->private; + int locked = 0; if (log->r5c_journal_mode == R5C_JOURNAL_MODE_WRITE_THROUGH) return; @@ -701,11 +703,15 @@ static void r5c_disable_writeback_async( /* wait superblock change before suspend */ wait_event(mddev->sb_wait, - !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); - - mddev_suspend(mddev); - log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH; - mddev_resume(mddev); + conf->log == NULL || + (!test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) && + (locked = mddev_trylock(mddev)))); + if (locked) { + mddev_suspend(mddev); + log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH; + mddev_resume(mddev); + mddev_unlock(mddev); + } } static void r5l_submit_current_io(struct r5l_log *log) @@ -3161,6 +3167,8 @@ void r5l_exit_log(struct r5conf *conf) conf->log = NULL; synchronize_rcu(); + /* Ensure disable_writeback_work wakes up and exits */ + wake_up(&conf->mddev->sb_wait); flush_work(&log->disable_writeback_work); md_unregister_thread(&log->reclaim_thread); mempool_destroy(log->meta_pool);