diff options
| author | David Francis <[email protected]> | 2025-07-17 14:35:55 +0000 |
|---|---|---|
| committer | Christian König <[email protected]> | 2025-07-18 06:59:24 +0000 |
| commit | 53096728b8910c6916ecc6c46a5abc5c678b58d9 (patch) | |
| tree | 4b64a70ad3874d8da30000aee8370e899a69159d /drivers/gpu/drm/drm_gem.c | |
| parent | drm: document DRM_MODE_PAGE_FLIP_EVENT interactions with atomic (diff) | |
| download | kernel-53096728b8910c6916ecc6c46a5abc5c678b58d9.tar.gz kernel-53096728b8910c6916ecc6c46a5abc5c678b58d9.zip | |
drm: Add DRM prime interface to reassign GEM handle
CRIU restore of drm buffer objects requires the ability to create
or import a buffer object with a specific gem handle.
Add new drm ioctl DRM_IOCTL_GEM_CHANGE_HANDLE, which takes
the gem handle of an object and moves that object to a
specified new gem handle.
This ioctl needs to call drm_prime_remove_buf_handle,
but that function acquires the prime lock, which the ioctl
needs to hold for other purposes.
Make drm_prime_remove_buf_handle not acquire the prime lock,
and change its other caller to reflect this.
The rest of the kernel patches required to enable CRIU can be
found at
https://lore.kernel.org/dri-devel/[email protected]/
v2 - Move documentation to UAPI headers
v3 - Always return 0 on success
Signed-off-by: David Francis <[email protected]>
Acked-by: Felix Kuehling <[email protected]>
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Christian König <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
| -rw-r--r-- | drivers/gpu/drm/drm_gem.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 0905ef6786e9..480f91db2e15 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -283,7 +283,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); @@ -934,6 +939,57 @@ err: return ret; } +int drm_gem_change_handle_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_gem_change_handle *args = data; + struct drm_gem_object *obj; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_GEM)) + return -EOPNOTSUPP; + + obj = drm_gem_object_lookup(file_priv, args->handle); + if (!obj) + return -ENOENT; + + if (args->handle == args->new_handle) + return 0; + + mutex_lock(&file_priv->prime.lock); + + spin_lock(&file_priv->table_lock); + ret = idr_alloc(&file_priv->object_idr, obj, + args->new_handle, args->new_handle + 1, GFP_NOWAIT); + spin_unlock(&file_priv->table_lock); + + if (ret < 0) + goto out_unlock; + + if (obj->dma_buf) { + ret = drm_prime_add_buf_handle(&file_priv->prime, obj->dma_buf, args->new_handle); + if (ret < 0) { + spin_lock(&file_priv->table_lock); + idr_remove(&file_priv->object_idr, args->new_handle); + spin_unlock(&file_priv->table_lock); + goto out_unlock; + } + + drm_prime_remove_buf_handle(&file_priv->prime, args->handle); + } + + ret = 0; + + spin_lock(&file_priv->table_lock); + idr_remove(&file_priv->object_idr, args->handle); + spin_unlock(&file_priv->table_lock); + +out_unlock: + mutex_unlock(&file_priv->prime.lock); + + return ret; +} + /** * drm_gem_open - initializes GEM file-private structures at devnode open time * @dev: drm_device which is being opened by userspace |
