[PATCH OLK-5.10] md/raid1,raid10: fix error-path detection with md_cloned_bio()
mainline inclusion from mainline-v7.2-rc1 commit 811545e0926d02a6a0b1a1258bb5544777c164d4 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17694 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Detect the error path using md_cloned_bio() instead of relying on r1_bio in raid1 or r10_bio->read_slot in raid10, which may be NULL or -1 after splitting and resubmitting a failed bio. As a result, the error path may not be recognized and memory allocations can incorrectly use GFP_NOIO instead of (GFP_NOIO | __GFP_HIGH), which can lead to a deadlock under memory pressure. Fixes: 689389a06ce7 ("md/raid1: simplify handle_read_error().") Fixes: 545250f24809 ("md/raid10: simplify handle_read_error()") Signed-off-by: Abd-Alrhman Masalkhi <abd.masalkhi@gmail.com> Reviewed-by: Xiao Ni <xiao@kernel.org> Link: https://patch.msgid.link/20260501114652.590037-3-abd.masalkhi@gmail.com Signed-off-by: Yu Kuai <yukuai@fygo.io> Conflicts: drivers/md/raid1.c drivers/md/raid10.c [Backport to hulk-5.10: upstream uses md_cloned_bio() which depends on io_clone_set infrastructure absent in hulk-5.10. Use current == mddev->thread->tsk to detect error path instead] Signed-off-by: Zhou Minqiang <zhouminqiang2@huawei.com> --- drivers/md/raid1.c | 9 ++++++--- drivers/md/raid10.c | 14 +++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index acd008f97847..b6ae83158a7b 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1198,13 +1198,16 @@ static void raid1_read_request(struct mddev *mddev, struct bio *bio, int rdisk; bool r1bio_existed = !!r1_bio; char b[BDEVNAME_SIZE]; + struct md_thread *thread = rcu_dereference(mddev->thread); + gfp_t gfp = GFP_NOIO; /* - * If r1_bio is set, we are blocking the raid1d thread - * so there is a tiny risk of deadlock. So ask for + * If we are in the error path, we are blocking the raid1d + * thread so there is a tiny risk of deadlock. So ask for * emergency memory if needed. */ - gfp_t gfp = r1_bio ? (GFP_NOIO | __GFP_HIGH) : GFP_NOIO; + if (thread && current == thread->tsk) + gfp = GFP_NOIO | __GFP_HIGH; if (r1bio_existed) { /* Need to get the block device name carefully */ diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index f272021d4e8b..4c97325905eb 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1127,8 +1127,17 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio, char b[BDEVNAME_SIZE]; int slot = r10_bio->read_slot; struct md_rdev *err_rdev = NULL; + struct md_thread *thread = rcu_dereference(mddev->thread); gfp_t gfp = GFP_NOIO; + /* + * If we are in the error path, we are blocking the raid10d + * thread so there is a tiny risk of deadlock. So ask for + * emergency memory if needed. + */ + if (thread && current == thread->tsk) + gfp = GFP_NOIO | __GFP_HIGH; + if (slot >= 0 && r10_bio->devs[slot].rdev) { /* * This is an error retry, but we cannot @@ -1138,11 +1147,6 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio, * we lose the device name in error messages. */ int disk; - /* - * As we are blocking raid10, it is a little safer to - * use __GFP_HIGH. - */ - gfp = GFP_NOIO | __GFP_HIGH; rcu_read_lock(); disk = r10_bio->devs[slot].devnum; -- 2.52.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/27327 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/35L... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/27327 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/35L...
participants (2)
-
patchwork bot -
Zhou Minqiang