[PATCH v7 06/13] nvme-pci: implement dma-buf backed requests
Christophe JAILLET
christophe.jaillet at wanadoo.fr
Tue Sep 29 08:45:39 PDT 2026
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 at kernel.org>
> Signed-off-by: Pavel Begunkov <asml.silence at 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
More information about the Linux-nvme
mailing list