Skip to content

Commit

Permalink
drm/shmem-helper: Pass GEM shmem object in public interfaces
Browse files Browse the repository at this point in the history
[ Upstream commit a193f3b ]

Change all GEM SHMEM object functions that receive a GEM object
of type struct drm_gem_object to expect an object of type
struct drm_gem_shmem_object instead.

This change reduces the number of upcasts from struct drm_gem_object
by moving them into callers. The C compiler can now verify that the
GEM SHMEM functions are called with the correct type.

For consistency, the patch also renames drm_gem_shmem_free_object to
drm_gem_shmem_free. It further updates documentation for a number of
functions.

v3:
	* fix docs for drm_gem_shmem_object_free()
v2:
	* mention _object_ callbacks in docs (Daniel)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20211108093149.7226-4-tzimmermann@suse.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Thomas Zimmermann authored and gregkh committed Aug 17, 2022
1 parent 4109ff9 commit ff0087d
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 102 deletions.
83 changes: 36 additions & 47 deletions drivers/gpu/drm/drm_gem_shmem_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
*
* This library provides helpers for GEM objects backed by shmem buffers
* allocated using anonymous pageable memory.
*
* Functions that operate on the GEM object receive struct &drm_gem_shmem_object.
* For GEM callback helpers in struct &drm_gem_object functions, see likewise
* named functions with an _object_ infix (e.g., drm_gem_shmem_object_vmap() wraps
* drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
*/

static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
Expand Down Expand Up @@ -112,15 +117,15 @@ 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_free_object - Free resources associated with a shmem GEM object
* @obj: GEM object to free
* drm_gem_shmem_free - Free resources associated with a shmem GEM object
* @shmem: shmem GEM object to free
*
* This function cleans up the GEM object state and frees the memory used to
* store the object itself.
*/
void drm_gem_shmem_free_object(struct drm_gem_object *obj)
void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
struct drm_gem_object *obj = &shmem->base;

WARN_ON(shmem->vmap_use_count);

Expand All @@ -144,7 +149,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
mutex_destroy(&shmem->vmap_lock);
kfree(shmem);
}
EXPORT_SYMBOL_GPL(drm_gem_shmem_free_object);
EXPORT_SYMBOL_GPL(drm_gem_shmem_free);

static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
{
Expand Down Expand Up @@ -224,18 +229,16 @@ EXPORT_SYMBOL(drm_gem_shmem_put_pages);

/**
* drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
* @obj: GEM object
* @shmem: shmem GEM object
*
* This function makes sure the backing pages are pinned in memory while the
* buffer is exported.
*
* Returns:
* 0 on success or a negative error code on failure.
*/
int drm_gem_shmem_pin(struct drm_gem_object *obj)
int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

WARN_ON(shmem->base.import_attach);

return drm_gem_shmem_get_pages(shmem);
Expand All @@ -244,15 +247,13 @@ EXPORT_SYMBOL(drm_gem_shmem_pin);

/**
* drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object
* @obj: GEM object
* @shmem: shmem GEM object
*
* This function removes the requirement that the backing pages are pinned in
* memory.
*/
void drm_gem_shmem_unpin(struct drm_gem_object *obj)
void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

WARN_ON(shmem->base.import_attach);

drm_gem_shmem_put_pages(shmem);
Expand Down Expand Up @@ -327,9 +328,8 @@ static int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, struct
* Returns:
* 0 on success or a negative error code on failure.
*/
int drm_gem_shmem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
int ret;

ret = mutex_lock_interruptible(&shmem->vmap_lock);
Expand Down Expand Up @@ -375,10 +375,8 @@ static void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
* This function hides the differences between dma-buf imported and natively
* allocated objects.
*/
void drm_gem_shmem_vunmap(struct drm_gem_object *obj, struct dma_buf_map *map)
void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct dma_buf_map *map)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

mutex_lock(&shmem->vmap_lock);
drm_gem_shmem_vunmap_locked(shmem, map);
mutex_unlock(&shmem->vmap_lock);
Expand Down Expand Up @@ -413,10 +411,8 @@ drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
/* Update madvise status, returns true if not purged, else
* false or -errno.
*/
int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv)
int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

mutex_lock(&shmem->pages_lock);

if (shmem->madv >= 0)
Expand All @@ -430,14 +426,14 @@ int drm_gem_shmem_madvise(struct drm_gem_object *obj, int madv)
}
EXPORT_SYMBOL(drm_gem_shmem_madvise);

void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_object *obj = &shmem->base;
struct drm_device *dev = obj->dev;
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

WARN_ON(!drm_gem_shmem_is_purgeable(shmem));

dma_unmap_sgtable(obj->dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
sg_free_table(shmem->sgt);
kfree(shmem->sgt);
shmem->sgt = NULL;
Expand All @@ -456,18 +452,15 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
*/
shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1);

invalidate_mapping_pages(file_inode(obj->filp)->i_mapping,
0, (loff_t)-1);
invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1);
}
EXPORT_SYMBOL(drm_gem_shmem_purge_locked);

bool drm_gem_shmem_purge(struct drm_gem_object *obj)
bool drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

if (!mutex_trylock(&shmem->pages_lock))
return false;
drm_gem_shmem_purge_locked(obj);
drm_gem_shmem_purge_locked(shmem);
mutex_unlock(&shmem->pages_lock);

return true;
Expand Down Expand Up @@ -575,7 +568,7 @@ static const struct vm_operations_struct drm_gem_shmem_vm_ops = {

/**
* drm_gem_shmem_mmap - Memory-map a shmem GEM object
* @obj: gem object
* @shmem: shmem GEM object
* @vma: VMA for the area to be mapped
*
* This function implements an augmented version of the GEM DRM file mmap
Expand All @@ -584,9 +577,9 @@ static const struct vm_operations_struct drm_gem_shmem_vm_ops = {
* Returns:
* 0 on success or a negative error code on failure.
*/
int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma)
{
struct drm_gem_shmem_object *shmem;
struct drm_gem_object *obj = &shmem->base;
int ret;

if (obj->import_attach) {
Expand All @@ -597,8 +590,6 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
return dma_buf_mmap(obj->dma_buf, vma, 0);
}

shmem = to_drm_gem_shmem_obj(obj);

ret = drm_gem_shmem_get_pages(shmem);
if (ret) {
drm_gem_vm_close(vma);
Expand All @@ -617,15 +608,13 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap);

/**
* drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs
* @shmem: shmem GEM object
* @p: DRM printer
* @indent: Tab indentation level
* @obj: GEM object
*/
void drm_gem_shmem_print_info(struct drm_printer *p, unsigned int indent,
const struct drm_gem_object *obj)
void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
struct drm_printer *p, unsigned int indent)
{
const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);

drm_printf_indent(p, indent, "pages_use_count=%u\n", shmem->pages_use_count);
drm_printf_indent(p, indent, "vmap_use_count=%u\n", shmem->vmap_use_count);
drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
Expand All @@ -635,7 +624,7 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
/**
* drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned
* pages for a shmem GEM object
* @obj: GEM object
* @shmem: shmem GEM object
*
* This function exports a scatter/gather table suitable for PRIME usage by
* calling the standard DMA mapping API.
Expand All @@ -646,9 +635,9 @@ EXPORT_SYMBOL(drm_gem_shmem_print_info);
* Returns:
* A pointer to the scatter/gather table of pinned pages or NULL on failure.
*/
struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_object *obj)
struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
struct drm_gem_object *obj = &shmem->base;

WARN_ON(shmem->base.import_attach);

Expand All @@ -659,7 +648,7 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
/**
* drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a
* scatter/gather table for a shmem GEM object.
* @obj: GEM object
* @shmem: shmem GEM object
*
* This function returns a scatter/gather table suitable for driver usage. If
* the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg
Expand All @@ -672,10 +661,10 @@ EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
* Returns:
* A pointer to the scatter/gather table of pinned pages or errno on failure.
*/
struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem)
{
struct drm_gem_object *obj = &shmem->base;
int ret;
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
struct sg_table *sgt;

if (shmem->sgt)
Expand All @@ -687,7 +676,7 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
if (ret)
return ERR_PTR(ret);

sgt = drm_gem_shmem_get_sg_table(&shmem->base);
sgt = drm_gem_shmem_get_sg_table(shmem);
if (IS_ERR(sgt)) {
ret = PTR_ERR(sgt);
goto err_put_pages;
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/lima/lima_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
if (err)
goto out;
} else {
struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(obj);
struct sg_table *sgt = drm_gem_shmem_get_pages_sgt(shmem);

if (IS_ERR(sgt)) {
err = PTR_ERR(sgt);
Expand All @@ -151,7 +151,7 @@ static void lima_gem_free_object(struct drm_gem_object *obj)
if (!list_empty(&bo->va))
dev_err(obj->dev->dev, "lima gem free bo still has va\n");

drm_gem_shmem_free_object(obj);
drm_gem_shmem_free(&bo->base);
}

static int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file)
Expand Down Expand Up @@ -179,7 +179,7 @@ static int lima_gem_pin(struct drm_gem_object *obj)
if (bo->heap_size)
return -EINVAL;

return drm_gem_shmem_pin(obj);
return drm_gem_shmem_pin(&bo->base);
}

static int lima_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
Expand All @@ -189,7 +189,7 @@ static int lima_gem_vmap(struct drm_gem_object *obj, struct dma_buf_map *map)
if (bo->heap_size)
return -EINVAL;

return drm_gem_shmem_vmap(obj, map);
return drm_gem_shmem_vmap(&bo->base, map);
}

static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
Expand All @@ -199,7 +199,7 @@ static int lima_gem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
if (bo->heap_size)
return -EINVAL;

return drm_gem_shmem_mmap(obj, vma);
return drm_gem_shmem_mmap(&bo->base, vma);
}

static const struct drm_gem_object_funcs lima_gem_funcs = {
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/lima/lima_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,15 +390,15 @@ static void lima_sched_build_error_task_list(struct lima_sched_task *task)
} else {
buffer_chunk->size = lima_bo_size(bo);

ret = drm_gem_shmem_vmap(&bo->base.base, &map);
ret = drm_gem_shmem_vmap(&bo->base, &map);
if (ret) {
kvfree(et);
goto out;
}

memcpy(buffer_chunk + 1, map.vaddr, buffer_chunk->size);

drm_gem_shmem_vunmap(&bo->base.base, &map);
drm_gem_shmem_vunmap(&bo->base, &map);
}

buffer_chunk = (void *)(buffer_chunk + 1) + buffer_chunk->size;
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/panfrost/panfrost_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
}
}

args->retained = drm_gem_shmem_madvise(gem_obj, args->madv);
args->retained = drm_gem_shmem_madvise(&bo->base, args->madv);

if (args->retained) {
if (args->madv == PANFROST_MADV_DONTNEED)
Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/panfrost/panfrost_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
kvfree(bo->sgts);
}

drm_gem_shmem_free_object(obj);
drm_gem_shmem_free(&bo->base);
}

struct panfrost_gem_mapping *
Expand Down Expand Up @@ -187,10 +187,12 @@ void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)

static int panfrost_gem_pin(struct drm_gem_object *obj)
{
if (to_panfrost_bo(obj)->is_heap)
struct panfrost_gem_object *bo = to_panfrost_bo(obj);

if (bo->is_heap)
return -EINVAL;

return drm_gem_shmem_pin(obj);
return drm_gem_shmem_pin(&bo->base);
}

static const struct drm_gem_object_funcs panfrost_gem_funcs = {
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/panfrost/panfrost_gem_shrinker.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static bool panfrost_gem_purge(struct drm_gem_object *obj)
goto unlock_mappings;

panfrost_gem_teardown_mappings_locked(bo);
drm_gem_shmem_purge_locked(obj);
drm_gem_shmem_purge_locked(&bo->base);
ret = true;

mutex_unlock(&shmem->pages_lock);
Expand Down
5 changes: 3 additions & 2 deletions drivers/gpu/drm/panfrost/panfrost_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ static int mmu_map_sg(struct panfrost_device *pfdev, struct panfrost_mmu *mmu,
int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
{
struct panfrost_gem_object *bo = mapping->obj;
struct drm_gem_object *obj = &bo->base.base;
struct drm_gem_shmem_object *shmem = &bo->base;
struct drm_gem_object *obj = &shmem->base;
struct panfrost_device *pfdev = to_panfrost_device(obj->dev);
struct sg_table *sgt;
int prot = IOMMU_READ | IOMMU_WRITE;
Expand All @@ -299,7 +300,7 @@ int panfrost_mmu_map(struct panfrost_gem_mapping *mapping)
if (bo->noexec)
prot |= IOMMU_NOEXEC;

sgt = drm_gem_shmem_get_pages_sgt(obj);
sgt = drm_gem_shmem_get_pages_sgt(shmem);
if (WARN_ON(IS_ERR(sgt)))
return PTR_ERR(sgt);

Expand Down

0 comments on commit ff0087d

Please sign in to comment.