From: Jason Gunthorpe <[email protected]> Introduce single_exporter_match into the dma_buf_ops so that single exporter drivers can simply set it using a static initializer to use the mapping type APIs. Provide a helper macro DMA_BUF_SIMPLE_SGT_EXP_MATCH() that generates the initializer for simple drivers that don't use P2P.
More complex exporters, especially those with P2P, need to implement the match_mapping call back to extract things like their DMA struct device from the dma_buf in order to do the P2P calculations. Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Alistair Popple <[email protected]> --- drivers/dma-buf/dma-buf.c | 14 +++++++++++--- include/linux/dma-buf-mapping.h | 15 +++++++++++++++ include/linux/dma-buf.h | 9 +++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index fc1e62a0b388..70cfab4d9c49 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -718,10 +718,14 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) || !exp_info->ops->release)) return ERR_PTR(-EINVAL); - if (exp_info->ops->match_mapping) { + if (exp_info->ops->match_mapping || + exp_info->ops->single_exporter_match) { if (WARN_ON(exp_info->ops->map_dma_buf || exp_info->ops->unmap_dma_buf)) return ERR_PTR(-EINVAL); + if (WARN_ON(exp_info->ops->match_mapping && + exp_info->ops->single_exporter_match)) + return ERR_PTR(-EINVAL); } else { if (WARN_ON(!exp_info->ops->map_dma_buf || !exp_info->ops->unmap_dma_buf)) @@ -1096,8 +1100,12 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, if (ret) goto err_attach; } else { - ret = dma_buf_match_mapping(&match_args, - &dma_buf_sgt_exp_compat_match, 1); + const struct dma_buf_mapping_match *exp_match = + dmabuf->ops->single_exporter_match; + + if (!exp_match) + exp_match = &dma_buf_sgt_exp_compat_match; + ret = dma_buf_match_mapping(&match_args, exp_match, 1); if (ret) goto err_attach; } diff --git a/include/linux/dma-buf-mapping.h b/include/linux/dma-buf-mapping.h index a961314dbd99..b02eb6759d38 100644 --- a/include/linux/dma-buf-mapping.h +++ b/include/linux/dma-buf-mapping.h @@ -356,4 +356,19 @@ DMA_BUF_EMAPPING_SGT_REQUIRES_P2P(const struct dma_buf_mapping_sgt_exp_ops *exp_ extern const struct dma_buf_mapping_match dma_buf_sgt_exp_compat_match; +/* + * dma_buf_ops initializer helper for simple drivers that use a single + * SGT map/unmap operation without P2P. + */ +#define DMA_BUF_SIMPLE_SGT_EXP_MATCH(_map, _unmap) \ + .single_exporter_match = &((const struct dma_buf_mapping_match){ \ + .type = &dma_buf_mapping_sgt_type, \ + .exp_ops = &((const struct dma_buf_mapping_sgt_exp_ops){ \ + .map_dma_buf = _map, \ + .unmap_dma_buf = _unmap, \ + }.ops), \ + .sgt_data = { \ + .exporter_requires_p2p = DMA_SGT_NO_P2P, \ + } }) + #endif diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 33582713a104..fc341b1257c3 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -364,6 +364,15 @@ struct dma_buf_ops { * disturbing a mapping that cannot be invalidated. */ int (*select_mapping)(struct dma_buf_attachment *attach); + + /** + * @single_exporter_match: + * + * Should only be set by the DMA_BUF_SIMPLE_*_EXP_MATCH() helper macros. + * Exactly one of @match_mapping or @single_exporter_match must be + * provided. + */ + const struct dma_buf_mapping_match *single_exporter_match; }; /** -- 2.54.0
