 
            On Sun, Oct 26, 2025 at 09:44:14PM -0700, Vivek Kasireddy wrote:
+/**
- dma_buf_match_interconnects - determine if there is a specific interconnect
- that is supported by both exporter and importer.
- @attach: [in] attachment to populate ic_match field
- @exp: [in] array of interconnects supported by exporter
- @exp_ics: [in] number of interconnects supported by exporter
- @imp: [in] array of interconnects supported by importer
- @imp_ics: [in] number of interconnects supported by importer
- This helper function iterates through the list interconnects supported by
- both exporter and importer to find a match. A successful match means that
- a common interconnect type is supported by both parties and the exporter's
- match_interconnect() callback also confirms that the importer is compatible
- with the exporter for that interconnect type.
Document which of the exporter/importer is supposed to call this
- If a match is found, the attach->ic_match field is populated with a copy
- of the exporter's match data.
- Return: true if a match is found, false otherwise.
- */
+bool dma_buf_match_interconnects(struct dma_buf_attachment *attach,
const struct dma_buf_interconnect_match *exp,
unsigned int exp_ics,
const struct dma_buf_interconnect_match *imp,
unsigned int imp_ics)+{
- const struct dma_buf_interconnect_ops *ic_ops;
- struct dma_buf_interconnect_match *ic_match;
- struct dma_buf *dmabuf = attach->dmabuf;
- unsigned int i, j;
- if (!exp || !imp)
return false;- if (!attach->allow_ic)
return false;
Seems redundant with this check for ic_ops == NULL:
- ic_ops = dmabuf->ops->interconnect_ops;
- if (!ic_ops || !ic_ops->match_interconnect)
return false;
This seems like too much of a maze to me..
I think you should structure it like this. First declare an interconnect:
struct dma_buf_interconnect iov_interconnect { .name = "IOV interconnect", .match =.. }
Then the exporters "subclass"
struct dma_buf_interconnect_ops vfio_iov_interconnect { .interconnect = &iov_interconnect, .map = vfio_map, }
I guess no container_of technique..
Then in VFIO's attach trigger the new code:
const struct dma_buf_interconnect_match vfio_exp_ics[] = { {&vfio_iov_interconnect}, };
dma_buf_match_interconnects(attach, &vfio_exp_ics))
Which will callback to the importer:
static const struct dma_buf_attach_ops xe_dma_buf_attach_ops = { .get_importer_interconnects }
dma_buf_match_interconnects() would call aops->get_importer_interconnects and matchs first on .interconnect, then call the interconnect->match function with exp/inpt match structs if not NULL.
+struct dma_buf_interconnect_match {
- const struct dma_buf_interconnect *type;
- struct device *dev;
- unsigned int bar;
+};
This should be more general, dev and bar are unique to the iov importer. Maybe just simple:
struct dma_buf_interconnect_match { struct dma_buf_interconnect *ic; // no need for type const struct dma_buf_interconnct_ops *exporter_ic_ops; u64 match_data[2]; // dev and bar are IOV specific, generalize };
Then some helper
const struct dma_buf_interconnect_match supports_ics[] = { IOV_INTERCONNECT(&vfio_iov_interconnect, dev, bar), }
And it would be nice if interconnect aware drivers could more easially interwork with non-interconnect importers.
So I'd add a exporter type of 'p2p dma mapped scatterlist' that just matches the legacy importer.
Jason