]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Revert "drm/prime: remove drm_prime_lookup_buf_by_handle"
authorChristian König <christian.koenig@amd.com>
Fri, 13 Jun 2025 13:50:41 +0000 (15:50 +0200)
committerChristian König <christian.koenig@amd.com>
Fri, 13 Jun 2025 13:52:52 +0000 (15:52 +0200)
This reverts commit c2aa5603af309968a10f8e0d929ec7662ada5f78.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Simona Vetter <simona.vetter@ffwll.ch>
Link: https://lore.kernel.org/r/aEwls5hPP9p-DPtt@phenom.ffwll.local
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_internal.h
drivers/gpu/drm/drm_prime.c

index a8c1c7b7be6cd23299f03e8449b9455c3a7ad737..a0a3b6baa56903c503d833d2563b02e3b5761a7d 100644 (file)
@@ -282,7 +282,7 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
        if (obj->funcs->close)
                obj->funcs->close(obj, file_priv);
 
-       drm_prime_remove_buf_handle(&file_priv->prime, obj->dma_buf, id);
+       drm_prime_remove_buf_handle(&file_priv->prime, id);
        drm_vma_node_revoke(&obj->vma_node, file_priv);
 
        drm_gem_object_handle_put_unlocked(obj);
index 1572b8af543f143932fd76e88076db3163ce7c7a..442eb31351ddd998652b4758e2546a82422e1937 100644 (file)
@@ -86,7 +86,6 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data,
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
 void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
-                                struct dma_buf *dma_buf,
                                 uint32_t handle);
 
 /* drm_managed.c */
index 1d93b44c00c41edcca236dec8a8672c04ae1edab..b703f83874e13f57f5192a03e8a0a725d4b8bd13 100644 (file)
@@ -90,6 +90,7 @@ struct drm_prime_member {
        uint32_t handle;
 
        struct rb_node dmabuf_rb;
+       struct rb_node handle_rb;
 };
 
 static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
@@ -121,9 +122,45 @@ static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
        rb_link_node(&member->dmabuf_rb, rb, p);
        rb_insert_color(&member->dmabuf_rb, &prime_fpriv->dmabufs);
 
+       rb = NULL;
+       p = &prime_fpriv->handles.rb_node;
+       while (*p) {
+               struct drm_prime_member *pos;
+
+               rb = *p;
+               pos = rb_entry(rb, struct drm_prime_member, handle_rb);
+               if (handle > pos->handle)
+                       p = &rb->rb_right;
+               else
+                       p = &rb->rb_left;
+       }
+       rb_link_node(&member->handle_rb, rb, p);
+       rb_insert_color(&member->handle_rb, &prime_fpriv->handles);
+
        return 0;
 }
 
+static struct dma_buf *drm_prime_lookup_buf_by_handle(struct drm_prime_file_private *prime_fpriv,
+                                                     uint32_t handle)
+{
+       struct rb_node *rb;
+
+       rb = prime_fpriv->handles.rb_node;
+       while (rb) {
+               struct drm_prime_member *member;
+
+               member = rb_entry(rb, struct drm_prime_member, handle_rb);
+               if (member->handle == handle)
+                       return member->dma_buf;
+               else if (member->handle < handle)
+                       rb = rb->rb_right;
+               else
+                       rb = rb->rb_left;
+       }
+
+       return NULL;
+}
+
 static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpriv,
                                       struct dma_buf *dma_buf,
                                       uint32_t *handle)
@@ -149,28 +186,25 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri
 }
 
 void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
-                                struct dma_buf *dma_buf,
                                 uint32_t handle)
 {
        struct rb_node *rb;
 
-       if (!dma_buf)
-               return;
-
        mutex_lock(&prime_fpriv->lock);
 
-       rb = prime_fpriv->dmabufs.rb_node;
+       rb = prime_fpriv->handles.rb_node;
        while (rb) {
                struct drm_prime_member *member;
 
-               member = rb_entry(rb, struct drm_prime_member, dmabuf_rb);
-               if (member->dma_buf == dma_buf && member->handle == handle) {
+               member = rb_entry(rb, struct drm_prime_member, handle_rb);
+               if (member->handle == handle) {
+                       rb_erase(&member->handle_rb, &prime_fpriv->handles);
                        rb_erase(&member->dmabuf_rb, &prime_fpriv->dmabufs);
 
                        dma_buf_put(member->dma_buf);
                        kfree(member);
                        break;
-               } else if (member->dma_buf < dma_buf) {
+               } else if (member->handle < handle) {
                        rb = rb->rb_right;
                } else {
                        rb = rb->rb_left;
@@ -412,6 +446,12 @@ struct dma_buf *drm_gem_prime_handle_to_dmabuf(struct drm_device *dev,
                goto out_unlock;
        }
 
+       dmabuf = drm_prime_lookup_buf_by_handle(&file_priv->prime, handle);
+       if (dmabuf) {
+               get_dma_buf(dmabuf);
+               goto out;
+       }
+
        mutex_lock(&dev->object_name_lock);
        /* re-export the original imported/exported object */
        if (obj->dma_buf) {