/* SPDX-License-Identifier: GPL-2.0 */12#ifndef __DRM_GEM_SHMEM_HELPER_H__3#define __DRM_GEM_SHMEM_HELPER_H__45#include <linux/fs.h>6#include <linux/mm.h>7#include <linux/mutex.h>89#include <drm/drm_file.h>10#include <drm/drm_gem.h>11#include <drm/drm_ioctl.h>12#include <drm/drm_prime.h>1314struct dma_buf_attachment;15struct drm_mode_create_dumb;16struct drm_printer;17struct sg_table;1819/**20* struct drm_gem_shmem_object - GEM object backed by shmem21*/22struct drm_gem_shmem_object {23/**24* @base: Base GEM object25*/26struct drm_gem_object base;2728/**29* @pages: Page table30*/31struct page **pages;3233/**34* @pages_use_count:35*36* Reference count on the pages table.37* The pages are put when the count reaches zero.38*/39refcount_t pages_use_count;4041/**42* @pages_pin_count:43*44* Reference count on the pinned pages table.45*46* Pages are hard-pinned and reside in memory if count47* greater than zero. Otherwise, when count is zero, the pages are48* allowed to be evicted and purged by memory shrinker.49*/50refcount_t pages_pin_count;5152/**53* @madv: State for madvise54*55* 0 is active/inuse.56* A negative value is the object is purged.57* Positive values are driver specific and not used by the helpers.58*/59int madv;6061/**62* @madv_list: List entry for madvise tracking63*64* Typically used by drivers to track purgeable objects65*/66struct list_head madv_list;6768/**69* @sgt: Scatter/gather table for imported PRIME buffers70*/71struct sg_table *sgt;7273/**74* @vaddr: Kernel virtual address of the backing memory75*/76void *vaddr;7778/**79* @vmap_use_count:80*81* Reference count on the virtual address.82* The address are un-mapped when the count reaches zero.83*/84refcount_t vmap_use_count;8586/**87* @pages_mark_dirty_on_put:88*89* Mark pages as dirty when they are put.90*/91bool pages_mark_dirty_on_put : 1;9293/**94* @pages_mark_accessed_on_put:95*96* Mark pages as accessed when they are put.97*/98bool pages_mark_accessed_on_put : 1;99100/**101* @map_wc: map object write-combined (instead of using shmem defaults).102*/103bool map_wc : 1;104};105106#define to_drm_gem_shmem_obj(obj) \107container_of(obj, struct drm_gem_shmem_object, base)108109struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);110struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,111size_t size,112struct vfsmount *gemfs);113void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);114115void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);116int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);117void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);118int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,119struct iosys_map *map);120void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,121struct iosys_map *map);122int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma);123124int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem);125void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem);126127int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv);128129static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem)130{131return (shmem->madv > 0) &&132!refcount_read(&shmem->pages_pin_count) && shmem->sgt &&133!shmem->base.dma_buf && !drm_gem_is_imported(&shmem->base);134}135136void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem);137138struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem);139struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem);140141void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,142struct drm_printer *p, unsigned int indent);143144extern const struct vm_operations_struct drm_gem_shmem_vm_ops;145146/*147* GEM object functions148*/149150/**151* drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free()152* @obj: GEM object to free153*154* This function wraps drm_gem_shmem_free(). Drivers that employ the shmem helpers155* should use it as their &drm_gem_object_funcs.free handler.156*/157static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)158{159struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);160161drm_gem_shmem_free(shmem);162}163164/**165* drm_gem_shmem_object_print_info() - Print &drm_gem_shmem_object info for debugfs166* @p: DRM printer167* @indent: Tab indentation level168* @obj: GEM object169*170* This function wraps drm_gem_shmem_print_info(). Drivers that employ the shmem helpers should171* use this function as their &drm_gem_object_funcs.print_info handler.172*/173static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsigned int indent,174const struct drm_gem_object *obj)175{176const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);177178drm_gem_shmem_print_info(shmem, p, indent);179}180181/**182* drm_gem_shmem_object_pin - GEM object function for drm_gem_shmem_pin()183* @obj: GEM object184*185* This function wraps drm_gem_shmem_pin(). Drivers that employ the shmem helpers should186* use it as their &drm_gem_object_funcs.pin handler.187*/188static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)189{190struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);191192return drm_gem_shmem_pin_locked(shmem);193}194195/**196* drm_gem_shmem_object_unpin - GEM object function for drm_gem_shmem_unpin()197* @obj: GEM object198*199* This function wraps drm_gem_shmem_unpin(). Drivers that employ the shmem helpers should200* use it as their &drm_gem_object_funcs.unpin handler.201*/202static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)203{204struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);205206drm_gem_shmem_unpin_locked(shmem);207}208209/**210* drm_gem_shmem_object_get_sg_table - GEM object function for drm_gem_shmem_get_sg_table()211* @obj: GEM object212*213* This function wraps drm_gem_shmem_get_sg_table(). Drivers that employ the shmem helpers should214* use it as their &drm_gem_object_funcs.get_sg_table handler.215*216* Returns:217* A pointer to the scatter/gather table of pinned pages or error pointer on failure.218*/219static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj)220{221struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);222223return drm_gem_shmem_get_sg_table(shmem);224}225226/*227* drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap_locked()228* @obj: GEM object229* @map: Returns the kernel virtual address of the SHMEM GEM object's backing store.230*231* This function wraps drm_gem_shmem_vmap_locked(). Drivers that employ the shmem232* helpers should use it as their &drm_gem_object_funcs.vmap handler.233*234* Returns:235* 0 on success or a negative error code on failure.236*/237static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj,238struct iosys_map *map)239{240struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);241242return drm_gem_shmem_vmap_locked(shmem, map);243}244245/*246* drm_gem_shmem_object_vunmap - GEM object function for drm_gem_shmem_vunmap()247* @obj: GEM object248* @map: Kernel virtual address where the SHMEM GEM object was mapped249*250* This function wraps drm_gem_shmem_vunmap_locked(). Drivers that employ the shmem251* helpers should use it as their &drm_gem_object_funcs.vunmap handler.252*/253static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj,254struct iosys_map *map)255{256struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);257258drm_gem_shmem_vunmap_locked(shmem, map);259}260261/**262* drm_gem_shmem_object_mmap - GEM object function for drm_gem_shmem_mmap()263* @obj: GEM object264* @vma: VMA for the area to be mapped265*266* This function wraps drm_gem_shmem_mmap(). Drivers that employ the shmem helpers should267* use it as their &drm_gem_object_funcs.mmap handler.268*269* Returns:270* 0 on success or a negative error code on failure.271*/272static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)273{274struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);275276return drm_gem_shmem_mmap(shmem, vma);277}278279/*280* Driver ops281*/282283struct drm_gem_object *284drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,285struct dma_buf_attachment *attach,286struct sg_table *sgt);287int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,288struct drm_mode_create_dumb *args);289struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,290struct dma_buf *buf);291292/**293* DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations294*295* This macro provides a shortcut for setting the shmem GEM operations296* in the &drm_driver structure. Drivers that do not require an s/g table297* for imported buffers should use this.298*/299#define DRM_GEM_SHMEM_DRIVER_OPS \300.gem_prime_import = drm_gem_shmem_prime_import_no_map, \301.dumb_create = drm_gem_shmem_dumb_create302303#endif /* __DRM_GEM_SHMEM_HELPER_H__ */304305306