From: Alistair Popple <apopple@nvidia.com>
To: dri-devel@lists.freedesktop.org, christian.koenig@amd.com,
sumit.semwal@linaro.org, jgg@nvidia.com
Cc: "Alistair Popple" <apopple@nvidia.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Simona Vetter" <simona.vetter@ffwll.ch>,
"Matthew Brost" <matthew.brost@intel.com>,
"Vivek Kasireddy" <vivek.kasireddy@intel.com>,
"Dongwon Kim" <dongwon.kim@intel.com>,
"Leon Romanovsky" <leonro@nvidia.com>,
"Kevin Tian" <kevin.tian@intel.com>,
"Xu Yilun" <yilun.xu@linux.intel.com>,
"Karl Mehltretter" <kmehltretter@gmail.com>,
"Baolu Lu" <baolu.lu@linux.intel.com>,
"Felix Kuehling" <felix.kuehling@amd.com>,
"Alex Deucher" <alexander.deucher@amd.com>,
intel-xe@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
linux-media@vger.kernel.org, linaro-mm-sig@lists.linaro.org,
linux-rdma@vger.kernel.org, iommu@lists.linux.dev,
"Alexey Kardashevskiy" <aik@amd.com>,
zhipingz@meta.com, treding@nvidia.com, jhubbard@nvidia.com
Subject: [PATCH 01/26] dma-buf: Introduce DMA-buf mapping types
Date: Mon, 26 Oct 2026 16:35:52 +1100 [thread overview]
Message-ID: <20261026053623.202642-2-apopple@nvidia.com> (raw)
In-Reply-To: <20261026053623.202642-1-apopple@nvidia.com>
From: Jason Gunthorpe <jgg@nvidia.com>
DMA-buf mapping types allow the importer and exporter to negotiate the
format of the map/unmap to be used during the attachment.
Currently DMA-buf only supports struct scatterlist as the attachment map
operation. This is not sufficient for all use cases as dma_addr_t is a
very specific and limited type.
With mapping types the importing driver can declare what it supports. For
example:
struct dma_buf_mapping_match imp_match[] = {
DMA_BUF_IMAPPING_MY_DRIVER(dev, ...),
DMA_BUF_IMAPPING_SGT(dev, false),
};
attach = dma_buf_mapping_attach(dmabuf, imp_match, ...)
And the exporting driver can declare what it supports:
int exporter_match_mapping(struct dma_buf_match_args *args)
{
struct dma_buf_mapping_match exp_match[] = {
DMA_BUF_EMAPPING_MY_DRIVER(my_ops, dev, ...),
DMA_BUF_EMAPPING_SGT(sgt_ops, dev, false),
DMA_BUF_EMAPPING_PAL(PAL_ops),
};
return dma_buf_match_mapping(args, exp_match, ...);
}
During dma_buf_mapping_attach() the core code records every mutually
acceptable (exporter entry, importer entry) pair in attach->matches, a
small fixed-size array in the attachment, in the exporter's order of
preference. The first entry is the default and is what attach->map_type
holds; later patches let the exporter choose a different entry of the set
at pin or map time, when the buffer's placement and the other attachments
are known. Importers and exporters that list a single type see exactly one
entry.
Add the basic types:
struct dma_buf_mapping_type
Type tag and ops for each mapping type.
struct dma_buf_mapping_match
Entry in a list of importer or exporter match specifications.
The match specification can be extended by the mapping type with
unique data.
dma_buf_match_mapping() / struct dma_buf_match_args
Helper to do the matching. Called by the exporting driver
via a dma_buf_ops callback.
struct dma_buf_mapping_exp_ops
Base type for the per-mapping type exporter provided functions. This
would be the map/unmap callbacks. Each mapping type can provide its own
functions for map/unmap type operations with optimal type signatures.
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ dma_buf_match_mapping() records the whole match set in
attach->matches instead of stopping at the first match, so that the
exporter can choose among the mutually acceptable types later, at pin or
map time, rather than the core fixing one type at attach. - apopple ]
Co-developed-by: Alistair Popple <apopple@nvidia.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>
---
drivers/dma-buf/dma-buf-mapping.c | 62 +++++++++++++++++++++++++
include/linux/dma-buf-mapping.h | 76 +++++++++++++++++++++++++++++++
include/linux/dma-buf.h | 31 +++++++++++++
3 files changed, 169 insertions(+)
diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 833be519e1e6..616ab057fb28 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -5,6 +5,7 @@
*/
#include <linux/dma-buf-mapping.h>
#include <linux/dma-resv.h>
+#include <linux/dma-buf.h>
#include <linux/overflow.h>
#include <linux/align.h>
@@ -257,3 +258,64 @@ void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
}
EXPORT_SYMBOL_NS_GPL(dma_buf_free_sgt, "DMA_BUF");
+
+/**
+ * dma_buf_match_mapping - Record the mapping types agreed upon by exporter
+ * and importer
+ * @args: Match arguments from attach
+ * @exp: Array of mapping types supported by the exporter, in priority order
+ * @exp_len: Number of entries in @exp
+ *
+ * Walk the exporter's list in order and, for each entry, find the first
+ * importer entry of the same type that the type's match() callback accepts.
+ * Every such pair is recorded in @args->attach->matches, so the match set
+ * preserves the exporter's priority. The first entry becomes the default in
+ * @args->attach->map_type.
+ *
+ * Because the exporter list is walked in order, the exporter controls the
+ * priority of mapping types.
+ *
+ * Returns: 0 if at least one type matched, -EINVAL if none did, -E2BIG if
+ * more than DMA_BUF_MAX_MATCHES types matched, or the error a match() callback
+ * aborted the search with.
+ */
+int dma_buf_match_mapping(struct dma_buf_match_args *args,
+ const struct dma_buf_mapping_match *exp,
+ size_t exp_len)
+{
+ const struct dma_buf_mapping_match *exp_end = exp + exp_len;
+ const struct dma_buf_mapping_match *imp_end =
+ args->imp_matches + args->imp_len;
+ struct dma_buf_attachment *attach = args->attach;
+ unsigned int nr = 0;
+ int ret;
+
+ for (; exp != exp_end; exp++) {
+ const struct dma_buf_mapping_match *imp = args->imp_matches;
+
+ for (; imp != imp_end; imp++) {
+ if (exp->type != imp->type)
+ continue;
+ if (exp->type->match) {
+ ret = exp->type->match(args->dmabuf, exp, imp);
+ if (ret == -EOPNOTSUPP)
+ continue;
+ if (ret != 0)
+ return ret;
+ }
+ if (nr == ARRAY_SIZE(attach->matches))
+ return -E2BIG;
+ exp->type->finish_match(args, exp, imp);
+ attach->matches[nr++] = attach->map_type;
+ break;
+ }
+ }
+
+ if (!nr)
+ return -EINVAL;
+
+ attach->nr_matches = nr;
+ attach->map_type = attach->matches[0];
+ return 0;
+}
+EXPORT_SYMBOL_NS_GPL(dma_buf_match_mapping, "DMA_BUF");
diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h
index 09bde3f748e4..03a03624166b 100644
--- a/include/linux/dma-buf-mapping.h
+++ b/include/linux/dma-buf-mapping.h
@@ -7,6 +7,77 @@
#define __DMA_BUF_MAPPING_H__
#include <linux/dma-buf.h>
+struct device;
+struct dma_buf;
+struct dma_buf_attachment;
+struct dma_buf_mapping_exp_ops;
+
+/* Type tag for all mapping operations */
+struct dma_buf_mapping_exp_ops {};
+
+/*
+ * Internal struct to pass arguments from the attach function to the matching
+ * function
+ */
+struct dma_buf_match_args {
+ struct dma_buf *dmabuf;
+ struct dma_buf_attachment *attach;
+ const struct dma_buf_mapping_match *imp_matches;
+ size_t imp_len;
+};
+
+/**
+ * struct dma_buf_mapping_type - Operations for a DMA-buf mapping type
+ *
+ * Each mapping type provides a singleton instance of this struct to describe
+ * the mapping type and its operations.
+ */
+struct dma_buf_mapping_type {
+ /**
+ * @name: Human-readable name for this mapping type, used in debugfs
+ * output
+ */
+ const char *name;
+
+ /**
+ * @match:
+ *
+ * Called during attach from dma_buf_match_mapping(). &exp and &imp are
+ * single items from the importer and exporter mapping match lists.
+ * Both will have the same instance of this struct as their type member.
+ *
+ * It determines if the exporter/importer are compatible.
+ *
+ * Returns: 0 on success
+ * -EOPNOTSUPP means ignore the failure and continue
+ * Everything else aborts the search and returns the -errno
+ */
+ int (*match)(struct dma_buf *dmabuf,
+ const struct dma_buf_mapping_match *exp,
+ const struct dma_buf_mapping_match *imp);
+
+ /**
+ * @finish_match:
+ *
+ * Called by dma_buf_match_mapping() after a successful match to store
+ * the negotiated result in @args->attach. The matched @exp and @imp
+ * entries are provided so the callback can copy type-specific data into
+ * the attachment.
+ */
+ void (*finish_match)(struct dma_buf_match_args *args,
+ const struct dma_buf_mapping_match *exp,
+ const struct dma_buf_mapping_match *imp);
+
+ /**
+ * @debugfs_dump:
+ *
+ * Optional callback to write mapping-type-specific diagnostic
+ * information about @attach to the debugfs seq_file @s.
+ */
+ void (*debugfs_dump)(struct seq_file *s,
+ struct dma_buf_attachment *attach);
+};
+
struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
struct p2pdma_provider *provider,
struct phys_vec *phys_vec,
@@ -14,4 +85,9 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
enum dma_data_direction dir);
void dma_buf_free_sgt(struct dma_buf_attachment *attach, struct sg_table *sgt,
enum dma_data_direction dir);
+
+int dma_buf_match_mapping(struct dma_buf_match_args *args,
+ const struct dma_buf_mapping_match *exp_mappings,
+ size_t exp_len);
+
#endif
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index d15b2b31d3c9..a749562c1728 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -27,6 +27,28 @@
struct device;
struct dma_buf;
struct dma_buf_attachment;
+struct dma_buf_mapping_type;
+struct dma_buf_mapping_exp_ops;
+
+/*
+ * Upper bound on the number of mapping types an attachment can record as
+ * mutually acceptable. An exporter offering more compatible types than this
+ * to one importer fails the attach with -E2BIG.
+ */
+#define DMA_BUF_MAX_MATCHES 4
+
+/*
+ * Match items are generated by the importer using the DMA_BUF_IMAPPING_*() and
+ * the exporter using the DMA_BUF_EMAPPING_*() functions. Each mapping type
+ * defines its own signature with its own data to make the match and attachment.
+ */
+struct dma_buf_mapping_match {
+ const struct dma_buf_mapping_type *type;
+ const struct dma_buf_mapping_exp_ops *exp_ops;
+ union {
+ /* Each mapping_type has unique match parameters here */
+ };
+};
/**
* struct dma_buf_ops - operations possible on struct dma_buf
@@ -472,6 +494,12 @@ struct dma_buf_attach_ops {
* @importer_ops: importer operations for this attachment, if provided
* dma_buf_map/unmap_attachment() must be called with the dma_resv lock held.
* @importer_priv: importer specific attachment data.
+ * @map_type: The match this attachment is mapped with. Until the exporter
+ * selects otherwise it holds the exporter's default, the first
+ * entry of @matches.
+ * @matches: The match set negotiated at attach time: every mapping type both
+ * sides accept, in the exporter's order of preference.
+ * @nr_matches: Number of valid entries in @matches.
*
* This structure holds the attachment information between the dma_buf buffer
* and its user device(s). The list contains one attachment struct per device
@@ -490,6 +518,9 @@ struct dma_buf_attachment {
const struct dma_buf_attach_ops *importer_ops;
void *importer_priv;
void *priv;
+ struct dma_buf_mapping_match map_type;
+ struct dma_buf_mapping_match matches[DMA_BUF_MAX_MATCHES];
+ unsigned int nr_matches;
};
/**
--
2.54.0
next prev parent reply other threads:[~2026-10-26 5:36 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
2026-10-26 5:35 ` Alistair Popple [this message]
2026-10-26 7:00 ` [PATCH 01/26] dma-buf: Introduce " sashiko-bot
2026-10-26 5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
2026-10-26 7:04 ` sashiko-bot
2026-10-26 5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
2026-10-26 7:20 ` sashiko-bot
2026-10-26 5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
2026-10-26 7:29 ` sashiko-bot
2026-10-26 5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
2026-10-26 7:39 ` sashiko-bot
2026-10-26 8:03 ` Karl Mehltretter
2026-10-27 5:46 ` Alistair Popple
2026-10-26 5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
2026-10-26 7:42 ` sashiko-bot
2026-10-26 5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
2026-10-26 7:56 ` sashiko-bot
2026-10-26 5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
2026-10-26 7:58 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
2026-10-26 8:02 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
2026-10-26 8:12 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
2026-10-26 8:13 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26 8:18 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
2026-10-26 8:34 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
2026-10-26 8:46 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
2026-10-26 9:00 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26 9:16 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
2026-10-26 9:26 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
2026-10-26 9:28 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
2026-10-26 9:35 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
2026-10-26 9:39 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
2026-10-26 9:49 ` sashiko-bot
2026-10-27 12:05 ` Christian König
2026-10-27 12:35 ` Jason Gunthorpe
2026-10-26 5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
2026-10-26 9:56 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
2026-10-26 10:01 ` sashiko-bot
2026-10-27 2:15 ` Karl Mehltretter
2026-10-27 3:42 ` Mikko Perttunen
2026-10-27 12:33 ` Jason Gunthorpe
2026-10-27 13:34 ` Mikko Perttunen
2026-10-27 13:43 ` Christian König
2026-10-27 12:11 ` Christian König
2026-10-27 12:31 ` Jason Gunthorpe
2026-10-27 12:07 ` Christian König
2026-10-27 12:38 ` Jason Gunthorpe
2026-10-27 13:17 ` Christian König
2026-10-27 14:08 ` Jason Gunthorpe
2026-10-27 14:28 ` Christian König
2026-10-27 14:44 ` Jason Gunthorpe
2026-10-27 14:54 ` Christian König
2026-10-26 5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
2026-10-26 10:13 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
2026-10-26 10:19 ` sashiko-bot
2026-10-26 5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
2026-10-26 10:22 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261026053623.202642-2-apopple@nvidia.com \
--to=apopple@nvidia.com \
--cc=aik@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=baolu.lu@linux.intel.com \
--cc=christian.koenig@amd.com \
--cc=dongwon.kim@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=felix.kuehling@amd.com \
--cc=intel-xe@lists.freedesktop.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jhubbard@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kmehltretter@gmail.com \
--cc=leonro@nvidia.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=matthew.brost@intel.com \
--cc=simona.vetter@ffwll.ch \
--cc=sumit.semwal@linaro.org \
--cc=thomas.hellstrom@linux.intel.com \
--cc=treding@nvidia.com \
--cc=vivek.kasireddy@intel.com \
--cc=yilun.xu@linux.intel.com \
--cc=zhipingz@meta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox