[PATCH v7 01/13] dma-buf: introduce initial file I/O infrastructure
Christophe JAILLET
christophe.jaillet at wanadoo.fr
Tue Sep 29 09:12:29 PDT 2026
Le 28/09/2026 à 15:32, Pavel Begunkov a écrit :
> The goal is to be able to natively use dma-buf in the read-write / IO
> path. This patch adds basic building blocks serving as a glue and API
> between drivers and upper layer subsystems providing the uAPI. Later
> patches implement it for NVMe raw block devices and expose it to the
> user space via io_uring.
>
> There are two main objects. struct dma_buf_io_ctx and struct
> dma_buf_io_map. The ctx is used during initial registration and serves
> as an interface between the upper layer user like io_uring and to the
> importer subsystem / driver. The map represents the actual dma map
> established for the target device[s] with dma_buf_map_attachment() and
> stored in a device specific format. The context is created via a new
> file operation ->init_dma_buf_io_ctx.
>
> The ctx-map separation exists to support map invalidation (see
> dma_buf_io_invalidate_mappings()). A ctx can create
> multiple maps during its lifetime, but there can only be no more than
> one (active) map attached to it. Invalidation drops the active map
> if present, and the next map will only be attempted to be created
> once there is a new request that wants to use the dma-buf IO ctx.
>
> The primary task of the dma_buf_io_map object is to count requests
> using it and to wait for their completion when we want to destroy the
> DMA map.
>
> [un]mapping and any work with dma addresses is delegated to the
> importer driver via an ops table stored in the ctx, see struct
> dma_buf_io_ops. Only the target driver / subsystem knows about devices
> it wants to use the dma-buf with, especially in case of multi-device
> filesystems or stacking in the future.
>
> Signed-off-by: Pavel Begunkov <asml.silence at gmail.com>
> ---
Hi,
a few nitpicks below, should it help
> +static void dma_buf_io_kill_maps(struct dma_buf_io_ctx *ctx, bool final)
> +{
> + struct dma_buf_io_map *map;
> +
> + scoped_guard(mutex, &ctx->map_mutex) {
guard() is enough. This saves indentation.
> + if (final)
> + ctx->maps_killed = true;
> +
> + map = rcu_dereference_protected(ctx->map,
> + lockdep_is_held(&ctx->map_mutex));
> + if (!map)
> + return;
> + rcu_assign_pointer(ctx->map, NULL);
> + percpu_ref_kill(&map->refs);
> + }
> +}
...
> +int dma_buf_io_ctx_create(struct file *file,
> + struct dma_buf *dmabuf,
> + enum dma_data_direction dir,
> + struct dma_buf_io_ctx **out_ctx)
> +{
> + struct dma_buf_io_ctx *ctx;
> + int ret;
> +
> + if (!file->f_op->init_dma_buf_io_ctx)
> + return -EOPNOTSUPP;
> +
> + ctx = kmalloc_obj(*ctx);
kzalloc_obj() and save the memset() below
> + if (!ctx)
> + return -ENOMEM;
> +
> + memset(ctx, 0, sizeof(*ctx));
> + ctx->dir = dir;
> + ctx->dmabuf = dmabuf;
> + get_dma_buf(dmabuf);
> + mutex_init(&ctx->map_mutex);
> + mutex_init(&ctx->map_create_mutex);
> + atomic_set(&ctx->active_maps, 0);
> + atomic_set(&ctx->all_maps, 0);
> + refcount_set(&ctx->refs, 1);
> + init_waitqueue_head(&ctx->maps_wq);
> +
> + ret = file->f_op->init_dma_buf_io_ctx(file, ctx);
> + if (ret) {
> + kfree(ctx);
> + dma_buf_put(dmabuf);
> + return ret;
> + }
> +
> + if (WARN_ON_ONCE(!ctx->dev_ops ||
> + !ctx->dev_ops->map ||
> + !ctx->dev_ops->unmap ||
> + !ctx->dev_ops->release))
> + return -EINVAL;
> +
> + *out_ctx = ctx;
> + return 0;
> +}
...
CJ
More information about the Linux-nvme
mailing list