Re: [PATCH 2/7] md: fix a race condition when stopping the sync thread
From: Yu Kuai <hidden>
Date: 2024-01-18 01:32:27
Also in:
dm-devel
Hi, 在 2024/01/18 2:18, Mikulas Patocka 写道:
Note that md_wakeup_thread_directly is racy - it will do nothing if the thread is already running or it may cause spurious wake-up if the thread is blocked in another subsystem.
No, as the comment said, md_wakeup_thread_directly() is just to prevent that md_wakeup_thread() can't wake up md_do_sync() if it's waiting for metadata update.
In order to eliminate the race condition, we will retry md_wakeup_thread_directly after 0.1 seconds.
And what you changed is not md_wakeup_thread_directly() at all. Thanks, Kuai
quoted hunk ↗ jump to hunk
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org # v6.7 Fixes: 130443d60b1b ("md: refactor idle/frozen_sync_thread() to fix deadlock") --- drivers/md/md.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) Index: linux-2.6/drivers/md/md.c ===================================================================--- linux-2.6.orig/drivers/md/md.c +++ linux-2.6/drivers/md/md.c@@ -4889,6 +4889,7 @@ static void stop_sync_thread(struct mdde mddev_unlock(mddev); +retry: set_bit(MD_RECOVERY_INTR, &mddev->recovery); /* * Thread might be blocked waiting for metadata update which will now@@ -4898,9 +4899,11 @@ static void stop_sync_thread(struct mdde if (work_pending(&mddev->sync_work)) flush_work(&mddev->sync_work); - wait_event(resync_wait, + if (!wait_event_timeout(resync_wait, !test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || - (check_seq && sync_seq != atomic_read(&mddev->sync_seq))); + (check_seq && sync_seq != atomic_read(&mddev->sync_seq)), + HZ / 10)) + goto retry; if (locked) mddev_lock_nointr(mddev);.