Hi Jason,
> Subject: Re: [RFC v2 2/8] dma-buf: Add a helper to match interconnects
> between exporter/importer
>
> 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
I missed adding that part. The importer is expected to call this in my current
design.
>
> > + *
> > + * 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:
Not really; attach->allow_ic would indicate if a successful match is
found or not. And, ic_ops is for the exporter to indicate whether it
supports interconnect ops or not.
>
> > + 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.
Ok, I'll try to test your suggestions.
>
> > +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
I am wondering what kind of match data would be needed for other
interconnects, so that we can try to generalize dma_buf_interconnect_match
or probably have interconnect specific implementations subclass it.
> };
>
> Then some helper
>
> const struct dma_buf_interconnect_match supports_ics[] = {
> IOV_INTERCONNECT(&vfio_iov_interconnect, dev, bar),
> }
I have done mostly the same thing as you suggest in patches 4 and 5 of this
series that add IOV interconnect support for vfio-pci and Xe drivers. Did you
get a chance to look at them?
>
> 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.
IIUC, even interconnect aware drivers (or exporters) would need to implement
map_dma_buf() op (which is mandatory) which would return an sg_table.
So, if match_interconnects() fails, then the exporter/importer would need to
fallback to using the legacy path.
Thanks,
Vivek
>
> Jason