dma-buf: Use struct dma_buf_map in dma_buf_vunmap() interfaces
authorThomas Zimmermann <tzimmermann@suse.de>
Fri, 25 Sep 2020 11:56:00 +0000 (13:56 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 29 Sep 2020 10:41:21 +0000 (12:41 +0200)
This patch updates dma_buf_vunmap() and dma-buf's vunmap callback to
use struct dma_buf_map. The interfaces used to receive a buffer address.
This address is now given in an instance of the structure.

Users of the functions are updated accordingly. This is only an interface
change. It is currently expected that dma-buf memory can be accessed with
system memory load/store operations.

v2:
* include dma-buf-heaps and i915 selftests (kernel test robot)
* initialize cma_obj before using it in drm_gem_cma_free_object()
  (kernel test robot)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Sumit Semwal <sumit.semwal@linaro.org>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Tomasz Figa <tfiga@chromium.org>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200925115601.23955-4-tzimmermann@suse.de
16 files changed:
drivers/dma-buf/dma-buf.c
drivers/dma-buf/heaps/heap-helpers.c
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/drm_gem_shmem_helper.c
drivers/gpu/drm/drm_prime.c
drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
drivers/gpu/drm/i915/gem/selftests/i915_gem_dmabuf.c
drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
drivers/gpu/drm/tegra/gem.c
drivers/media/common/videobuf2/videobuf2-dma-contig.c
drivers/media/common/videobuf2/videobuf2-dma-sg.c
drivers/media/common/videobuf2/videobuf2-vmalloc.c
include/drm/drm_prime.h
include/linux/dma-buf-map.h
include/linux/dma-buf.h

index 61bd24d21b3875998a0f123451bd42a5b43533b9..a6ba4d598f0eb29bee977b568800d8203a9fc135 100644 (file)
@@ -1236,21 +1236,21 @@ EXPORT_SYMBOL_GPL(dma_buf_vmap);
 /**
  * dma_buf_vunmap - Unmap a vmap obtained by dma_buf_vmap.
  * @dmabuf:    [in]    buffer to vunmap
- * @vaddr:     [in]    vmap to vunmap
+ * @map:       [in]    vmap pointer to vunmap
  */
-void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
+void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
 {
        if (WARN_ON(!dmabuf))
                return;
 
        BUG_ON(dma_buf_map_is_null(&dmabuf->vmap_ptr));
        BUG_ON(dmabuf->vmapping_counter == 0);
-       BUG_ON(!dma_buf_map_is_vaddr(&dmabuf->vmap_ptr, vaddr));
+       BUG_ON(!dma_buf_map_is_equal(&dmabuf->vmap_ptr, map));
 
        mutex_lock(&dmabuf->lock);
        if (--dmabuf->vmapping_counter == 0) {
                if (dmabuf->ops->vunmap)
-                       dmabuf->ops->vunmap(dmabuf, vaddr);
+                       dmabuf->ops->vunmap(dmabuf, map);
                dma_buf_map_clear(&dmabuf->vmap_ptr);
        }
        mutex_unlock(&dmabuf->lock);
index 27e54d9c120cd3354d48bfa913b95b682dced647..e9fb2818f2d4d7bbc457b8fac9f46a4ada16998a 100644 (file)
@@ -252,7 +252,7 @@ static int dma_heap_dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map
        return 0;
 }
 
-static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr)
+static void dma_heap_dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map)
 {
        struct heap_helper_buffer *buffer = dmabuf->priv;
 
index eb412e45f8966af4f71b491950bf1c00222ff4bc..5e9d29961307e1063592ed0dae01b823f20c13a1 100644 (file)
@@ -175,13 +175,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
  */
 void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
 {
-       struct drm_gem_cma_object *cma_obj;
-
-       cma_obj = to_drm_gem_cma_obj(gem_obj);
+       struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj);
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(cma_obj->vaddr);
 
        if (gem_obj->import_attach) {
                if (cma_obj->vaddr)
-                       dma_buf_vunmap(gem_obj->import_attach->dmabuf, cma_obj->vaddr);
+                       dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map);
                drm_prime_gem_destroy(gem_obj, cma_obj->sgt);
        } else if (cma_obj->vaddr) {
                dma_free_wc(gem_obj->dev->dev, cma_obj->base.size,
@@ -645,7 +644,7 @@ drm_gem_cma_prime_import_sg_table_vmap(struct drm_device *dev,
 
        obj = drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
        if (IS_ERR(obj)) {
-               dma_buf_vunmap(attach->dmabuf, map.vaddr);
+               dma_buf_vunmap(attach->dmabuf, &map);
                return obj;
        }
 
index ad10a57cfece320bfc3d30682bfa3597d32b878a..3c2e8cde69a8685e6705dd54a5bca7d7cef04739 100644 (file)
@@ -337,6 +337,7 @@ EXPORT_SYMBOL(drm_gem_shmem_vmap);
 static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
 {
        struct drm_gem_object *obj = &shmem->base;
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(shmem->vaddr);
 
        if (WARN_ON_ONCE(!shmem->vmap_use_count))
                return;
@@ -345,7 +346,7 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem)
                return;
 
        if (obj->import_attach)
-               dma_buf_vunmap(obj->import_attach->dmabuf, shmem->vaddr);
+               dma_buf_vunmap(obj->import_attach->dmabuf, &map);
        else
                vunmap(shmem->vaddr);
 
index 2d75e58d21fea7e441e6e9cbaa2b75bf26aa19dc..4910c446db836a7036aabf68c9a1c15beba9427f 100644 (file)
@@ -687,16 +687,16 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vmap);
 /**
  * drm_gem_dmabuf_vunmap - dma_buf vunmap implementation for GEM
  * @dma_buf: buffer to be unmapped
- * @vaddr: the virtual address of the buffer
+ * @map: the virtual address of the buffer
  *
  * Releases a kernel virtual mapping. This can be used as the
  * &dma_buf_ops.vunmap callback. Calls into &drm_gem_object_funcs.vunmap for device specific handling.
  */
-void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
+void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
 {
        struct drm_gem_object *obj = dma_buf->priv;
 
-       drm_gem_vunmap(obj, vaddr);
+       drm_gem_vunmap(obj, map->vaddr);
 }
 EXPORT_SYMBOL(drm_gem_dmabuf_vunmap);
 
index 80a9fc143bbbc8cb8df1fa15371e88e9bc91ba1f..135fbff6fecf4d2c83d0141b584608336471353d 100644 (file)
@@ -70,9 +70,10 @@ void etnaviv_gem_prime_unpin(struct drm_gem_object *obj)
 
 static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj)
 {
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(etnaviv_obj->vaddr);
+
        if (etnaviv_obj->vaddr)
-               dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf,
-                              etnaviv_obj->vaddr);
+               dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, &map);
 
        /* Don't drop the pages for imported dmabuf, as they are not
         * ours, just free the array we allocated:
index 77b363d3000bdb431a6ffb14fd0615e11ebf8010..fec0e1e3dc3e1d763066f36b44d8b8a59c8d65c4 100644 (file)
@@ -96,7 +96,7 @@ static int i915_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map
        return 0;
 }
 
-static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
+static void i915_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
 {
        struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
 
index 3aad7643b0b7df1c134f7f6c044fbe2efeb419b1..b6d43880b0c19afabbbc5b53c535f07608eb4984 100644 (file)
@@ -152,7 +152,7 @@ static int igt_dmabuf_import(void *arg)
 
        err = 0;
 out_dma_map:
-       dma_buf_vunmap(dmabuf, dma_map);
+       dma_buf_vunmap(dmabuf, &map);
 out_obj:
        i915_gem_object_put(obj);
 out_dmabuf:
@@ -182,7 +182,7 @@ static int igt_dmabuf_import_ownership(void *arg)
        }
 
        memset(ptr, 0xc5, PAGE_SIZE);
-       dma_buf_vunmap(dmabuf, ptr);
+       dma_buf_vunmap(dmabuf, &map);
 
        obj = to_intel_bo(i915_gem_prime_import(&i915->drm, dmabuf));
        if (IS_ERR(obj)) {
@@ -250,7 +250,7 @@ static int igt_dmabuf_export_vmap(void *arg)
        memset(ptr, 0xc5, dmabuf->size);
 
        err = 0;
-       dma_buf_vunmap(dmabuf, ptr);
+       dma_buf_vunmap(dmabuf, &map);
 out:
        dma_buf_put(dmabuf);
        return err;
index dcae46441f7d8c64e603ff2a74938fe577b60adf..7dfef531f6d4a12c76526b53670f2ab149d32f12 100644 (file)
@@ -75,11 +75,11 @@ static int mock_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
        return 0;
 }
 
-static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr)
+static void mock_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map)
 {
        struct mock_dmabuf *mock = to_mock(dma_buf);
 
-       vm_unmap_ram(vaddr, mock->npages);
+       vm_unmap_ram(map->vaddr, mock->npages);
 }
 
 static int mock_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
index 2b6e06c7a2c590eb04971e9c769de9e7b5e85ad3..5df577682878c3923cf56f49c122f76f37242502 100644 (file)
@@ -149,11 +149,12 @@ static void *tegra_bo_mmap(struct host1x_bo *bo)
 static void tegra_bo_munmap(struct host1x_bo *bo, void *addr)
 {
        struct tegra_bo *obj = host1x_to_tegra_bo(bo);
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(addr);
 
        if (obj->vaddr)
                return;
        else if (obj->gem.import_attach)
-               dma_buf_vunmap(obj->gem.import_attach->dmabuf, addr);
+               dma_buf_vunmap(obj->gem.import_attach->dmabuf, &map);
        else
                vunmap(addr);
 }
@@ -663,7 +664,7 @@ static int tegra_gem_prime_vmap(struct dma_buf *buf, struct dma_buf_map *map)
        return 0;
 }
 
-static void tegra_gem_prime_vunmap(struct dma_buf *buf, void *vaddr)
+static void tegra_gem_prime_vunmap(struct dma_buf *buf, struct dma_buf_map *map)
 {
 }
 
index 11428287bdf3298a194134c63fde128189934d39..a1eb8279b113ad53f5533a78a9a0d553a3899788 100644 (file)
@@ -648,6 +648,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
 {
        struct vb2_dc_buf *buf = mem_priv;
        struct sg_table *sgt = buf->dma_sgt;
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr);
 
        if (WARN_ON(!buf->db_attach)) {
                pr_err("trying to unpin a not attached buffer\n");
@@ -660,7 +661,7 @@ static void vb2_dc_unmap_dmabuf(void *mem_priv)
        }
 
        if (buf->vaddr) {
-               dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
+               dma_buf_vunmap(buf->db_attach->dmabuf, &map);
                buf->vaddr = NULL;
        }
        dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
index c51170e9c1b9807d10ef2ea21b4fa3178225b14a..d5157e903e2769a7178e7898a8bc716a386cedcb 100644 (file)
@@ -580,6 +580,7 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
 {
        struct vb2_dma_sg_buf *buf = mem_priv;
        struct sg_table *sgt = buf->dma_sgt;
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr);
 
        if (WARN_ON(!buf->db_attach)) {
                pr_err("trying to unpin a not attached buffer\n");
@@ -592,7 +593,7 @@ static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
        }
 
        if (buf->vaddr) {
-               dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
+               dma_buf_vunmap(buf->db_attach->dmabuf, &map);
                buf->vaddr = NULL;
        }
        dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
index 7b68e2379c6551dda3c27ca5d3efff132b0046a0..11ba0eb1315b391814f8001bece80809a2a251b0 100644 (file)
@@ -390,17 +390,19 @@ static int vb2_vmalloc_map_dmabuf(void *mem_priv)
 static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
 {
        struct vb2_vmalloc_buf *buf = mem_priv;
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr);
 
-       dma_buf_vunmap(buf->dbuf, buf->vaddr);
+       dma_buf_vunmap(buf->dbuf, &map);
        buf->vaddr = NULL;
 }
 
 static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
 {
        struct vb2_vmalloc_buf *buf = mem_priv;
+       struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(buf->vaddr);
 
        if (buf->vaddr)
-               dma_buf_vunmap(buf->dbuf, buf->vaddr);
+               dma_buf_vunmap(buf->dbuf, &map);
 
        kfree(buf);
 }
index 3ee22639ff779c85cf1775e5a0be18c9df1c87ba..093f760cc13119f7f630dd20fb2cea60ffe74345 100644 (file)
@@ -84,7 +84,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
                           struct sg_table *sgt,
                           enum dma_data_direction dir);
 int drm_gem_dmabuf_vmap(struct dma_buf *dma_buf, struct dma_buf_map *map);
-void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, void *vaddr);
+void drm_gem_dmabuf_vunmap(struct dma_buf *dma_buf, struct dma_buf_map *map);
 
 int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
 int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma);
index 5ae732d373ebd09da498fd758149b05cba138c0a..c173a4abf4bae80b88c93db00c6369954606f153 100644 (file)
@@ -23,6 +23,16 @@ struct dma_buf_map {
        bool is_iomem;
 };
 
+/**
+ * DMA_BUF_MAP_INIT_VADDR - Initializes struct dma_buf_map to an address in system memory
+ * @vaddr:     A system-memory address
+ */
+#define DMA_BUF_MAP_INIT_VADDR(vaddr_) \
+       { \
+               .vaddr = (vaddr_), \
+               .is_iomem = false, \
+       }
+
 /**
  * dma_buf_map_set_vaddr - Sets a dma-buf mapping structure to an address in system memory
  * @map:       The dma-buf mapping structure
@@ -36,10 +46,26 @@ static inline void dma_buf_map_set_vaddr(struct dma_buf_map *map, void *vaddr)
        map->is_iomem = false;
 }
 
-/* API transition helper */
-static inline bool dma_buf_map_is_vaddr(const struct dma_buf_map *map, const void *vaddr)
+/**
+ * dma_buf_map_is_equal - Compares two dma-buf mapping structures for equality
+ * @lhs:       The dma-buf mapping structure
+ * @rhs:       A dma-buf mapping structure to compare with
+ *
+ * Two dma-buf mapping structures are equal if they both refer to the same type of memory
+ * and to the same address within that memory.
+ *
+ * Returns:
+ * True is both structures are equal, or false otherwise.
+ */
+static inline bool dma_buf_map_is_equal(const struct dma_buf_map *lhs,
+                                       const struct dma_buf_map *rhs)
 {
-       return !map->is_iomem && (map->vaddr == vaddr);
+       if (lhs->is_iomem != rhs->is_iomem)
+               return false;
+       else if (lhs->is_iomem)
+               return lhs->vaddr_iomem == rhs->vaddr_iomem;
+       else
+               return lhs->vaddr == rhs->vaddr;
 }
 
 /**
index 7237997cfa38160caae774aec25390ac86b26585..cf77cc15f4ba314cfe7d9c39e0db36e91b5da343 100644 (file)
@@ -267,7 +267,7 @@ struct dma_buf_ops {
        int (*mmap)(struct dma_buf *, struct vm_area_struct *vma);
 
        int (*vmap)(struct dma_buf *dmabuf, struct dma_buf_map *map);
-       void (*vunmap)(struct dma_buf *, void *vaddr);
+       void (*vunmap)(struct dma_buf *dmabuf, struct dma_buf_map *map);
 };
 
 /**
@@ -504,5 +504,5 @@ int dma_buf_end_cpu_access(struct dma_buf *dma_buf,
 int dma_buf_mmap(struct dma_buf *, struct vm_area_struct *,
                 unsigned long);
 int dma_buf_vmap(struct dma_buf *dmabuf, struct dma_buf_map *map);
-void dma_buf_vunmap(struct dma_buf *dmabuf, void *vaddr);
+void dma_buf_vunmap(struct dma_buf *dmabuf, struct dma_buf_map *map);
 #endif /* __DMA_BUF_H__ */