This is a note to let you know that I've just added the patch titled md/raid10: factor out code from wait_barrier() to stop_waiting_barrier() to the 5.15-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: md-raid10-factor-out-code-from-wait_barrier-to-stop_.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit dad5a7dc4963d82c70930d9b292cf2d105eef29f Author: Yu Kuai <yukuai3@xxxxxxxxxx> Date: Fri Sep 16 19:34:24 2022 +0800 md/raid10: factor out code from wait_barrier() to stop_waiting_barrier() [ Upstream commit ed2e063f92c44c891ccd883e289dde6ca870edcc ] Currently the nasty condition in wait_barrier() is hard to read. This patch factors out the condition into a function. There are no functional changes. Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> Acked-by: Paul Menzel <pmenzel@xxxxxxxxxxxxx> Reviewed-by: Logan Gunthorpe <logang@xxxxxxxxxxxx> Acked-by: Guoqing Jiang <guoqing.jiang@xxxxxxxxx> Signed-off-by: Song Liu <song@xxxxxxxxxx> Stable-dep-of: 72c215ed8731 ("md/raid10: fix task hung in raid10d") Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 287bebde2e546..31ecb080851ac 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -952,41 +952,47 @@ static void lower_barrier(struct r10conf *conf) wake_up(&conf->wait_barrier); } +static bool stop_waiting_barrier(struct r10conf *conf) +{ + struct bio_list *bio_list = current->bio_list; + + /* barrier is dropped */ + if (!conf->barrier) + return true; + + /* + * If there are already pending requests (preventing the barrier from + * rising completely), and the pre-process bio queue isn't empty, then + * don't wait, as we need to empty that queue to get the nr_pending + * count down. + */ + if (atomic_read(&conf->nr_pending) && bio_list && + (!bio_list_empty(&bio_list[0]) || !bio_list_empty(&bio_list[1]))) + return true; + + /* move on if recovery thread is blocked by us */ + if (conf->mddev->thread->tsk == current && + test_bit(MD_RECOVERY_RUNNING, &conf->mddev->recovery) && + conf->nr_queued > 0) + return true; + + return false; +} + static bool wait_barrier(struct r10conf *conf, bool nowait) { bool ret = true; spin_lock_irq(&conf->resync_lock); if (conf->barrier) { - struct bio_list *bio_list = current->bio_list; conf->nr_waiting++; - /* Wait for the barrier to drop. - * However if there are already pending - * requests (preventing the barrier from - * rising completely), and the - * pre-process bio queue isn't empty, - * then don't wait, as we need to empty - * that queue to get the nr_pending - * count down. - */ /* Return false when nowait flag is set */ if (nowait) { ret = false; } else { raid10_log(conf->mddev, "wait barrier"); wait_event_lock_irq(conf->wait_barrier, - !conf->barrier || - (atomic_read(&conf->nr_pending) && - bio_list && - (!bio_list_empty(&bio_list[0]) || - !bio_list_empty(&bio_list[1]))) || - /* move on if recovery thread is - * blocked by us - */ - (conf->mddev->thread->tsk == current && - test_bit(MD_RECOVERY_RUNNING, - &conf->mddev->recovery) && - conf->nr_queued > 0), + stop_waiting_barrier(conf), conf->resync_lock); } conf->nr_waiting--;