[PATCH v4 8/9] md/raid1,raid10: set IO_BLOCKED in case of BLK_STS_P2PDMA
Mykola Marzhan <[email protected]> Wed, 22 Jul 2026 20:58:40 +0200
| Newsgroups | org.kernel.vger.linux-raid,org.infradead.lists.linux-nvme,org.kernel.vger.linux-block,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.linux-rdma |
|---|---|
| Message-ID | <[email protected]> |
From: Logan Gunthorpe <[email protected]> A read that fails with BLK_STS_P2PDMA cannot succeed against that member, so mark the leg IO_BLOCKED and let the retry redirect elsewhere. Skip the read-error machinery: there is nothing on the medium to fix, fix_read_error()'s probe reads into host pages and would "succeed", and charging the read-error budget would evict a healthy member under a P2P read workload. FailFast eviction is skipped for the same reason -- the request never reached the wire. Fixes: 02666132403a ("md: propagate BLK_FEAT_PCI_P2PDMA from member devices to RAID device") Assisted-by: Claude:claude-fable-5 Signed-off-by: Logan Gunthorpe <[email protected]> Co-developed-by: Mykola Marzhan <[email protected]> Signed-off-by: Mykola Marzhan <[email protected]> --- drivers/md/raid1.c | 4 +++- drivers/md/raid10.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 917d694ef401..76a1426e64f0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2658,6 +2658,8 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) { struct md_rdev *rdev = conf->mirrors[r1_bio->read_disk].rdev; struct bio *bio = r1_bio->bios[r1_bio->read_disk]; + /* evaluate before the bio_put() below */ + bool p2pdma_error = bio->bi_status == BLK_STS_P2PDMA; struct mddev *mddev = conf->mddev; sector_t sector; @@ -2675,7 +2677,7 @@ static void handle_read_error(struct r1conf *conf, struct r1bio *r1_bio) * read error. This is all done synchronously while the array is * frozen. */ - if (mddev->ro) { + if (mddev->ro || p2pdma_error) { r1_bio->bios[r1_bio->read_disk] = IO_BLOCKED; } else if (test_bit(FailFast, &rdev->flags)) { md_error(mddev, rdev); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9045a3f02dae..e35aeac29f06 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2848,6 +2848,7 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) { int slot = r10_bio->read_slot; struct bio *bio; + bool p2pdma_error; struct r10conf *conf = mddev->private; struct md_rdev *rdev = r10_bio->devs[slot].rdev; @@ -2860,10 +2861,12 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) * frozen. */ bio = r10_bio->devs[slot].bio; + /* evaluate before the bio_put() below */ + p2pdma_error = bio->bi_status == BLK_STS_P2PDMA; bio_put(bio); r10_bio->devs[slot].bio = NULL; - if (mddev->ro) + if (mddev->ro || p2pdma_error) r10_bio->devs[slot].bio = IO_BLOCKED; else if (!test_bit(FailFast, &rdev->flags)) { freeze_array(conf, 1); -- 2.52.0