[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250423092437.GA1895@lst.de>
Date: Wed, 23 Apr 2025 11:24:37 +0200
From: Christoph Hellwig <hch@....de>
To: Leon Romanovsky <leon@...nel.org>, Keith Busch <kbusch@...nel.org>
Cc: Marek Szyprowski <m.szyprowski@...sung.com>,
Jens Axboe <axboe@...nel.dk>, Christoph Hellwig <hch@....de>,
Jake Edge <jake@....net>, Jonathan Corbet <corbet@....net>,
Jason Gunthorpe <jgg@...pe.ca>, Zhu Yanjun <zyjzyj2000@...il.com>,
Robin Murphy <robin.murphy@....com>, Joerg Roedel <joro@...tes.org>,
Will Deacon <will@...nel.org>, Sagi Grimberg <sagi@...mberg.me>,
Bjorn Helgaas <bhelgaas@...gle.com>,
Logan Gunthorpe <logang@...tatee.com>,
Yishai Hadas <yishaih@...dia.com>,
Shameer Kolothum <shameerali.kolothum.thodi@...wei.com>,
Kevin Tian <kevin.tian@...el.com>,
Alex Williamson <alex.williamson@...hat.com>,
Jérôme Glisse <jglisse@...hat.com>,
Andrew Morton <akpm@...ux-foundation.org>,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-block@...r.kernel.org, linux-rdma@...r.kernel.org,
iommu@...ts.linux.dev, linux-nvme@...ts.infradead.org,
linux-pci@...r.kernel.org, kvm@...r.kernel.org, linux-mm@...ck.org,
Niklas Schnelle <schnelle@...ux.ibm.com>,
Chuck Lever <chuck.lever@...cle.com>,
Luis Chamberlain <mcgrof@...nel.org>,
Matthew Wilcox <willy@...radead.org>,
Dan Williams <dan.j.williams@...el.com>,
Kanchan Joshi <joshi.k@...sung.com>,
Chaitanya Kulkarni <kch@...dia.com>,
Nitesh Shetty <nj.shetty@...sung.com>,
Leon Romanovsky <leonro@...dia.com>
Subject: Re: [PATCH v9 23/24] nvme-pci: convert to blk_rq_dma_map
I don't think the meta SGL handling is quite right yet, and the
single segment data handling also regressed. Totally untested
patch below, I'll try to allocate some testing time later today.
Right now I don't have a test setup for metasgl, though. Keith,
do you have a good qemu config for that? Or anyone else?
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index f69f1eb4308e..80c21082b0c6 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -634,7 +634,11 @@ static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
dma_addr_t dma_addr;
if (iod->flags & IOD_SINGLE_SEGMENT) {
- dma_addr = le64_to_cpu(iod->cmd.common.dptr.prp1);
+ if (iod->cmd.common.flags &
+ (NVME_CMD_SGL_METABUF | NVME_CMD_SGL_METASEG))
+ dma_addr = le64_to_cpu(iod->cmd.common.dptr.sgl.addr);
+ else
+ dma_addr = le64_to_cpu(iod->cmd.common.dptr.prp1);
dma_unmap_page(dev->dev, dma_addr, iod->total_len,
rq_dma_dir(req));
return;
@@ -922,35 +926,37 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req)
return nvme_pci_setup_prps(dev, req);
}
-static __always_inline void nvme_unmap_metadata(struct nvme_dev *dev,
- struct request *req)
+static void nvme_unmap_metadata(struct nvme_dev *dev, struct request *req)
{
unsigned int entries = req->nr_integrity_segments;
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
struct nvme_sgl_desc *sg_list = iod->meta_list;
enum dma_data_direction dir = rq_dma_dir(req);
- dma_addr_t dma_addr;
- if (iod->flags & IOD_SINGLE_SEGMENT) {
- dma_addr = le64_to_cpu(iod->cmd.common.dptr.sgl.addr);
- dma_unmap_page(dev->dev, dma_addr, iod->total_len, rq_dma_dir(req));
+ /*
+ * If the NVME_CMD_SGL_METASEG flag is not set and we're using the
+ * non-SGL linear meta buffer we know that we have a single input
+ * segment as well.
+ *
+ * Note that it would be nice to always use the linear buffer when
+ * using IOVA mappings and kernel buffers to avoid the SGL
+ * indirection, but that's left for a future optimization.
+ */
+ if (!(iod->cmd.common.flags & NVME_CMD_SGL_METASEG)) {
+ dma_unmap_page(dev->dev,
+ le64_to_cpu(iod->cmd.common.dptr.prp1),
+ iod->total_len, rq_dma_dir(req));
return;
}
if (!blk_rq_dma_unmap(req, dev->dev, &iod->dma_meta_state,
iod->total_meta_len)) {
- if (iod->cmd.common.flags & NVME_CMD_SGL_METASEG) {
- unsigned int i;
+ unsigned int i;
- for (i = 0; i < entries; i++)
- dma_unmap_page(dev->dev,
- le64_to_cpu(sg_list[i].addr),
- le32_to_cpu(sg_list[i].length), dir);
- } else {
- dma_unmap_page(dev->dev, iod->meta_dma,
- rq_integrity_vec(req).bv_len, dir);
- return;
- }
+ for (i = 0; i < entries; i++)
+ dma_unmap_page(dev->dev,
+ le64_to_cpu(sg_list[i].addr),
+ le32_to_cpu(sg_list[i].length), dir);
}
dma_pool_free(dev->prp_small_pool, iod->meta_list, iod->meta_dma);
Powered by blists - more mailing lists