Am 28.03.25 um 19:06 schrieb David Francis: > 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);
That won't work like this. If this is the only handle (which is likely directly after creation) then that would potentially destroy the DMA-buf. > + > + 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); This needs to be an IOCTL and not an exported function. Re-ordering handles *must* be separate to re-creating the buffers. Regards, Christian. > \ 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__ */