CRIU restore of drm buffer objects requires the ability to create
a buffer object with a specific gem handle.

Add function drm_prime_change_buf_handle to change the gem handle
of a specified buffer object.

This function calls drm_gem_object_release_handle.
drm_gem_object_release_handle is an internal function with one caller;
make it not acquire the prime lock.

Signed-off-by: David Francis <david.fran...@amd.com>
---
 drivers/gpu/drm/drm_gem.c   |  5 ++++
 drivers/gpu/drm/drm_prime.c | 47 +++++++++++++++++++++++++++++++++----
 include/drm/drm_prime.h     |  2 ++
 3 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index ee811764c3df..f56eeed808d2 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -282,7 +282,12 @@ drm_gem_object_release_handle(int id, void *ptr, void 
*data)
        if (obj->funcs->close)
                obj->funcs->close(obj, file_priv);
 
+       mutex_lock(&file_priv->prime.lock);
+
        drm_prime_remove_buf_handle(&file_priv->prime, id);
+
+       mutex_unlock(&file_priv->prime.lock);
+
        drm_vma_node_revoke(&obj->vma_node, file_priv);
 
        drm_gem_object_handle_put_unlocked(obj);
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 0e3f8adf162f..08205b291825 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -190,8 +190,6 @@ void drm_prime_remove_buf_handle(struct 
drm_prime_file_private *prime_fpriv,
 {
        struct rb_node *rb;
 
-       mutex_lock(&prime_fpriv->lock);
-
        rb = prime_fpriv->handles.rb_node;
        while (rb) {
                struct drm_prime_member *member;
@@ -210,8 +208,6 @@ void drm_prime_remove_buf_handle(struct 
drm_prime_file_private *prime_fpriv,
                        rb = rb->rb_left;
                }
        }
-
-       mutex_unlock(&prime_fpriv->lock);
 }
 
 void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv)
@@ -1084,3 +1080,46 @@ void drm_prime_gem_destroy(struct drm_gem_object *obj, 
struct sg_table *sg)
        dma_buf_put(dma_buf);
 }
 EXPORT_SYMBOL(drm_prime_gem_destroy);
+
+/**
+ * drm_prime_change_buf_handle - function to change the gem handle of a bo
+ * @file_priv: drm file-private structure
+ * @gem_obj: gem object whose handle should be changed
+ * @newhandle: handle to change to
+ *
+ * Will fail if the gem object cannot be found or if the new handle
+ * is already in use.
+ */
+int drm_prime_change_buf_handle(struct drm_file *file_priv, struct 
drm_gem_object *gem_obj, int newhandle)
+{
+       int oldhandle = -1;
+       int ret;
+
+       mutex_lock(&file_priv->prime.lock);
+
+       ret = drm_prime_lookup_buf_handle(&file_priv->prime, gem_obj->dma_buf, 
&oldhandle);
+       if (ret < 0)
+               goto out_unlock;
+
+       drm_prime_remove_buf_handle(&file_priv->prime, oldhandle);
+
+       spin_lock(&file_priv->table_lock);
+
+       idr_remove(&file_priv->object_idr, oldhandle);
+       ret = idr_alloc(&file_priv->object_idr, gem_obj, newhandle, newhandle + 
1, GFP_NOWAIT);
+
+       spin_unlock(&file_priv->table_lock);
+
+       if (ret < 0)
+               goto out_unlock;
+
+       ret = drm_prime_add_buf_handle(&file_priv->prime, gem_obj->dma_buf, 
newhandle);
+       if (ret < 0)
+               goto out_unlock;
+
+out_unlock:
+       mutex_unlock(&file_priv->prime.lock);
+
+       return ret;
+}
+EXPORT_SYMBOL(drm_prime_change_buf_handle);
\ No newline at end of file
diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
index fa085c44d4ca..5a9288493dd7 100644
--- a/include/drm/drm_prime.h
+++ b/include/drm/drm_prime.h
@@ -112,5 +112,7 @@ int drm_prime_sg_to_page_array(struct sg_table *sgt, struct 
page **pages,
                               int max_pages);
 int drm_prime_sg_to_dma_addr_array(struct sg_table *sgt, dma_addr_t *addrs,
                                   int max_pages);
+int drm_prime_change_buf_handle(struct drm_file *file_priv,
+                               struct drm_gem_object *gem_obj, int newhandle);
 
 #endif /* __DRM_PRIME_H__ */
-- 
2.34.1

Reply via email to