From: Kiran Kumar Modukuri <kmodukuri@nvidia.com> mainline inclusion from mainline-v7.2-rc1 commit fb0eeeed91f3236133383445fee5cc8f20330e6e 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... -------------------------------- NVMe multipath does not expose BLK_FEAT_PCI_P2PDMA on the head disk even when all underlying controllers support it. Set BLK_FEAT_PCI_P2PDMA unconditionally in nvme_mpath_alloc_disk() alongside the other features. nvme_update_ns_info_block() already calls queue_limits_stack_bdev() to stack each path's limits onto the head disk, which routes through blk_stack_limits(). The core now clears BLK_FEAT_PCI_P2PDMA automatically if any path (e.g., FC) does not support it, consistent with how BLK_FEAT_NOWAIT and BLK_FEAT_POLL are handled. Tested-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Nitesh Shetty <nj.shetty@samsung.com> Signed-off-by: Kiran Kumar Modukuri <kmodukuri@nvidia.com> Signed-off-by: Chaitanya Kulkarni <kch@nvidia.com> Tested=by: Pranjal Shrivastava <praan@google.com> Link: https://patch.msgid.link/20260513185153.95552-4-kch@nvidia.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Conflicts: drivers/nvme/host/multipath.c drivers/nvme/host/core.c [OLK-6.6 has no queue_limits.features; the head disk capability is expressed as QUEUE_FLAG_PCI_P2PDMA. The path limits are stacked with blk_stack_limits() directly rather than through disk_stack_limits(), so the generic clear does not cover this path. Set the queue flag in nvme_mpath_alloc_disk() and clear it after the blk_stack_limits() calls in nvme_update_ns_info_generic() and nvme_update_ns_info_block() when the path queue does not advertise P2P.] Signed-off-by: Zizhi Wo <wozizhi@huawei.com> Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/nvme/host/core.c | 6 ++++++ drivers/nvme/host/multipath.c | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 317ce71b7904..d049b55efd03 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2052,10 +2052,13 @@ static int nvme_update_ns_info_generic(struct nvme_ns *ns, blk_mq_freeze_queue(ns->head->disk->queue); set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info)); nvme_mpath_revalidate_paths(ns); blk_stack_limits(&ns->head->disk->queue->limits, &ns->queue->limits, 0); + if (!blk_queue_pci_p2pdma(ns->queue)) + blk_queue_flag_clear(QUEUE_FLAG_PCI_P2PDMA, + ns->head->disk->queue); ns->head->disk->flags |= GENHD_FL_HIDDEN; blk_mq_unfreeze_queue(ns->head->disk->queue); } /* Hide the block-interface for these devices */ @@ -2127,10 +2130,13 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, nvme_update_disk_info(ns->head->disk, ns, id); set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info)); nvme_mpath_revalidate_paths(ns); blk_stack_limits(&ns->head->disk->queue->limits, &ns->queue->limits, 0); + if (!blk_queue_pci_p2pdma(ns->queue)) + blk_queue_flag_clear(QUEUE_FLAG_PCI_P2PDMA, + ns->head->disk->queue); disk_update_readahead(ns->head->disk); blk_mq_unfreeze_queue(ns->head->disk->queue); } ret = 0; diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 09cc0f880e83..5faf599cbea2 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -650,10 +650,11 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) ctrl->subsys->instance, head->instance); blk_queue_flag_set(QUEUE_FLAG_NONROT, head->disk->queue); blk_queue_flag_set(QUEUE_FLAG_NOWAIT, head->disk->queue); blk_queue_flag_set(QUEUE_FLAG_IO_STAT, head->disk->queue); + blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, head->disk->queue); /* * This assumes all controllers that refer to a namespace either * support poll queues or not. That is not a strict guarantee, * but if the assumption is wrong the effect is only suboptimal * performance but not correctness problem. -- 2.52.0