[PATCH v6 07/12] md/raid1,raid10: skip futile retries on P2PDMA mapping failures
From: Mykola Marzhan
Date: Sun Jul 26 2026 - 07:40:51 EST
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 <mykola@xxxxxxxxxxx>
Reviewed-by: Logan Gunthorpe <logang@xxxxxxxxxxxx>
---
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