This is a note to let you know that I've just added the patch titled dm mpath: fix racey management of PG initialization to the 5.8-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: dm-mpath-fix-racey-management-of-pg-initialization.patch and it can be found in the queue-5.8 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From c322ee9320eaa4013ca3620b1130992916b19b31 Mon Sep 17 00:00:00 2001 From: Mike Snitzer <snitzer@xxxxxxxxxx> Date: Mon, 24 Aug 2020 14:19:55 -0400 Subject: dm mpath: fix racey management of PG initialization From: Mike Snitzer <snitzer@xxxxxxxxxx> commit c322ee9320eaa4013ca3620b1130992916b19b31 upstream. Commit 935fcc56abc3 ("dm mpath: only flush workqueue when needed") changed flush_multipath_work() to avoid needless workqueue flushing (of a multipath global workqueue). But that change didn't realize the surrounding flush_multipath_work() code should also only run if 'pg_init_in_progress' is set. Fix this by only doing all of flush_multipath_work()'s PG init related work if 'pg_init_in_progress' is set. Otherwise multipath_wait_for_pg_init_completion() will run unconditionally but the preceeding flush_workqueue(kmpath_handlerd) may not. This could lead to deadlock (though only if kmpath_handlerd never runs a corresponding work to decrement 'pg_init_in_progress'). It could also be, though highly unlikely, that the kmpath_handlerd work that does PG init completes before 'pg_init_in_progress' is set, and then an intervening DM table reload's multipath_postsuspend() triggers flush_multipath_work(). Fixes: 935fcc56abc3 ("dm mpath: only flush workqueue when needed") Cc: stable@xxxxxxxxxxxxxxx Reported-by: Ben Marzinski <bmarzins@xxxxxxxxxx> Signed-off-by: Mike Snitzer <snitzer@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/md/dm-mpath.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -1247,17 +1247,25 @@ static void multipath_wait_for_pg_init_c static void flush_multipath_work(struct multipath *m) { if (m->hw_handler_name) { - set_bit(MPATHF_PG_INIT_DISABLED, &m->flags); - smp_mb__after_atomic(); + unsigned long flags; + + if (!atomic_read(&m->pg_init_in_progress)) + goto skip; + + spin_lock_irqsave(&m->lock, flags); + if (atomic_read(&m->pg_init_in_progress) && + !test_and_set_bit(MPATHF_PG_INIT_DISABLED, &m->flags)) { + spin_unlock_irqrestore(&m->lock, flags); - if (atomic_read(&m->pg_init_in_progress)) flush_workqueue(kmpath_handlerd); - multipath_wait_for_pg_init_completion(m); + multipath_wait_for_pg_init_completion(m); - clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags); - smp_mb__after_atomic(); + spin_lock_irqsave(&m->lock, flags); + clear_bit(MPATHF_PG_INIT_DISABLED, &m->flags); + } + spin_unlock_irqrestore(&m->lock, flags); } - +skip: if (m->queue_mode == DM_TYPE_BIO_BASED) flush_work(&m->process_queued_bios); flush_work(&m->trigger_event); Patches currently in stable-queue which might be from snitzer@xxxxxxxxxx are queue-5.8/dm-integrity-fix-error-reporting-in-bitmap-mode-after-creation.patch queue-5.8/dm-thin-metadata-fix-use-after-free-in-dm_bm_set_read_only.patch queue-5.8/dm-mpath-fix-racey-management-of-pg-initialization.patch queue-5.8/dm-thin-metadata-avoid-returning-cmd-bm-wild-pointer-on-error.patch queue-5.8/dm-cache-metadata-avoid-returning-cmd-bm-wild-pointer-on-error.patch queue-5.8/dm-crypt-initialize-crypto-wait-structures.patch queue-5.8/dm-writecache-handle-dax-to-partitions-on-persistent-memory-correctly.patch