[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