From f00eb0ff45793383d5a62db2d2aea63ada0ccdbd Mon Sep 17 00:00:00 2001 From: Zizhi Wo Date: Mon, 17 Aug 2026 11:33:40 +0800 Subject: [PATCH] md/raid10: fix missing wakeup in wait_barrier_nolock Fuzz testing triggered a hung raid10d thread: INFO: task md0_raid10 blocked for more than 120 seconds. Call Trace: raid10d md_thread kthread wait_barrier_nolock() speculatively increments nr_pending. If a concurrent writer changes resync_lock's sequence, it rolls the count back with atomic_dec_and_test(). The rollback currently wakes wait_barrier only when nr_pending reaches zero. freeze_array() can be waiting for nr_pending == nr_queued + extra while array_freeze_pending is set. If the rollback changes nr_pending from 2 to 1, the condition becomes true but no wakeup is sent, leaving raid10d blocked indefinitely. Also wake wait_barrier when array_freeze_pending is set, matching allow_barrier(). Fixes: b9b083f9044a ("md/raid10: convert resync_lock to use seqlock") Signed-off-by: Zizhi Wo Reviewed-by: Abd-Alrhman Masalkhi Link: https://patch.msgid.link/20260817033340.418119-3-wozizhi@huawei.com Signed-off-by: Yu Kuai --- drivers/md/raid10.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 65acc240f7ca..560be6338519 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1010,7 +1010,8 @@ static bool wait_barrier_nolock(struct r10conf *conf) if (!read_seqretry(&conf->resync_lock, seq)) return true; - if (atomic_dec_and_test(&conf->nr_pending)) + if (atomic_dec_and_test(&conf->nr_pending) || + READ_ONCE(conf->array_freeze_pending)) wake_up_barrier(conf); return false;