The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of the entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h.

This driver creatively uses sg_table->orig_nents to store the size of the
allocate scatterlist and ignores the number of the entries returned by
dma_map_sg function. The sg_table->orig_nents is (mis)used to properly
free the (over)allocated scatterlist.

This patch only introduces common dma-mapping wrappers operating directly
on the struct sg_table objects to the dmabuf related functions, so the
other drivers, which might share buffers with i915 could rely on the
properly set nents and orig_nents values.

Signed-off-by: Marek Szyprowski <m.szyprow...@samsung.com>
---
For more information, see '[PATCH v3 00/25] DRM: fix struct sg_table nents
vs. orig_nents misuse' thread: https://lkml.org/lkml/2020/5/5/187
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++--------
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  7 +++----
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..7e8583e 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -48,12 +48,10 @@ static struct sg_table *i915_gem_map_dma_buf(struct 
dma_buf_attachment *attachme
                src = sg_next(src);
        }
 
-       if (!dma_map_sg_attrs(attachment->dev,
-                             st->sgl, st->nents, dir,
-                             DMA_ATTR_SKIP_CPU_SYNC)) {
-               ret = -ENOMEM;
+       ret = dma_map_sgtable_attrs(attachment->dev, st, dir,
+                                   DMA_ATTR_SKIP_CPU_SYNC);
+       if (ret)
                goto err_free_sg;
-       }
 
        return st;
 
@@ -73,9 +71,8 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment 
*attachment,
 {
        struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
-       dma_unmap_sg_attrs(attachment->dev,
-                          sg->sgl, sg->nents, dir,
-                          DMA_ATTR_SKIP_CPU_SYNC);
+       dma_unmap_sgtable_attrs(attachment->dev, sg, dir,
+                               DMA_ATTR_SKIP_CPU_SYNC);
        sg_free_table(sg);
        kfree(sg);
 
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c 
b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..756cb76 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,10 +28,9 @@ static struct sg_table *mock_map_dma_buf(struct 
dma_buf_attachment *attachment,
                sg = sg_next(sg);
        }
 
-       if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
-               err = -ENOMEM;
+       err = dma_map_sgtable(attachment->dev, st, dir);
+       if (err)
                goto err_st;
-       }
 
        return st;
 
@@ -46,7 +45,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment 
*attachment,
                               struct sg_table *st,
                               enum dma_data_direction dir)
 {
-       dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+       dma_unmap_sgtable(attachment->dev, st, dir);
        sg_free_table(st);
        kfree(st);
 }
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to