mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
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
This commit is contained in:
parent
04b325fb34
commit
b78dab8297
|
|
@ -158,6 +158,30 @@ struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
|
||||
|
||||
/**
|
||||
* __drm_gem_shmem_release_sgt_locked - Unpin and DMA unmap pages, and release the
|
||||
* cached scatter/gather table for an shmem GEM object.
|
||||
* @shmem: shmem GEM object
|
||||
*
|
||||
* If the passed shmem object has an active scatter/gather table for driver
|
||||
* usage, this function will unmap it and release the memory associated with it.
|
||||
* It is the responsibility of the caller to ensure it holds the dma_resv_lock
|
||||
* for this object.
|
||||
*
|
||||
* Drivers should not need to call this function themselves, it is mainly
|
||||
* intended for usage in the Rust shmem bindings.
|
||||
*/
|
||||
void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem)
|
||||
{
|
||||
dma_resv_assert_held(shmem->base.resv);
|
||||
|
||||
dma_unmap_sgtable(shmem->base.dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
|
||||
sg_free_table(shmem->sgt);
|
||||
kfree(shmem->sgt);
|
||||
shmem->sgt = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__drm_gem_shmem_free_sgt_locked);
|
||||
|
||||
/**
|
||||
* drm_gem_shmem_release - Release resources associated with a shmem GEM object.
|
||||
* @shmem: shmem GEM object
|
||||
|
|
@ -176,12 +200,8 @@ void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem)
|
|||
|
||||
drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
|
||||
|
||||
if (shmem->sgt) {
|
||||
dma_unmap_sgtable(obj->dev->dev, shmem->sgt,
|
||||
DMA_BIDIRECTIONAL, 0);
|
||||
sg_free_table(shmem->sgt);
|
||||
kfree(shmem->sgt);
|
||||
}
|
||||
if (shmem->sgt)
|
||||
__drm_gem_shmem_free_sgt_locked(shmem);
|
||||
if (shmem->pages)
|
||||
drm_gem_shmem_put_pages_locked(shmem);
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shme
|
|||
struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
|
||||
void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem);
|
||||
void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
|
||||
void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem);
|
||||
|
||||
void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);
|
||||
int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user