]> Git Repo - linux.git/commitdiff
drm/gem: Take reservation lock for vmap/vunmap operations
authorDmitry Osipenko <[email protected]>
Mon, 17 Oct 2022 17:22:11 +0000 (20:22 +0300)
committerDmitry Osipenko <[email protected]>
Mon, 17 Oct 2022 22:21:38 +0000 (01:21 +0300)
The new common dma-buf locking convention will require buffer importers
to hold the reservation lock around mapping operations. Make DRM GEM core
to take the lock around the vmapping operations and update DRM drivers to
use the locked functions for the case where DRM core now holds the lock.
This patch prepares DRM core and drivers to the common dynamic dma-buf
locking convention.

Acked-by: Christian König <[email protected]>
Signed-off-by: Dmitry Osipenko <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
drivers/gpu/drm/drm_client.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_gem_dma_helper.c
drivers/gpu/drm/drm_gem_framebuffer_helper.c
drivers/gpu/drm/drm_gem_ttm_helper.c
drivers/gpu/drm/lima/lima_sched.c
drivers/gpu/drm/panfrost/panfrost_dump.c
drivers/gpu/drm/panfrost/panfrost_perfcnt.c
drivers/gpu/drm/qxl/qxl_object.c
drivers/gpu/drm/qxl/qxl_prime.c
include/drm/drm_gem.h

index 2b230b4d694237524ca52f8e110e415c4d9575d1..fbcb1e995384a17d2c3158f2afe79b57b067a7a8 100644 (file)
@@ -323,7 +323,7 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer,
         * fd_install step out of the driver backend hooks, to make that
         * final step optional for internal users.
         */
-       ret = drm_gem_vmap(buffer->gem, map);
+       ret = drm_gem_vmap_unlocked(buffer->gem, map);
        if (ret)
                return ret;
 
@@ -345,7 +345,7 @@ void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
 {
        struct iosys_map *map = &buffer->map;
 
-       drm_gem_vunmap(buffer->gem, map);
+       drm_gem_vunmap_unlocked(buffer->gem, map);
 }
 EXPORT_SYMBOL(drm_client_buffer_vunmap);
 
index 86d670c712867163d8329c19c93ca8d7e1a64a92..dbee4863e4f71e1fb13daec56f5cf66901b1b083 100644 (file)
@@ -1171,6 +1171,8 @@ int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
        int ret;
 
+       dma_resv_assert_held(obj->resv);
+
        if (!obj->funcs->vmap)
                return -EOPNOTSUPP;
 
@@ -1186,6 +1188,8 @@ EXPORT_SYMBOL(drm_gem_vmap);
 
 void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
+       dma_resv_assert_held(obj->resv);
+
        if (iosys_map_is_null(map))
                return;
 
@@ -1197,6 +1201,26 @@ void drm_gem_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
 }
 EXPORT_SYMBOL(drm_gem_vunmap);
 
+int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
+{
+       int ret;
+
+       dma_resv_lock(obj->resv, NULL);
+       ret = drm_gem_vmap(obj, map);
+       dma_resv_unlock(obj->resv);
+
+       return ret;
+}
+EXPORT_SYMBOL(drm_gem_vmap_unlocked);
+
+void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map)
+{
+       dma_resv_lock(obj->resv, NULL);
+       drm_gem_vunmap(obj, map);
+       dma_resv_unlock(obj->resv);
+}
+EXPORT_SYMBOL(drm_gem_vunmap_unlocked);
+
 /**
  * drm_gem_lock_reservations - Sets up the ww context and acquires
  * the lock on an array of GEM objects.
index f6901ff97bbb5b55808e3da571b0744bedb18309..1e658c4483668df0dbabcec5fb98b7237d56b408 100644 (file)
@@ -230,7 +230,7 @@ void drm_gem_dma_free(struct drm_gem_dma_object *dma_obj)
 
        if (gem_obj->import_attach) {
                if (dma_obj->vaddr)
-                       dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map);
+                       dma_buf_vunmap_unlocked(gem_obj->import_attach->dmabuf, &map);
                drm_prime_gem_destroy(gem_obj, dma_obj->sgt);
        } else if (dma_obj->vaddr) {
                if (dma_obj->map_noncoherent)
@@ -581,7 +581,7 @@ drm_gem_dma_prime_import_sg_table_vmap(struct drm_device *dev,
        struct iosys_map map;
        int ret;
 
-       ret = dma_buf_vmap(attach->dmabuf, &map);
+       ret = dma_buf_vmap_unlocked(attach->dmabuf, &map);
        if (ret) {
                DRM_ERROR("Failed to vmap PRIME buffer\n");
                return ERR_PTR(ret);
@@ -589,7 +589,7 @@ drm_gem_dma_prime_import_sg_table_vmap(struct drm_device *dev,
 
        obj = drm_gem_dma_prime_import_sg_table(dev, attach, sgt);
        if (IS_ERR(obj)) {
-               dma_buf_vunmap(attach->dmabuf, &map);
+               dma_buf_vunmap_unlocked(attach->dmabuf, &map);
                return obj;
        }
 
index 880a4975507fc14c07cb8fa5b1ed3d79a33bd205..e35e224e6303a28fc0af4a8f9dc65351470b743f 100644 (file)
@@ -354,7 +354,7 @@ int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map,
                        ret = -EINVAL;
                        goto err_drm_gem_vunmap;
                }
-               ret = drm_gem_vmap(obj, &map[i]);
+               ret = drm_gem_vmap_unlocked(obj, &map[i]);
                if (ret)
                        goto err_drm_gem_vunmap;
        }
@@ -376,7 +376,7 @@ err_drm_gem_vunmap:
                obj = drm_gem_fb_get_obj(fb, i);
                if (!obj)
                        continue;
-               drm_gem_vunmap(obj, &map[i]);
+               drm_gem_vunmap_unlocked(obj, &map[i]);
        }
        return ret;
 }
@@ -403,7 +403,7 @@ void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map)
                        continue;
                if (iosys_map_is_null(&map[i]))
                        continue;
-               drm_gem_vunmap(obj, &map[i]);
+               drm_gem_vunmap_unlocked(obj, &map[i]);
        }
 }
 EXPORT_SYMBOL(drm_gem_fb_vunmap);
index e5fc875990c4f3308e0134f9dc0455e84d1f2ec0..d5962a34c01d5ff1a82b9044aa2382c3ef07e6fc 100644 (file)
@@ -64,13 +64,8 @@ int drm_gem_ttm_vmap(struct drm_gem_object *gem,
                     struct iosys_map *map)
 {
        struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
-       int ret;
-
-       dma_resv_lock(gem->resv, NULL);
-       ret = ttm_bo_vmap(bo, map);
-       dma_resv_unlock(gem->resv);
 
-       return ret;
+       return ttm_bo_vmap(bo, map);
 }
 EXPORT_SYMBOL(drm_gem_ttm_vmap);
 
@@ -87,9 +82,7 @@ void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
 {
        struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
 
-       dma_resv_lock(gem->resv, NULL);
        ttm_bo_vunmap(bo, map);
-       dma_resv_unlock(gem->resv);
 }
 EXPORT_SYMBOL(drm_gem_ttm_vunmap);
 
index e82931712d8a2acb29e993f82d77f250225a0895..ff003403fbbc7ffd04cd2986b5dbe833a32e7db6 100644 (file)
@@ -371,7 +371,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
                } else {
                        buffer_chunk->size = lima_bo_size(bo);
 
-                       ret = drm_gem_shmem_vmap(&bo->base, &map);
+                       ret = drm_gem_vmap_unlocked(&bo->base.base, &map);
                        if (ret) {
                                kvfree(et);
                                goto out;
@@ -379,7 +379,7 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
 
                        memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);
 
-                       drm_gem_shmem_vunmap(&bo->base, &map);
+                       drm_gem_vunmap_unlocked(&bo->base.base, &map);
                }
 
                buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
index 89056a1aac7dfef68aafd9316a789e532a5f487b..f62a019cc523a67c7bda3e21184e2bd666a27138 100644 (file)
@@ -209,7 +209,7 @@ void panfrost_core_dump(struct panfrost_job *job)
                        goto dump_header;
                }
 
-               ret = drm_gem_shmem_vmap(&bo->base, &map);
+               ret = drm_gem_vmap_unlocked(&bo->base.base, &map);
                if (ret) {
                        dev_err(pfdev->dev, "Panfrost Dump: couldn't map Buffer Object\n");
                        iter.hdr->bomap.valid = 0;
@@ -236,7 +236,7 @@ void panfrost_core_dump(struct panfrost_job *job)
                vaddr = map.vaddr;
                memcpy(iter.data, vaddr, bo->base.base.size);
 
-               drm_gem_shmem_vunmap(&bo->base, &map);
+               drm_gem_vunmap_unlocked(&bo->base.base, &map);
 
                iter.hdr->bomap.valid = cpu_to_le32(1);
 
index bc0df93f7f215665c51373c50afcf0afad69f64b..ba9b6e2b26363799f3330d01f5a0321435397f8a 100644 (file)
@@ -106,7 +106,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
                goto err_close_bo;
        }
 
-       ret = drm_gem_shmem_vmap(bo, &map);
+       ret = drm_gem_vmap_unlocked(&bo->base, &map);
        if (ret)
                goto err_put_mapping;
        perfcnt->buf = map.vaddr;
@@ -165,7 +165,7 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
        return 0;
 
 err_vunmap:
-       drm_gem_shmem_vunmap(bo, &map);
+       drm_gem_vunmap_unlocked(&bo->base, &map);
 err_put_mapping:
        panfrost_gem_mapping_put(perfcnt->mapping);
 err_close_bo:
@@ -195,7 +195,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
                  GPU_PERFCNT_CFG_MODE(GPU_PERFCNT_CFG_MODE_OFF));
 
        perfcnt->user = NULL;
-       drm_gem_shmem_vunmap(&perfcnt->mapping->obj->base, &map);
+       drm_gem_vunmap_unlocked(&perfcnt->mapping->obj->base.base, &map);
        perfcnt->buf = NULL;
        panfrost_gem_close(&perfcnt->mapping->obj->base.base, file_priv);
        panfrost_mmu_as_put(pfdev, perfcnt->mapping->mmu);
index 695d9308d1f08b8aa0bbfc518a63a696dcd995b1..06a58dad5f5cf4e8b78f5aa2955e801470388c34 100644 (file)
@@ -168,9 +168,16 @@ int qxl_bo_vmap_locked(struct qxl_bo *bo, struct iosys_map *map)
                bo->map_count++;
                goto out;
        }
-       r = ttm_bo_vmap(&bo->tbo, &bo->map);
+
+       r = __qxl_bo_pin(bo);
        if (r)
                return r;
+
+       r = ttm_bo_vmap(&bo->tbo, &bo->map);
+       if (r) {
+               __qxl_bo_unpin(bo);
+               return r;
+       }
        bo->map_count = 1;
 
        /* TODO: Remove kptr in favor of map everywhere. */
@@ -192,12 +199,6 @@ int qxl_bo_vmap(struct qxl_bo *bo, struct iosys_map *map)
        if (r)
                return r;
 
-       r = __qxl_bo_pin(bo);
-       if (r) {
-               qxl_bo_unreserve(bo);
-               return r;
-       }
-
        r = qxl_bo_vmap_locked(bo, map);
        qxl_bo_unreserve(bo);
        return r;
@@ -247,6 +248,7 @@ void qxl_bo_vunmap_locked(struct qxl_bo *bo)
                return;
        bo->kptr = NULL;
        ttm_bo_vunmap(&bo->tbo, &bo->map);
+       __qxl_bo_unpin(bo);
 }
 
 int qxl_bo_vunmap(struct qxl_bo *bo)
@@ -258,7 +260,6 @@ int qxl_bo_vunmap(struct qxl_bo *bo)
                return r;
 
        qxl_bo_vunmap_locked(bo);
-       __qxl_bo_unpin(bo);
        qxl_bo_unreserve(bo);
        return 0;
 }
index 142d01415acb37617826d7a4a2f3e81e29fa12ce..9169c26357d3660e5c1b38fba545b1a0dfb807f2 100644 (file)
@@ -59,7 +59,7 @@ int qxl_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
        struct qxl_bo *bo = gem_to_qxl_bo(obj);
        int ret;
 
-       ret = qxl_bo_vmap(bo, map);
+       ret = qxl_bo_vmap_locked(bo, map);
        if (ret < 0)
                return ret;
 
@@ -71,5 +71,5 @@ void qxl_gem_prime_vunmap(struct drm_gem_object *obj,
 {
        struct qxl_bo *bo = gem_to_qxl_bo(obj);
 
-       qxl_bo_vunmap(bo);
+       qxl_bo_vunmap_locked(bo);
 }
index 58a18a17c67ebb9c0d5b61f92f47947b281ed449..ed82039bfd5ba5ba412a0ec30eae53638d608d65 100644 (file)
@@ -408,6 +408,9 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj);
 void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages,
                bool dirty, bool accessed);
 
+int drm_gem_vmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
+void drm_gem_vunmap_unlocked(struct drm_gem_object *obj, struct iosys_map *map);
+
 int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles,
                           int count, struct drm_gem_object ***objs_out);
 struct drm_gem_object *drm_gem_object_lookup(struct drm_file *filp, u32 handle);
This page took 0.080273 seconds and 4 git commands to generate.