Hi Jason, Thomas, Christian,
 
> If the importer provides an op for supports_interconnects(), the
> exporter starts the matching (or negotiation) process (during
> attach) by invoking the supports_interconnects() which would then
> call this helper to identify the first common interconnect
> supported by both exporter and importer.
> 
> Note that whether an interconnect is supported between an
> exporter/importer is ultimately determined by the exporter via
> the match op it is expected to provide.
Does this design look OK to you?

Thanks,
Vivek

> 
> Cc: Jason Gunthorpe <[email protected]>
> Cc: Christian Koenig <[email protected]>
> Cc: Sumit Semwal <[email protected]>
> Cc: Thomas Hellström <[email protected]>
> Cc: Simona Vetter <[email protected]>
> Signed-off-by: Vivek Kasireddy <[email protected]>
> ---
>  drivers/dma-buf/dma-buf.c            | 45 +++++++++++++++++++++++++++-
>  include/linux/dma-buf-interconnect.h |  6 ++++
>  include/linux/dma-buf.h              |  9 ++++++
>  3 files changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 162642bd53e8..ed48540d1c1d 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -965,8 +965,11 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf,
> struct device *dev,
> 
>       attach->dev = dev;
>       attach->dmabuf = dmabuf;
> -     if (importer_ops)
> +     if (importer_ops) {
>               attach->peer2peer = importer_ops->allow_peer2peer;
> +             if (importer_ops->supports_interconnects)
> +                     attach->allow_ic = true;
> +     }
>       attach->importer_ops = importer_ops;
>       attach->importer_priv = importer_priv;
> 
> @@ -1680,6 +1683,46 @@ void dma_buf_unmap_interconnect(struct
> dma_buf_attachment *attach,
>  }
>  EXPORT_SYMBOL_NS_GPL(dma_buf_unmap_interconnect, "DMA_BUF");
> 
> +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 *exp_ic, *imp_ic;
> +     const struct dma_buf_interconnect_ops *ic_ops;
> +     struct dma_buf *dmabuf = attach->dmabuf;
> +     unsigned int i, j;
> +
> +     if (!exp || !imp)
> +             return false;
> +
> +     if (!attach->allow_ic)
> +             return false;
> +
> +     ic_ops = dmabuf->ops->interconnect_ops;
> +     if (!ic_ops || !ic_ops->match_interconnect)
> +             return false;
> +
> +     for (i = 0; i < exp_ics; i++) {
> +             for (j = 0; j < imp_ics; j++) {
> +                     exp_ic = exp[i].interconnect;
> +                     imp_ic = imp[j].interconnect;
> +
> +                     if (exp_ic->type == imp_ic->type) {
> +                             if (ic_ops->match_interconnect(exp_ic, imp_ic)) 
> {
> +                                     attach->interconnect.type = exp_ic-
> >type;
> +                                     return true;
> +                             }
> +                     }
> +             }
> +     }
> +
> +     attach->allow_ic = false;
> +     return false;
> +}
> +EXPORT_SYMBOL_NS_GPL(dma_buf_match_interconnects, "DMA_BUF");
> +
>  #ifdef CONFIG_DEBUG_FS
>  static int dma_buf_debug_show(struct seq_file *s, void *unused)
>  {
> diff --git a/include/linux/dma-buf-interconnect.h b/include/linux/dma-buf-
> interconnect.h
> index 17504dea9691..a72f65ed4806 100644
> --- a/include/linux/dma-buf-interconnect.h
> +++ b/include/linux/dma-buf-interconnect.h
> @@ -20,10 +20,16 @@ struct dma_buf_interconnect {
>       enum dma_buf_interconnect_type type;
>  };
> 
> +struct dma_buf_interconnect_match {
> +     const struct dma_buf_interconnect *interconnect;
> +};
> +
>  struct dma_buf_interconnect_ops {
>       int (*map_interconnect)(struct dma_buf_attachment *attach,
>                               struct dma_buf_ranges *ranges);
>       void (*unmap_interconnect)(struct dma_buf_attachment *attach,
>                                  struct dma_buf_ranges *ranges);
> +     bool (*match_interconnect)(const struct dma_buf_interconnect
> *exp_ic,
> +                                const struct dma_buf_interconnect *imp_ic);
>  };
>  #endif
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index db91c67c00d6..3e6124387f3c 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -479,6 +479,10 @@ struct dma_buf_attach_ops {
>        * point to the new location of the DMA-buf.
>        */
>       void (*move_notify)(struct dma_buf_attachment *attach);
> +
> +     bool (*supports_interconnects)(struct dma_buf_attachment *attach,
> +                                    const struct dma_buf_interconnect_match 
> *,
> +                                    unsigned int num_ics);
>  };
> 
>  /**
> @@ -599,6 +603,11 @@ void dma_buf_unmap_attachment(struct
> dma_buf_attachment *, struct sg_table *,
>  struct dma_buf_ranges *dma_buf_map_interconnect(struct
> dma_buf_attachment *);
>  void dma_buf_unmap_interconnect(struct dma_buf_attachment *,
>                               struct dma_buf_ranges *);
> +bool dma_buf_match_interconnects(struct dma_buf_attachment *attach,
> +                              const struct dma_buf_interconnect_match *,
> +                              unsigned int exp_ics,
> +                              const struct dma_buf_interconnect_match *,
> +                              unsigned int imp_ics);
> 
>  void dma_buf_move_notify(struct dma_buf *dma_buf);
>  int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
> --
> 2.50.1

Reply via email to