Skip to content

Commit b78dab8

Browse files
committed
drm/gem/shmem: Introduce __drm_gem_shmem_free_sgt_locked()
One of the complications of trying to use the shmem helpers to create a scatterlist for shmem objects is that we need to be able to provide a guarantee that the driver cannot be unbound for the lifetime of the scatterlist. The easiest way of handling this seems to be just hooking up an unmap operation to devres the first time we create a scatterlist, which allows us to still take advantage of gem shmem facilities without breaking that guarantee. To allow for this, we extract __drm_gem_shmem_free_sgt_locked() - which allows a caller (e.g. the rust bindings) to manually unmap the sgt for a gem object as needed. Signed-off-by: Lyude Paul <lyude@redhat.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260529183702.677677-6-lyude@redhat.com
1 parent 04b325f commit b78dab8

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

drivers/gpu/drm/drm_gem_shmem_helper.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,30 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t
158158
}
159159
EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
160160

161+
/**
162+
* __drm_gem_shmem_release_sgt_locked - Unpin and DMA unmap pages, and release the
163+
* cached scatter/gather table for an shmem GEM object.
164+
* @shmem: shmem GEM object
165+
*
166+
* If the passed shmem object has an active scatter/gather table for driver
167+
* usage, this function will unmap it and release the memory associated with it.
168+
* It is the responsibility of the caller to ensure it holds the dma_resv_lock
169+
* for this object.
170+
*
171+
* Drivers should not need to call this function themselves, it is mainly
172+
* intended for usage in the Rust shmem bindings.
173+
*/
174+
void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem)
175+
{
176+
dma_resv_assert_held(shmem->base.resv);
177+
178+
dma_unmap_sgtable(shmem->base.dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
179+
sg_free_table(shmem->sgt);
180+
kfree(shmem->sgt);
181+
shmem->sgt = NULL;
182+
}
183+
EXPORT_SYMBOL_GPL(__drm_gem_shmem_free_sgt_locked);
184+
161185
/**
162186
* drm_gem_shmem_release - Release resources associated with a shmem GEM object.
163187
* @shmem: shmem GEM object
@@ -176,12 +200,8 @@ void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem)
176200

177201
drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
178202

179-
if (shmem->sgt) {
180-
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
181-
DMA_BIDIRECTIONAL, 0);
182-
sg_free_table(shmem->sgt);
183-
kfree(shmem->sgt);
184-
}
203+
if (shmem->sgt)
204+
__drm_gem_shmem_free_sgt_locked(shmem);
185205
if (shmem->pages)
186206
drm_gem_shmem_put_pages_locked(shmem);
187207

include/drm/drm_gem_shmem_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shme
111111
struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
112112
void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem);
113113
void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
114+
void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem);
114115

115116
void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);
116117
int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);

0 commit comments

Comments
 (0)