hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/10302 --------------------------------- A namespace that carries protection information cannot use P2P memory: generating or verifying PI makes the block layer walk the data pages, and P2P pages are not CPU accessible. nvme sets QUEUE_FLAG_PCI_P2PDMA when the namespace is created, but the integrity profile is registered later and can change on every revalidation. A PI namespace therefore keeps advertising P2P, and an I/O that carries P2P pages reaches bio_integrity_prep() and accesses memory the CPU cannot map. The capability has to follow the namespace's integrity state, which is only known after nvme_update_disk_info() has registered or dropped the profile. Keep it in sync on the path queue: clear it while the profile is present, and set it again when the profile is removed and the controller supports P2P. Signed-off-by: Zizhi Wo <wozizhi@huawei.com> --- drivers/nvme/host/core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 02a3d29c5947..a969ec2b762a 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2100,10 +2100,16 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, blk_mq_unfreeze_queue(ns->disk->queue); goto out; } nvme_set_chunk_sectors(ns, id); nvme_update_disk_info(ns->disk, ns, id); + /* P2P pages cannot be used for block layer PI processing. */ + if (blk_get_integrity(ns->disk)) + blk_queue_flag_clear(QUEUE_FLAG_PCI_P2PDMA, ns->queue); + else if (ns->ctrl->ops->supports_pci_p2pdma && + ns->ctrl->ops->supports_pci_p2pdma(ns->ctrl)) + blk_queue_flag_set(QUEUE_FLAG_PCI_P2PDMA, ns->queue); nvme_set_queue_limits(ns->ctrl, ns->queue); if (ns->head->ids.csi == NVME_CSI_ZNS) { ret = nvme_update_zone_info(ns, lbaf); if (ret) { -- 2.52.0