Hi all, On Wed, 27 Oct 2021 15:37:39 +1100 Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote: > > Today's linux-next merge of the char-misc tree got a conflict in: > > drivers/gpu/drm/tegra/gem.c > > between commit: > > 1c4d17a5267b ("drm/tegra: Implement correct DMA-BUF semantics") > > from the drm-tegra tree and commit: > > 16b0314aa746 ("dma-buf: move dma-buf symbols into the DMA_BUF module namespace") > > from the char-misc tree. > > I fixed it up (see below) and can carry the fix as necessary. This > is now fixed as far as linux-next is concerned, but any non trivial > conflicts should be mentioned to your upstream maintainer when your tree > is submitted for merging. You may also want to consider cooperating > with the maintainer of the conflicting tree to minimise any particularly > complex conflicts. > > -- > Cheers, > Stephen Rothwell > > diff --cc drivers/gpu/drm/tegra/gem.c > index 62fc7e8429d4,d38fd7e12b57..000000000000 > --- a/drivers/gpu/drm/tegra/gem.c > +++ b/drivers/gpu/drm/tegra/gem.c > @@@ -20,78 -21,60 +21,80 @@@ > #include "drm.h" > #include "gem.h" > > + MODULE_IMPORT_NS(DMA_BUF); > + > -static void tegra_bo_put(struct host1x_bo *bo) > +static unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents) > { > - struct tegra_bo *obj = host1x_to_tegra_bo(bo); > + dma_addr_t next = ~(dma_addr_t)0; > + unsigned int count = 0, i; > + struct scatterlist *s; > + > + for_each_sg(sgl, s, nents, i) { > + /* sg_dma_address(s) is only valid for entries that have sg_dma_len(s) != 0. */ > + if (!sg_dma_len(s)) > + continue; > + > + if (sg_dma_address(s) != next) { > + next = sg_dma_address(s) + sg_dma_len(s); > + count++; > + } > + } > > - drm_gem_object_put(&obj->gem); > + return count; > } > > -/* XXX move this into lib/scatterlist.c? */ > -static int sg_alloc_table_from_sg(struct sg_table *sgt, struct scatterlist *sg, > - unsigned int nents, gfp_t gfp_mask) > +static inline unsigned int sgt_dma_count_chunks(struct sg_table *sgt) > { > - struct scatterlist *dst; > - unsigned int i; > - int err; > - > - err = sg_alloc_table(sgt, nents, gfp_mask); > - if (err < 0) > - return err; > - > - dst = sgt->sgl; > + return sg_dma_count_chunks(sgt->sgl, sgt->nents); > +} > > - for (i = 0; i < nents; i++) { > - sg_set_page(dst, sg_page(sg), sg->length, 0); > - dst = sg_next(dst); > - sg = sg_next(sg); > - } > +static void tegra_bo_put(struct host1x_bo *bo) > +{ > + struct tegra_bo *obj = host1x_to_tegra_bo(bo); > > - return 0; > + drm_gem_object_put(&obj->gem); > } > > -static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo, > - dma_addr_t *phys) > +static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_bo *bo, > + enum dma_data_direction direction) > { > struct tegra_bo *obj = host1x_to_tegra_bo(bo); > - struct sg_table *sgt; > + struct drm_gem_object *gem = &obj->gem; > + struct host1x_bo_mapping *map; > int err; > > + map = kzalloc(sizeof(*map), GFP_KERNEL); > + if (!map) > + return ERR_PTR(-ENOMEM); > + > + kref_init(&map->ref); > + map->bo = host1x_bo_get(bo); > + map->direction = direction; > + map->dev = dev; > + > /* > - * If we've manually mapped the buffer object through the IOMMU, make > - * sure to return the IOVA address of our mapping. > - * > - * Similarly, for buffers that have been allocated by the DMA API the > - * physical address can be used for devices that are not attached to > - * an IOMMU. For these devices, callers must pass a valid pointer via > - * the @phys argument. > - * > - * Imported buffers were also already mapped at import time, so the > - * existing mapping can be reused. > + * Imported buffers need special treatment to satisfy the semantics of DMA-BUF. > */ > - if (phys) { > - *phys = obj->iova; > - return NULL; > + if (gem->import_attach) { > + struct dma_buf *buf = gem->import_attach->dmabuf; > + > + map->attach = dma_buf_attach(buf, dev); > + if (IS_ERR(map->attach)) { > + err = PTR_ERR(map->attach); > + goto free; > + } > + > + map->sgt = dma_buf_map_attachment(map->attach, direction); > + if (IS_ERR(map->sgt)) { > + dma_buf_detach(buf, map->attach); > + err = PTR_ERR(map->sgt); > + goto free; > + } > + > + err = sgt_dma_count_chunks(map->sgt); > + map->size = gem->size; > + > + goto out; > } > > /* This is now a conflict between the drm-tegra tree and Linus' tree. -- Cheers, Stephen Rothwell
Attachment:
pgpAbKALiKppP.pgp
Description: OpenPGP digital signature