From: Kiran Kumar Modukuri <kmodukuri@nvidia.com> mainline inclusion from mainline-v7.2-rc1 commit 02666132403aec8fc5de315002894f713ef17dbc category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/10302 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- MD RAID does not propagate BLK_FEAT_PCI_P2PDMA from member devices to the RAID device, preventing peer-to-peer DMA through the RAID layer even when all underlying devices support it. Enable BLK_FEAT_PCI_P2PDMA unconditionally in raid0, raid1 and raid10 personalities during queue limits setup. blk_stack_limits() clears it automatically if any member device lacks support, consistent with how BLK_FEAT_NOWAIT and BLK_FEAT_POLL are handled in the block core. Parity RAID personalities (raid4/5/6) are excluded because they require CPU access to data pages for parity computation, which is incompatible with P2P mappings. Tested with RAID0/1/10 arrays containing multiple NVMe devices with P2PDMA support, confirming that peer-to-peer transfers work correctly through the RAID layer. Tested-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Xiao Ni <xni@redhat.com> Signed-off-by: Kiran Kumar Modukuri <kmodukuri@nvidia.com> Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com> Reviewed-by: Yu Kuai <yukuai@fygo.io> Tested=by: Pranjal Shrivastava <praan@google.com> Link: https://patch.msgid.link/20260513185153.95552-3-kch@nvidia.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Conflicts: drivers/md/raid0.c drivers/md/raid1.c drivers/md/raid10.c [OLK-6.6 has no raid*_set_limits() helpers and no queue_limits.features. The personalities set their limits inline in raid*_run() and stack member limits with disk_stack_limits(). Set QUEUE_FLAG_PCI_P2PDMA in those inline limit blocks before the disk_stack_limits() loop, so the clear added by the preceding block patch still enforces the all-member rule.] Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/md/raid0.c | 2 ++ drivers/md/raid1.c | 1 + drivers/md/raid10.c | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index c97daac92439..dfa93be8415a 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -402,10 +402,12 @@ static int raid0_run(struct mddev *mddev) blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); blk_queue_io_opt(mddev->queue, (mddev->chunk_sectors << 9) * mddev->raid_disks); + blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, mddev->queue); + rdev_for_each(rdev, mddev) { disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); } } diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index e045073b09f2..ce7092b57238 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -3218,10 +3218,11 @@ static int raid1_run(struct mddev *mddev) if (IS_ERR(conf)) return PTR_ERR(conf); if (!mddev_is_dm(mddev)) { blk_queue_max_write_zeroes_sectors(mddev->queue, 0); + blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, mddev->queue); rdev_for_each(rdev, mddev) disk_stack_limits(mddev->gendisk, rdev->bdev, rdev->data_offset << 9); } diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e8ce8cdd7fce..d267a02af348 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -4006,10 +4006,11 @@ static int raid10_run(struct mddev *mddev) if (!mddev_is_dm(conf->mddev)) { blk_queue_max_write_zeroes_sectors(mddev->queue, 0); blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); raid10_set_io_opt(conf); + blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, mddev->queue); } rdev_for_each(rdev, mddev) { long long diff; -- 2.52.0