1/* SPDX-License-Identifier: GPL-2.0 */
2
3#ifndef __DRM_GEM_SHMEM_HELPER_H__
4#define __DRM_GEM_SHMEM_HELPER_H__
5
6#include <linux/fs.h>
7#include <linux/mm.h>
8#include <linux/mutex.h>
9
10#include <drm/drm_file.h>
11#include <drm/drm_gem.h>
12#include <drm/drm_ioctl.h>
13#include <drm/drm_prime.h>
14
15struct dma_buf_attachment;
16struct drm_mode_create_dumb;
17struct drm_printer;
18struct sg_table;
19
20/**
21 * struct drm_gem_shmem_object - GEM object backed by shmem
22 */
23struct drm_gem_shmem_object {
24 /**
25 * @base: Base GEM object
26 */
27 struct drm_gem_object base;
28
29 /**
30 * @pages: Page table
31 */
32 struct page **pages;
33
34 /**
35 * @pages_use_count:
36 *
37 * Reference count on the pages table.
38 * The pages are put when the count reaches zero.
39 */
40 refcount_t pages_use_count;
41
42 /**
43 * @pages_pin_count:
44 *
45 * Reference count on the pinned pages table.
46 *
47 * Pages are hard-pinned and reside in memory if count
48 * greater than zero. Otherwise, when count is zero, the pages are
49 * allowed to be evicted and purged by memory shrinker.
50 */
51 refcount_t pages_pin_count;
52
53 /**
54 * @madv: State for madvise
55 *
56 * 0 is active/inuse.
57 * A negative value is the object is purged.
58 * Positive values are driver specific and not used by the helpers.
59 */
60 int madv;
61
62 /**
63 * @madv_list: List entry for madvise tracking
64 *
65 * Typically used by drivers to track purgeable objects
66 */
67 struct list_head madv_list;
68
69 /**
70 * @sgt: Scatter/gather table for imported PRIME buffers
71 */
72 struct sg_table *sgt;
73
74 /**
75 * @vaddr: Kernel virtual address of the backing memory
76 */
77 void *vaddr;
78
79 /**
80 * @vmap_use_count:
81 *
82 * Reference count on the virtual address.
83 * The address are un-mapped when the count reaches zero.
84 */
85 refcount_t vmap_use_count;
86
87 /**
88 * @pages_mark_dirty_on_put:
89 *
90 * Mark pages as dirty when they are put.
91 */
92 bool pages_mark_dirty_on_put : 1;
93
94 /**
95 * @pages_mark_accessed_on_put:
96 *
97 * Mark pages as accessed when they are put.
98 */
99 bool pages_mark_accessed_on_put : 1;
100
101 /**
102 * @map_wc: map object write-combined (instead of using shmem defaults).
103 */
104 bool map_wc : 1;
105};
106
107#define to_drm_gem_shmem_obj(obj) \
108 container_of(obj, struct drm_gem_shmem_object, base)
109
110int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size);
111struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
112struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,
113 size_t size,
114 struct vfsmount *gemfs);
115void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem);
116void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
117
118void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem);
119int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem);
120void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem);
121int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,
122 struct iosys_map *map);
123void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
124 struct iosys_map *map);
125int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma);
126
127int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem);
128void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem);
129
130int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv);
131
132static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object *shmem)
133{
134 return (shmem->madv > 0) &&
135 !refcount_read(r: &shmem->pages_pin_count) && shmem->sgt &&
136 !shmem->base.dma_buf && !drm_gem_is_imported(obj: &shmem->base);
137}
138
139void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem);
140
141struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem);
142struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem);
143
144void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
145 struct drm_printer *p, unsigned int indent);
146
147extern const struct vm_operations_struct drm_gem_shmem_vm_ops;
148
149/*
150 * GEM object functions
151 */
152
153/**
154 * drm_gem_shmem_object_free - GEM object function for drm_gem_shmem_free()
155 * @obj: GEM object to free
156 *
157 * This function wraps drm_gem_shmem_free(). Drivers that employ the shmem helpers
158 * should use it as their &drm_gem_object_funcs.free handler.
159 */
160static inline void drm_gem_shmem_object_free(struct drm_gem_object *obj)
161{
162 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
163
164 drm_gem_shmem_free(shmem);
165}
166
167/**
168 * drm_gem_shmem_object_print_info() - Print &drm_gem_shmem_object info for debugfs
169 * @p: DRM printer
170 * @indent: Tab indentation level
171 * @obj: GEM object
172 *
173 * This function wraps drm_gem_shmem_print_info(). Drivers that employ the shmem helpers should
174 * use this function as their &drm_gem_object_funcs.print_info handler.
175 */
176static inline void drm_gem_shmem_object_print_info(struct drm_printer *p, unsigned int indent,
177 const struct drm_gem_object *obj)
178{
179 const struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
180
181 drm_gem_shmem_print_info(shmem, p, indent);
182}
183
184/**
185 * drm_gem_shmem_object_pin - GEM object function for drm_gem_shmem_pin()
186 * @obj: GEM object
187 *
188 * This function wraps drm_gem_shmem_pin(). Drivers that employ the shmem helpers should
189 * use it as their &drm_gem_object_funcs.pin handler.
190 */
191static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
192{
193 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
194
195 return drm_gem_shmem_pin_locked(shmem);
196}
197
198/**
199 * drm_gem_shmem_object_unpin - GEM object function for drm_gem_shmem_unpin()
200 * @obj: GEM object
201 *
202 * This function wraps drm_gem_shmem_unpin(). Drivers that employ the shmem helpers should
203 * use it as their &drm_gem_object_funcs.unpin handler.
204 */
205static inline void drm_gem_shmem_object_unpin(struct drm_gem_object *obj)
206{
207 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
208
209 drm_gem_shmem_unpin_locked(shmem);
210}
211
212/**
213 * drm_gem_shmem_object_get_sg_table - GEM object function for drm_gem_shmem_get_sg_table()
214 * @obj: GEM object
215 *
216 * This function wraps drm_gem_shmem_get_sg_table(). Drivers that employ the shmem helpers should
217 * use it as their &drm_gem_object_funcs.get_sg_table handler.
218 *
219 * Returns:
220 * A pointer to the scatter/gather table of pinned pages or error pointer on failure.
221 */
222static inline struct sg_table *drm_gem_shmem_object_get_sg_table(struct drm_gem_object *obj)
223{
224 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
225
226 return drm_gem_shmem_get_sg_table(shmem);
227}
228
229/*
230 * drm_gem_shmem_object_vmap - GEM object function for drm_gem_shmem_vmap_locked()
231 * @obj: GEM object
232 * @map: Returns the kernel virtual address of the SHMEM GEM object's backing store.
233 *
234 * This function wraps drm_gem_shmem_vmap_locked(). Drivers that employ the shmem
235 * helpers should use it as their &drm_gem_object_funcs.vmap handler.
236 *
237 * Returns:
238 * 0 on success or a negative error code on failure.
239 */
240static inline int drm_gem_shmem_object_vmap(struct drm_gem_object *obj,
241 struct iosys_map *map)
242{
243 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
244
245 return drm_gem_shmem_vmap_locked(shmem, map);
246}
247
248/*
249 * drm_gem_shmem_object_vunmap - GEM object function for drm_gem_shmem_vunmap()
250 * @obj: GEM object
251 * @map: Kernel virtual address where the SHMEM GEM object was mapped
252 *
253 * This function wraps drm_gem_shmem_vunmap_locked(). Drivers that employ the shmem
254 * helpers should use it as their &drm_gem_object_funcs.vunmap handler.
255 */
256static inline void drm_gem_shmem_object_vunmap(struct drm_gem_object *obj,
257 struct iosys_map *map)
258{
259 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
260
261 drm_gem_shmem_vunmap_locked(shmem, map);
262}
263
264/**
265 * drm_gem_shmem_object_mmap - GEM object function for drm_gem_shmem_mmap()
266 * @obj: GEM object
267 * @vma: VMA for the area to be mapped
268 *
269 * This function wraps drm_gem_shmem_mmap(). Drivers that employ the shmem helpers should
270 * use it as their &drm_gem_object_funcs.mmap handler.
271 *
272 * Returns:
273 * 0 on success or a negative error code on failure.
274 */
275static inline int drm_gem_shmem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
276{
277 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
278
279 return drm_gem_shmem_mmap(shmem, vma);
280}
281
282/*
283 * Driver ops
284 */
285
286struct drm_gem_object *
287drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
288 struct dma_buf_attachment *attach,
289 struct sg_table *sgt);
290int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
291 struct drm_mode_create_dumb *args);
292struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
293 struct dma_buf *buf);
294
295/**
296 * DRM_GEM_SHMEM_DRIVER_OPS - Default shmem GEM operations
297 *
298 * This macro provides a shortcut for setting the shmem GEM operations
299 * in the &drm_driver structure. Drivers that do not require an s/g table
300 * for imported buffers should use this.
301 */
302#define DRM_GEM_SHMEM_DRIVER_OPS \
303 .gem_prime_import = drm_gem_shmem_prime_import_no_map, \
304 .dumb_create = drm_gem_shmem_dumb_create
305
306#endif /* __DRM_GEM_SHMEM_HELPER_H__ */
307

source code of linux/include/drm/drm_gem_shmem_helper.h