[PATCH v6 07/12] md/raid1,raid10: skip futile retries on P2PDMA mapping failures
From: Mykola Marzhan <hidden>
Date: 2026-07-26 11:32:52
Also in:
linux-block, linux-nvme, linux-pci, linux-rdma, lkml, stable
Subsystem:
software raid (multiple disks) support, the rest · Maintainers:
Song Liu, Yu Kuai, Linus Torvalds
BLK_STS_P2PDMA reflects the peer/member pairing, not member health:
retrying the same pages on the same member cannot succeed. Keep
WriteErrorSeen so the range stays fenced, but skip WantReplacement and
FailFast eviction, as commit f7b24c7b41f2 ("md/raid1,raid10: don't fail
devices for invalid IO errors") did for BLK_STS_INVAL. raid10
replacement legs are unchanged: a write error there fails the
replacement, whatever the status.
The failure is whole-range and deterministic, so narrow_write_error()'s
block-by-block submit_bio_wait() retries are pointless. Record the
whole range as a bad block in the completion handler instead.
Fixes: 02666132403a ("md: propagate BLK_FEAT_PCI_P2PDMA from member devices to RAID device")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Mykola Marzhan <redacted>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
---
drivers/md/raid1-10.c | 3 +++
drivers/md/raid1.c | 11 ++++++++---
drivers/md/raid10.c | 7 ++++++-
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/md/raid1-10.c b/drivers/md/raid1-10.c
index cee21452e066..89daf8558251 100644
--- a/drivers/md/raid1-10.c
+++ b/drivers/md/raid1-10.c@@ -309,6 +309,9 @@ static inline void raid1_write_error(struct mddev *mddev, struct md_rdev *rdev, { set_bit(WriteErrorSeen, &rdev->flags); + if (bio->bi_status == BLK_STS_P2PDMA) + return; + if (!test_and_set_bit(WantReplacement, &rdev->flags)) set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 19c4dec450de..83ebf40237d5 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c@@ -2624,10 +2624,15 @@ static void handle_write_finished(struct r1conf *conf, struct r1bio *r1_bio) * narrow down and record precise write * errors. */ + struct md_rdev *rdev = conf->mirrors[m].rdev; + fail = true; - narrow_write_error(r1_bio, m); - rdev_dec_pending(conf->mirrors[m].rdev, - conf->mddev); + if (r1_bio->bios[m]->bi_status == BLK_STS_P2PDMA) + rdev_set_badblocks(rdev, r1_bio->sector, + r1_bio->sectors, 0); + else + narrow_write_error(r1_bio, m); + rdev_dec_pending(rdev, conf->mddev); } if (fail) { spin_lock_irq(&conf->device_lock);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 428bddddfe71..77c7d8a59916 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c@@ -2940,7 +2940,12 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio) rdev_dec_pending(rdev, conf->mddev); } else if (bio != NULL && bio->bi_status) { fail = true; - narrow_write_error(r10_bio, m); + if (bio->bi_status == BLK_STS_P2PDMA) + rdev_set_badblocks(rdev, + r10_bio->devs[m].addr, + r10_bio->sectors, 0); + else + narrow_write_error(r10_bio, m); rdev_dec_pending(rdev, conf->mddev); } bio = r10_bio->devs[m].repl_bio;
--
2.52.0