Le 28/09/2026 à 15:32, Pavel Begunkov a écrit :
Enable BIO_DMABUF_MAP backed requests. On registration we map the dma-buf and store it as a prp list, which is then used to initialise requests. All attached contexts are stored in a new list dmabuf_ctxs, and additions/removals are synchronised with dmabuf_lock.
Suggested-by: Keith Busch kbusch@kernel.org Signed-off-by: Pavel Begunkov asml.silence@gmail.com
Hi,
a few nitpick below, should it help.
drivers/nvme/host/core.c | 12 ++ drivers/nvme/host/nvme.h | 2 + drivers/nvme/host/pci.c | 308 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+)
[...]
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index a953c0697f99..e58bdd9a4098 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -27,6 +27,8 @@ #include <linux/io-64-nonatomic-lo-hi.h> #include <linux/io-64-nonatomic-hi-lo.h> #include <linux/sed-opal.h> +#include <linux/dma-buf-io.h> +#include <linux/dma-resv.h>
Move up, to keep better alphabetical order ?
#include "trace.h" #include "nvme.h" @@ -318,6 +320,8 @@ struct nvme_dev { bool hmb; struct sg_table *hmb_sgt; mempool_t *dmavec_mempool;
- struct list_head dmabuf_ctxs;
- struct mutex dmabuf_lock;
/* shadow doorbell buffer support: */ __le32 *dbbuf_dbs; @@ -397,6 +401,13 @@ struct nvme_queue { struct completion delete_done; }; +struct nvme_dmabuf_map {
- struct dma_buf_io_map base;
- struct sg_table *sgt;
- unsigned nr_entries;
- dma_addr_t dma_list[];
Add __counted_by(nr_entries) and update nvme_dma_buf_io_map() so that nr_entries is set at the right time ?
+};
- /* bits for iod->flags */ enum nvme_iod_flags { /* this command has been aborted by the timeout handler */
...
+static struct dma_buf_io_map *nvme_dma_buf_io_map(struct dma_buf_io_ctx *ctx) +{
- unsigned nr_entries = ctx->dmabuf->size / NVME_CTRL_PAGE_SIZE;
- struct nvme_dma_buf_io_ctx *nvme_ctx = ctx->dev_priv;
- struct dma_buf_attachment *attach = nvme_ctx->attach;
- unsigned long tmp, i = 0;
- struct nvme_dmabuf_map *map;
- struct scatterlist *sg;
- struct sg_table *sgt;
- int ret;
- dma_resv_assert_held(ctx->dmabuf->resv);
- map = kvmalloc_flex(*map, dma_list, nr_entries);
- if (!map)
return ERR_PTR(-ENOMEM);- sgt = dma_buf_map_attachment(attach, ctx->dir);
- if (IS_ERR(sgt)) {
ret = PTR_ERR(sgt);sgt = NULL;goto err;- }
- for_each_sgtable_dma_sg(sgt, sg, tmp) {
dma_addr_t dma_addr = sg_dma_address(sg);unsigned long sg_len = sg_dma_len(sg);if ((sg_len % NVME_CTRL_PAGE_SIZE) ||(dma_addr % NVME_CTRL_PAGE_SIZE)) {ret = -EINVAL;goto err;}while (sg_len) {map->dma_list[i++] = dma_addr;dma_addr += NVME_CTRL_PAGE_SIZE;sg_len -= NVME_CTRL_PAGE_SIZE;}- }
- ret = dma_buf_io_init_map(ctx, &map->base, sgt);
- if (ret)
goto err;- map->nr_entries = nr_entries;
- map->sgt = sgt;
- return &map->base;
+err:
- if (sgt)
dma_buf_unmap_attachment(attach, sgt, ctx->dir);- kfree(map);
kvfree()?
- return ERR_PTR(ret);
+}
...
CJ