Re: [PATCH 4.19 005/118] nvme-pci: fix conflicting p2p resource adds

From: Logan Gunthorpe
Date: Mon Nov 26 2018 - 14:23:57 EST




On 2018-11-26 3:49 a.m., Greg Kroah-Hartman wrote:
> 4.19-stable review patch. If anyone has any objections, please let me know.

This commit is fixing a bug in the p2pdma code which was merged for
4.20. I'm not sure it would actually fix anything in the stable kernels.
On the other hand, based on my understanding, it shouldn't hurt anything
either.

Thanks,

Logan

> ------------------
>
> [ Upstream commit 9fe5c59ff6a1e5e26a39b75489a1420e7eaaf0b1 ]
>
> The nvme pci driver had been adding its CMB resource to the P2P DMA
> subsystem everytime on on a controller reset. This results in the
> following warning:
>
> ------------[ cut here ]------------
> nvme 0000:00:03.0: Conflicting mapping in same section
> WARNING: CPU: 7 PID: 81 at kernel/memremap.c:155 devm_memremap_pages+0xa6/0x380
> ...
> Call Trace:
> pci_p2pdma_add_resource+0x153/0x370
> nvme_reset_work+0x28c/0x17b1 [nvme]
> ? add_timer+0x107/0x1e0
> ? dequeue_entity+0x81/0x660
> ? dequeue_entity+0x3b0/0x660
> ? pick_next_task_fair+0xaf/0x610
> ? __switch_to+0xbc/0x410
> process_one_work+0x1cf/0x350
> worker_thread+0x215/0x3d0
> ? process_one_work+0x350/0x350
> kthread+0x107/0x120
> ? kthread_park+0x80/0x80
> ret_from_fork+0x1f/0x30
> ---[ end trace f7ea76ac6ee72727 ]---
> nvme nvme0: failed to register the CMB
>
> This patch fixes this by registering the CMB with P2P only once.
>
> Signed-off-by: Keith Busch <keith.busch@xxxxxxxxx>
> Reviewed-by: Logan Gunthorpe <logang@xxxxxxxxxxxx>
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> Signed-off-by: Jens Axboe <axboe@xxxxxxxxx>
> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
> ---
> drivers/nvme/host/pci.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
> index d668682f91df..da18e0ac9fa2 100644
> --- a/drivers/nvme/host/pci.c
> +++ b/drivers/nvme/host/pci.c
> @@ -1647,6 +1647,9 @@ static void nvme_map_cmb(struct nvme_dev *dev)
> struct pci_dev *pdev = to_pci_dev(dev->dev);
> int bar;
>
> + if (dev->cmb_size)
> + return;
> +
> dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);
> if (!dev->cmbsz)
> return;
> @@ -2129,7 +2132,6 @@ static void nvme_pci_disable(struct nvme_dev *dev)
> {
> struct pci_dev *pdev = to_pci_dev(dev->dev);
>
> - nvme_release_cmb(dev);
> pci_free_irq_vectors(pdev);
>
> if (pci_is_enabled(pdev)) {
> @@ -2577,6 +2579,7 @@ static void nvme_remove(struct pci_dev *pdev)
> nvme_stop_ctrl(&dev->ctrl);
> nvme_remove_namespaces(&dev->ctrl);
> nvme_dev_disable(dev, true);
> + nvme_release_cmb(dev);
> nvme_free_host_mem(dev);
> nvme_dev_remove_admin(dev);
> nvme_free_queues(dev, 0);
>