1b9c02e10SThomas Hellström /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2f72c2db4SDanilo Krummrich
3f72c2db4SDanilo Krummrich #ifndef __DRM_GPUVM_H__
4f72c2db4SDanilo Krummrich #define __DRM_GPUVM_H__
5f72c2db4SDanilo Krummrich
6f72c2db4SDanilo Krummrich /*
7f72c2db4SDanilo Krummrich * Copyright (c) 2022 Red Hat.
8f72c2db4SDanilo Krummrich *
9f72c2db4SDanilo Krummrich * Permission is hereby granted, free of charge, to any person obtaining a
10f72c2db4SDanilo Krummrich * copy of this software and associated documentation files (the "Software"),
11f72c2db4SDanilo Krummrich * to deal in the Software without restriction, including without limitation
12f72c2db4SDanilo Krummrich * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13f72c2db4SDanilo Krummrich * and/or sell copies of the Software, and to permit persons to whom the
14f72c2db4SDanilo Krummrich * Software is furnished to do so, subject to the following conditions:
15f72c2db4SDanilo Krummrich *
16f72c2db4SDanilo Krummrich * The above copyright notice and this permission notice shall be included in
17f72c2db4SDanilo Krummrich * all copies or substantial portions of the Software.
18f72c2db4SDanilo Krummrich *
19f72c2db4SDanilo Krummrich * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20f72c2db4SDanilo Krummrich * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21f72c2db4SDanilo Krummrich * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22f72c2db4SDanilo Krummrich * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
23f72c2db4SDanilo Krummrich * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24f72c2db4SDanilo Krummrich * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25f72c2db4SDanilo Krummrich * OTHER DEALINGS IN THE SOFTWARE.
26f72c2db4SDanilo Krummrich */
27f72c2db4SDanilo Krummrich
2894bc2249SDanilo Krummrich #include <linux/dma-resv.h>
29f72c2db4SDanilo Krummrich #include <linux/list.h>
30f72c2db4SDanilo Krummrich #include <linux/rbtree.h>
31f72c2db4SDanilo Krummrich #include <linux/types.h>
32f72c2db4SDanilo Krummrich
33546ca4d3SDanilo Krummrich #include <drm/drm_device.h>
34f72c2db4SDanilo Krummrich #include <drm/drm_gem.h>
3550c1a36fSDanilo Krummrich #include <drm/drm_exec.h>
36f72c2db4SDanilo Krummrich
37f72c2db4SDanilo Krummrich struct drm_gpuvm;
3894bc2249SDanilo Krummrich struct drm_gpuvm_bo;
39f72c2db4SDanilo Krummrich struct drm_gpuvm_ops;
40f72c2db4SDanilo Krummrich
41f72c2db4SDanilo Krummrich /**
42f72c2db4SDanilo Krummrich * enum drm_gpuva_flags - flags for struct drm_gpuva
43f72c2db4SDanilo Krummrich */
44f72c2db4SDanilo Krummrich enum drm_gpuva_flags {
45f72c2db4SDanilo Krummrich /**
46f72c2db4SDanilo Krummrich * @DRM_GPUVA_INVALIDATED:
47f72c2db4SDanilo Krummrich *
48f72c2db4SDanilo Krummrich * Flag indicating that the &drm_gpuva's backing GEM is invalidated.
49f72c2db4SDanilo Krummrich */
50f72c2db4SDanilo Krummrich DRM_GPUVA_INVALIDATED = (1 << 0),
51f72c2db4SDanilo Krummrich
52f72c2db4SDanilo Krummrich /**
53f72c2db4SDanilo Krummrich * @DRM_GPUVA_SPARSE:
54f72c2db4SDanilo Krummrich *
55f72c2db4SDanilo Krummrich * Flag indicating that the &drm_gpuva is a sparse mapping.
56f72c2db4SDanilo Krummrich */
57f72c2db4SDanilo Krummrich DRM_GPUVA_SPARSE = (1 << 1),
58f72c2db4SDanilo Krummrich
59f72c2db4SDanilo Krummrich /**
60f72c2db4SDanilo Krummrich * @DRM_GPUVA_USERBITS: user defined bits
61f72c2db4SDanilo Krummrich */
62f72c2db4SDanilo Krummrich DRM_GPUVA_USERBITS = (1 << 2),
63f72c2db4SDanilo Krummrich };
64f72c2db4SDanilo Krummrich
65f72c2db4SDanilo Krummrich /**
66f72c2db4SDanilo Krummrich * struct drm_gpuva - structure to track a GPU VA mapping
67f72c2db4SDanilo Krummrich *
68f72c2db4SDanilo Krummrich * This structure represents a GPU VA mapping and is associated with a
69f72c2db4SDanilo Krummrich * &drm_gpuvm.
70f72c2db4SDanilo Krummrich *
71f72c2db4SDanilo Krummrich * Typically, this structure is embedded in bigger driver structures.
72f72c2db4SDanilo Krummrich */
73f72c2db4SDanilo Krummrich struct drm_gpuva {
74f72c2db4SDanilo Krummrich /**
75f72c2db4SDanilo Krummrich * @vm: the &drm_gpuvm this object is associated with
76f72c2db4SDanilo Krummrich */
77f72c2db4SDanilo Krummrich struct drm_gpuvm *vm;
78f72c2db4SDanilo Krummrich
79f72c2db4SDanilo Krummrich /**
8094bc2249SDanilo Krummrich * @vm_bo: the &drm_gpuvm_bo abstraction for the mapped
8194bc2249SDanilo Krummrich * &drm_gem_object
8294bc2249SDanilo Krummrich */
8394bc2249SDanilo Krummrich struct drm_gpuvm_bo *vm_bo;
8494bc2249SDanilo Krummrich
8594bc2249SDanilo Krummrich /**
86f72c2db4SDanilo Krummrich * @flags: the &drm_gpuva_flags for this mapping
87f72c2db4SDanilo Krummrich */
88f72c2db4SDanilo Krummrich enum drm_gpuva_flags flags;
89f72c2db4SDanilo Krummrich
90f72c2db4SDanilo Krummrich /**
91f72c2db4SDanilo Krummrich * @va: structure containing the address and range of the &drm_gpuva
92f72c2db4SDanilo Krummrich */
93f72c2db4SDanilo Krummrich struct {
94f72c2db4SDanilo Krummrich /**
95200a6b3aSRandy Dunlap * @va.addr: the start address
96f72c2db4SDanilo Krummrich */
97f72c2db4SDanilo Krummrich u64 addr;
98f72c2db4SDanilo Krummrich
99f72c2db4SDanilo Krummrich /*
100f72c2db4SDanilo Krummrich * @range: the range
101f72c2db4SDanilo Krummrich */
102f72c2db4SDanilo Krummrich u64 range;
103f72c2db4SDanilo Krummrich } va;
104f72c2db4SDanilo Krummrich
105f72c2db4SDanilo Krummrich /**
106f72c2db4SDanilo Krummrich * @gem: structure containing the &drm_gem_object and it's offset
107f72c2db4SDanilo Krummrich */
108f72c2db4SDanilo Krummrich struct {
109f72c2db4SDanilo Krummrich /**
110200a6b3aSRandy Dunlap * @gem.offset: the offset within the &drm_gem_object
111f72c2db4SDanilo Krummrich */
112f72c2db4SDanilo Krummrich u64 offset;
113f72c2db4SDanilo Krummrich
114f72c2db4SDanilo Krummrich /**
115200a6b3aSRandy Dunlap * @gem.obj: the mapped &drm_gem_object
116f72c2db4SDanilo Krummrich */
117f72c2db4SDanilo Krummrich struct drm_gem_object *obj;
118f72c2db4SDanilo Krummrich
119f72c2db4SDanilo Krummrich /**
120200a6b3aSRandy Dunlap * @gem.entry: the &list_head to attach this object to a &drm_gpuvm_bo
121f72c2db4SDanilo Krummrich */
122f72c2db4SDanilo Krummrich struct list_head entry;
123f72c2db4SDanilo Krummrich } gem;
124f72c2db4SDanilo Krummrich
125f72c2db4SDanilo Krummrich /**
126f72c2db4SDanilo Krummrich * @rb: structure containing data to store &drm_gpuvas in a rb-tree
127f72c2db4SDanilo Krummrich */
128f72c2db4SDanilo Krummrich struct {
129f72c2db4SDanilo Krummrich /**
130200a6b3aSRandy Dunlap * @rb.node: the rb-tree node
131f72c2db4SDanilo Krummrich */
132f72c2db4SDanilo Krummrich struct rb_node node;
133f72c2db4SDanilo Krummrich
134f72c2db4SDanilo Krummrich /**
135200a6b3aSRandy Dunlap * @rb.entry: The &list_head to additionally connect &drm_gpuvas
136f72c2db4SDanilo Krummrich * in the same order they appear in the interval tree. This is
137f72c2db4SDanilo Krummrich * useful to keep iterating &drm_gpuvas from a start node found
138f72c2db4SDanilo Krummrich * through the rb-tree while doing modifications on the rb-tree
139f72c2db4SDanilo Krummrich * itself.
140f72c2db4SDanilo Krummrich */
141f72c2db4SDanilo Krummrich struct list_head entry;
142f72c2db4SDanilo Krummrich
143f72c2db4SDanilo Krummrich /**
144200a6b3aSRandy Dunlap * @rb.__subtree_last: needed by the interval tree, holding last-in-subtree
145f72c2db4SDanilo Krummrich */
146f72c2db4SDanilo Krummrich u64 __subtree_last;
147f72c2db4SDanilo Krummrich } rb;
148f72c2db4SDanilo Krummrich };
149f72c2db4SDanilo Krummrich
150f72c2db4SDanilo Krummrich int drm_gpuva_insert(struct drm_gpuvm *gpuvm, struct drm_gpuva *va);
151f72c2db4SDanilo Krummrich void drm_gpuva_remove(struct drm_gpuva *va);
152f72c2db4SDanilo Krummrich
15394bc2249SDanilo Krummrich void drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo);
154f72c2db4SDanilo Krummrich void drm_gpuva_unlink(struct drm_gpuva *va);
155f72c2db4SDanilo Krummrich
156f72c2db4SDanilo Krummrich struct drm_gpuva *drm_gpuva_find(struct drm_gpuvm *gpuvm,
157f72c2db4SDanilo Krummrich u64 addr, u64 range);
158f72c2db4SDanilo Krummrich struct drm_gpuva *drm_gpuva_find_first(struct drm_gpuvm *gpuvm,
159f72c2db4SDanilo Krummrich u64 addr, u64 range);
160f72c2db4SDanilo Krummrich struct drm_gpuva *drm_gpuva_find_prev(struct drm_gpuvm *gpuvm, u64 start);
161f72c2db4SDanilo Krummrich struct drm_gpuva *drm_gpuva_find_next(struct drm_gpuvm *gpuvm, u64 end);
162f72c2db4SDanilo Krummrich
drm_gpuva_init(struct drm_gpuva * va,u64 addr,u64 range,struct drm_gem_object * obj,u64 offset)163f72c2db4SDanilo Krummrich static inline void drm_gpuva_init(struct drm_gpuva *va, u64 addr, u64 range,
164f72c2db4SDanilo Krummrich struct drm_gem_object *obj, u64 offset)
165f72c2db4SDanilo Krummrich {
166f72c2db4SDanilo Krummrich va->va.addr = addr;
167f72c2db4SDanilo Krummrich va->va.range = range;
168f72c2db4SDanilo Krummrich va->gem.obj = obj;
169f72c2db4SDanilo Krummrich va->gem.offset = offset;
170f72c2db4SDanilo Krummrich }
171f72c2db4SDanilo Krummrich
172f72c2db4SDanilo Krummrich /**
173f72c2db4SDanilo Krummrich * drm_gpuva_invalidate() - sets whether the backing GEM of this &drm_gpuva is
174f72c2db4SDanilo Krummrich * invalidated
175f72c2db4SDanilo Krummrich * @va: the &drm_gpuva to set the invalidate flag for
176f72c2db4SDanilo Krummrich * @invalidate: indicates whether the &drm_gpuva is invalidated
177f72c2db4SDanilo Krummrich */
drm_gpuva_invalidate(struct drm_gpuva * va,bool invalidate)178f72c2db4SDanilo Krummrich static inline void drm_gpuva_invalidate(struct drm_gpuva *va, bool invalidate)
179f72c2db4SDanilo Krummrich {
180f72c2db4SDanilo Krummrich if (invalidate)
181f72c2db4SDanilo Krummrich va->flags |= DRM_GPUVA_INVALIDATED;
182f72c2db4SDanilo Krummrich else
183f72c2db4SDanilo Krummrich va->flags &= ~DRM_GPUVA_INVALIDATED;
184f72c2db4SDanilo Krummrich }
185f72c2db4SDanilo Krummrich
186f72c2db4SDanilo Krummrich /**
187f72c2db4SDanilo Krummrich * drm_gpuva_invalidated() - indicates whether the backing BO of this &drm_gpuva
188f72c2db4SDanilo Krummrich * is invalidated
189f72c2db4SDanilo Krummrich * @va: the &drm_gpuva to check
190200a6b3aSRandy Dunlap *
191200a6b3aSRandy Dunlap * Returns: %true if the GPU VA is invalidated, %false otherwise
192f72c2db4SDanilo Krummrich */
drm_gpuva_invalidated(struct drm_gpuva * va)193f72c2db4SDanilo Krummrich static inline bool drm_gpuva_invalidated(struct drm_gpuva *va)
194f72c2db4SDanilo Krummrich {
195f72c2db4SDanilo Krummrich return va->flags & DRM_GPUVA_INVALIDATED;
196f72c2db4SDanilo Krummrich }
197f72c2db4SDanilo Krummrich
198f72c2db4SDanilo Krummrich /**
199809ef191SDanilo Krummrich * enum drm_gpuvm_flags - flags for struct drm_gpuvm
200809ef191SDanilo Krummrich */
201809ef191SDanilo Krummrich enum drm_gpuvm_flags {
202809ef191SDanilo Krummrich /**
20394bc2249SDanilo Krummrich * @DRM_GPUVM_RESV_PROTECTED: GPUVM is protected externally by the
20494bc2249SDanilo Krummrich * GPUVM's &dma_resv lock
20594bc2249SDanilo Krummrich */
20694bc2249SDanilo Krummrich DRM_GPUVM_RESV_PROTECTED = BIT(0),
20794bc2249SDanilo Krummrich
20894bc2249SDanilo Krummrich /**
209809ef191SDanilo Krummrich * @DRM_GPUVM_USERBITS: user defined bits
210809ef191SDanilo Krummrich */
21194bc2249SDanilo Krummrich DRM_GPUVM_USERBITS = BIT(1),
212809ef191SDanilo Krummrich };
213809ef191SDanilo Krummrich
214809ef191SDanilo Krummrich /**
215f72c2db4SDanilo Krummrich * struct drm_gpuvm - DRM GPU VA Manager
216f72c2db4SDanilo Krummrich *
217f72c2db4SDanilo Krummrich * The DRM GPU VA Manager keeps track of a GPU's virtual address space by using
218f72c2db4SDanilo Krummrich * &maple_tree structures. Typically, this structure is embedded in bigger
219f72c2db4SDanilo Krummrich * driver structures.
220f72c2db4SDanilo Krummrich *
221f72c2db4SDanilo Krummrich * Drivers can pass addresses and ranges in an arbitrary unit, e.g. bytes or
222f72c2db4SDanilo Krummrich * pages.
223f72c2db4SDanilo Krummrich *
224f72c2db4SDanilo Krummrich * There should be one manager instance per GPU virtual address space.
225f72c2db4SDanilo Krummrich */
226f72c2db4SDanilo Krummrich struct drm_gpuvm {
227f72c2db4SDanilo Krummrich /**
228f72c2db4SDanilo Krummrich * @name: the name of the DRM GPU VA space
229f72c2db4SDanilo Krummrich */
230f72c2db4SDanilo Krummrich const char *name;
231f72c2db4SDanilo Krummrich
232f72c2db4SDanilo Krummrich /**
233809ef191SDanilo Krummrich * @flags: the &drm_gpuvm_flags of this GPUVM
234809ef191SDanilo Krummrich */
235809ef191SDanilo Krummrich enum drm_gpuvm_flags flags;
236809ef191SDanilo Krummrich
237809ef191SDanilo Krummrich /**
238546ca4d3SDanilo Krummrich * @drm: the &drm_device this VM lives in
239546ca4d3SDanilo Krummrich */
240546ca4d3SDanilo Krummrich struct drm_device *drm;
241546ca4d3SDanilo Krummrich
242546ca4d3SDanilo Krummrich /**
243f72c2db4SDanilo Krummrich * @mm_start: start of the VA space
244f72c2db4SDanilo Krummrich */
245f72c2db4SDanilo Krummrich u64 mm_start;
246f72c2db4SDanilo Krummrich
247f72c2db4SDanilo Krummrich /**
248f72c2db4SDanilo Krummrich * @mm_range: length of the VA space
249f72c2db4SDanilo Krummrich */
250f72c2db4SDanilo Krummrich u64 mm_range;
251f72c2db4SDanilo Krummrich
252f72c2db4SDanilo Krummrich /**
253f72c2db4SDanilo Krummrich * @rb: structures to track &drm_gpuva entries
254f72c2db4SDanilo Krummrich */
255f72c2db4SDanilo Krummrich struct {
256f72c2db4SDanilo Krummrich /**
257200a6b3aSRandy Dunlap * @rb.tree: the rb-tree to track GPU VA mappings
258f72c2db4SDanilo Krummrich */
259f72c2db4SDanilo Krummrich struct rb_root_cached tree;
260f72c2db4SDanilo Krummrich
261f72c2db4SDanilo Krummrich /**
262200a6b3aSRandy Dunlap * @rb.list: the &list_head to track GPU VA mappings
263f72c2db4SDanilo Krummrich */
264f72c2db4SDanilo Krummrich struct list_head list;
265f72c2db4SDanilo Krummrich } rb;
266f72c2db4SDanilo Krummrich
267f72c2db4SDanilo Krummrich /**
2688af72338SDanilo Krummrich * @kref: reference count of this object
2698af72338SDanilo Krummrich */
2708af72338SDanilo Krummrich struct kref kref;
2718af72338SDanilo Krummrich
2728af72338SDanilo Krummrich /**
273f72c2db4SDanilo Krummrich * @kernel_alloc_node:
274f72c2db4SDanilo Krummrich *
275f72c2db4SDanilo Krummrich * &drm_gpuva representing the address space cutout reserved for
276f72c2db4SDanilo Krummrich * the kernel
277f72c2db4SDanilo Krummrich */
278f72c2db4SDanilo Krummrich struct drm_gpuva kernel_alloc_node;
279f72c2db4SDanilo Krummrich
280f72c2db4SDanilo Krummrich /**
281f72c2db4SDanilo Krummrich * @ops: &drm_gpuvm_ops providing the split/merge steps to drivers
282f72c2db4SDanilo Krummrich */
283f72c2db4SDanilo Krummrich const struct drm_gpuvm_ops *ops;
284bbe84580SDanilo Krummrich
285bbe84580SDanilo Krummrich /**
286bbe84580SDanilo Krummrich * @r_obj: Resv GEM object; representing the GPUVM's common &dma_resv.
287bbe84580SDanilo Krummrich */
288bbe84580SDanilo Krummrich struct drm_gem_object *r_obj;
28950c1a36fSDanilo Krummrich
29050c1a36fSDanilo Krummrich /**
29150c1a36fSDanilo Krummrich * @extobj: structure holding the extobj list
29250c1a36fSDanilo Krummrich */
29350c1a36fSDanilo Krummrich struct {
29450c1a36fSDanilo Krummrich /**
295200a6b3aSRandy Dunlap * @extobj.list: &list_head storing &drm_gpuvm_bos serving as
29650c1a36fSDanilo Krummrich * external object
29750c1a36fSDanilo Krummrich */
29850c1a36fSDanilo Krummrich struct list_head list;
29950c1a36fSDanilo Krummrich
30050c1a36fSDanilo Krummrich /**
301200a6b3aSRandy Dunlap * @extobj.local_list: pointer to the local list temporarily
302200a6b3aSRandy Dunlap * storing entries from the external object list
30350c1a36fSDanilo Krummrich */
30450c1a36fSDanilo Krummrich struct list_head *local_list;
30550c1a36fSDanilo Krummrich
30650c1a36fSDanilo Krummrich /**
307200a6b3aSRandy Dunlap * @extobj.lock: spinlock to protect the extobj list
30850c1a36fSDanilo Krummrich */
30950c1a36fSDanilo Krummrich spinlock_t lock;
31050c1a36fSDanilo Krummrich } extobj;
31150c1a36fSDanilo Krummrich
31250c1a36fSDanilo Krummrich /**
31350c1a36fSDanilo Krummrich * @evict: structure holding the evict list and evict list lock
31450c1a36fSDanilo Krummrich */
31550c1a36fSDanilo Krummrich struct {
31650c1a36fSDanilo Krummrich /**
317200a6b3aSRandy Dunlap * @evict.list: &list_head storing &drm_gpuvm_bos currently
318200a6b3aSRandy Dunlap * being evicted
31950c1a36fSDanilo Krummrich */
32050c1a36fSDanilo Krummrich struct list_head list;
32150c1a36fSDanilo Krummrich
32250c1a36fSDanilo Krummrich /**
323200a6b3aSRandy Dunlap * @evict.local_list: pointer to the local list temporarily
324200a6b3aSRandy Dunlap * storing entries from the evicted object list
32550c1a36fSDanilo Krummrich */
32650c1a36fSDanilo Krummrich struct list_head *local_list;
32750c1a36fSDanilo Krummrich
32850c1a36fSDanilo Krummrich /**
329200a6b3aSRandy Dunlap * @evict.lock: spinlock to protect the evict list
33050c1a36fSDanilo Krummrich */
33150c1a36fSDanilo Krummrich spinlock_t lock;
33250c1a36fSDanilo Krummrich } evict;
333f72c2db4SDanilo Krummrich };
334f72c2db4SDanilo Krummrich
335f72c2db4SDanilo Krummrich void drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
336809ef191SDanilo Krummrich enum drm_gpuvm_flags flags,
337546ca4d3SDanilo Krummrich struct drm_device *drm,
338bbe84580SDanilo Krummrich struct drm_gem_object *r_obj,
339f72c2db4SDanilo Krummrich u64 start_offset, u64 range,
340f72c2db4SDanilo Krummrich u64 reserve_offset, u64 reserve_range,
341f72c2db4SDanilo Krummrich const struct drm_gpuvm_ops *ops);
3428af72338SDanilo Krummrich
3438af72338SDanilo Krummrich /**
3448af72338SDanilo Krummrich * drm_gpuvm_get() - acquire a struct drm_gpuvm reference
3458af72338SDanilo Krummrich * @gpuvm: the &drm_gpuvm to acquire the reference of
3468af72338SDanilo Krummrich *
3478af72338SDanilo Krummrich * This function acquires an additional reference to @gpuvm. It is illegal to
3488af72338SDanilo Krummrich * call this without already holding a reference. No locks required.
349200a6b3aSRandy Dunlap *
350200a6b3aSRandy Dunlap * Returns: the &struct drm_gpuvm pointer
3518af72338SDanilo Krummrich */
3528af72338SDanilo Krummrich static inline struct drm_gpuvm *
drm_gpuvm_get(struct drm_gpuvm * gpuvm)3538af72338SDanilo Krummrich drm_gpuvm_get(struct drm_gpuvm *gpuvm)
3548af72338SDanilo Krummrich {
3558af72338SDanilo Krummrich kref_get(&gpuvm->kref);
3568af72338SDanilo Krummrich
3578af72338SDanilo Krummrich return gpuvm;
3588af72338SDanilo Krummrich }
3598af72338SDanilo Krummrich
3608af72338SDanilo Krummrich void drm_gpuvm_put(struct drm_gpuvm *gpuvm);
361f72c2db4SDanilo Krummrich
3629297cfc9SDanilo Krummrich bool drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm, u64 addr, u64 range);
363f72c2db4SDanilo Krummrich bool drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range);
364f72c2db4SDanilo Krummrich
365bbe84580SDanilo Krummrich struct drm_gem_object *
366bbe84580SDanilo Krummrich drm_gpuvm_resv_object_alloc(struct drm_device *drm);
367bbe84580SDanilo Krummrich
368bbe84580SDanilo Krummrich /**
36994bc2249SDanilo Krummrich * drm_gpuvm_resv_protected() - indicates whether &DRM_GPUVM_RESV_PROTECTED is
37094bc2249SDanilo Krummrich * set
37194bc2249SDanilo Krummrich * @gpuvm: the &drm_gpuvm
37294bc2249SDanilo Krummrich *
37394bc2249SDanilo Krummrich * Returns: true if &DRM_GPUVM_RESV_PROTECTED is set, false otherwise.
37494bc2249SDanilo Krummrich */
37594bc2249SDanilo Krummrich static inline bool
drm_gpuvm_resv_protected(struct drm_gpuvm * gpuvm)37694bc2249SDanilo Krummrich drm_gpuvm_resv_protected(struct drm_gpuvm *gpuvm)
37794bc2249SDanilo Krummrich {
37894bc2249SDanilo Krummrich return gpuvm->flags & DRM_GPUVM_RESV_PROTECTED;
37994bc2249SDanilo Krummrich }
38094bc2249SDanilo Krummrich
38194bc2249SDanilo Krummrich /**
382bbe84580SDanilo Krummrich * drm_gpuvm_resv() - returns the &drm_gpuvm's &dma_resv
383bbe84580SDanilo Krummrich * @gpuvm__: the &drm_gpuvm
384bbe84580SDanilo Krummrich *
385bbe84580SDanilo Krummrich * Returns: a pointer to the &drm_gpuvm's shared &dma_resv
386bbe84580SDanilo Krummrich */
387bbe84580SDanilo Krummrich #define drm_gpuvm_resv(gpuvm__) ((gpuvm__)->r_obj->resv)
388bbe84580SDanilo Krummrich
389bbe84580SDanilo Krummrich /**
390bbe84580SDanilo Krummrich * drm_gpuvm_resv_obj() - returns the &drm_gem_object holding the &drm_gpuvm's
391bbe84580SDanilo Krummrich * &dma_resv
392bbe84580SDanilo Krummrich * @gpuvm__: the &drm_gpuvm
393bbe84580SDanilo Krummrich *
394bbe84580SDanilo Krummrich * Returns: a pointer to the &drm_gem_object holding the &drm_gpuvm's shared
395bbe84580SDanilo Krummrich * &dma_resv
396bbe84580SDanilo Krummrich */
397bbe84580SDanilo Krummrich #define drm_gpuvm_resv_obj(gpuvm__) ((gpuvm__)->r_obj)
398bbe84580SDanilo Krummrich
399bbe84580SDanilo Krummrich #define drm_gpuvm_resv_held(gpuvm__) \
400bbe84580SDanilo Krummrich dma_resv_held(drm_gpuvm_resv(gpuvm__))
401bbe84580SDanilo Krummrich
402bbe84580SDanilo Krummrich #define drm_gpuvm_resv_assert_held(gpuvm__) \
403bbe84580SDanilo Krummrich dma_resv_assert_held(drm_gpuvm_resv(gpuvm__))
404bbe84580SDanilo Krummrich
40594bc2249SDanilo Krummrich #define drm_gpuvm_resv_held(gpuvm__) \
40694bc2249SDanilo Krummrich dma_resv_held(drm_gpuvm_resv(gpuvm__))
40794bc2249SDanilo Krummrich
40894bc2249SDanilo Krummrich #define drm_gpuvm_resv_assert_held(gpuvm__) \
40994bc2249SDanilo Krummrich dma_resv_assert_held(drm_gpuvm_resv(gpuvm__))
41094bc2249SDanilo Krummrich
41150c1a36fSDanilo Krummrich /**
41250c1a36fSDanilo Krummrich * drm_gpuvm_is_extobj() - indicates whether the given &drm_gem_object is an
41350c1a36fSDanilo Krummrich * external object
41450c1a36fSDanilo Krummrich * @gpuvm: the &drm_gpuvm to check
41550c1a36fSDanilo Krummrich * @obj: the &drm_gem_object to check
41650c1a36fSDanilo Krummrich *
41750c1a36fSDanilo Krummrich * Returns: true if the &drm_gem_object &dma_resv differs from the
41850c1a36fSDanilo Krummrich * &drm_gpuvms &dma_resv, false otherwise
41950c1a36fSDanilo Krummrich */
42050c1a36fSDanilo Krummrich static inline bool
drm_gpuvm_is_extobj(struct drm_gpuvm * gpuvm,struct drm_gem_object * obj)42150c1a36fSDanilo Krummrich drm_gpuvm_is_extobj(struct drm_gpuvm *gpuvm,
42250c1a36fSDanilo Krummrich struct drm_gem_object *obj)
42350c1a36fSDanilo Krummrich {
42450c1a36fSDanilo Krummrich return obj && obj->resv != drm_gpuvm_resv(gpuvm);
42550c1a36fSDanilo Krummrich }
42650c1a36fSDanilo Krummrich
427f72c2db4SDanilo Krummrich static inline struct drm_gpuva *
__drm_gpuva_next(struct drm_gpuva * va)428f72c2db4SDanilo Krummrich __drm_gpuva_next(struct drm_gpuva *va)
429f72c2db4SDanilo Krummrich {
430f72c2db4SDanilo Krummrich if (va && !list_is_last(&va->rb.entry, &va->vm->rb.list))
431f72c2db4SDanilo Krummrich return list_next_entry(va, rb.entry);
432f72c2db4SDanilo Krummrich
433f72c2db4SDanilo Krummrich return NULL;
434f72c2db4SDanilo Krummrich }
435f72c2db4SDanilo Krummrich
436f72c2db4SDanilo Krummrich /**
437f72c2db4SDanilo Krummrich * drm_gpuvm_for_each_va_range() - iterate over a range of &drm_gpuvas
438f72c2db4SDanilo Krummrich * @va__: &drm_gpuva structure to assign to in each iteration step
439f72c2db4SDanilo Krummrich * @gpuvm__: &drm_gpuvm to walk over
440f72c2db4SDanilo Krummrich * @start__: starting offset, the first gpuva will overlap this
441f72c2db4SDanilo Krummrich * @end__: ending offset, the last gpuva will start before this (but may
442f72c2db4SDanilo Krummrich * overlap)
443f72c2db4SDanilo Krummrich *
444f72c2db4SDanilo Krummrich * This iterator walks over all &drm_gpuvas in the &drm_gpuvm that lie
445f72c2db4SDanilo Krummrich * between @start__ and @end__. It is implemented similarly to list_for_each(),
446f72c2db4SDanilo Krummrich * but is using the &drm_gpuvm's internal interval tree to accelerate
447f72c2db4SDanilo Krummrich * the search for the starting &drm_gpuva, and hence isn't safe against removal
448f72c2db4SDanilo Krummrich * of elements. It assumes that @end__ is within (or is the upper limit of) the
449f72c2db4SDanilo Krummrich * &drm_gpuvm. This iterator does not skip over the &drm_gpuvm's
450f72c2db4SDanilo Krummrich * @kernel_alloc_node.
451f72c2db4SDanilo Krummrich */
452f72c2db4SDanilo Krummrich #define drm_gpuvm_for_each_va_range(va__, gpuvm__, start__, end__) \
453f72c2db4SDanilo Krummrich for (va__ = drm_gpuva_find_first((gpuvm__), (start__), (end__) - (start__)); \
454f72c2db4SDanilo Krummrich va__ && (va__->va.addr < (end__)); \
455f72c2db4SDanilo Krummrich va__ = __drm_gpuva_next(va__))
456f72c2db4SDanilo Krummrich
457f72c2db4SDanilo Krummrich /**
458f72c2db4SDanilo Krummrich * drm_gpuvm_for_each_va_range_safe() - safely iterate over a range of
459f72c2db4SDanilo Krummrich * &drm_gpuvas
460f72c2db4SDanilo Krummrich * @va__: &drm_gpuva to assign to in each iteration step
461f72c2db4SDanilo Krummrich * @next__: another &drm_gpuva to use as temporary storage
462f72c2db4SDanilo Krummrich * @gpuvm__: &drm_gpuvm to walk over
463f72c2db4SDanilo Krummrich * @start__: starting offset, the first gpuva will overlap this
464f72c2db4SDanilo Krummrich * @end__: ending offset, the last gpuva will start before this (but may
465f72c2db4SDanilo Krummrich * overlap)
466f72c2db4SDanilo Krummrich *
467f72c2db4SDanilo Krummrich * This iterator walks over all &drm_gpuvas in the &drm_gpuvm that lie
468f72c2db4SDanilo Krummrich * between @start__ and @end__. It is implemented similarly to
469f72c2db4SDanilo Krummrich * list_for_each_safe(), but is using the &drm_gpuvm's internal interval
470f72c2db4SDanilo Krummrich * tree to accelerate the search for the starting &drm_gpuva, and hence is safe
471f72c2db4SDanilo Krummrich * against removal of elements. It assumes that @end__ is within (or is the
472f72c2db4SDanilo Krummrich * upper limit of) the &drm_gpuvm. This iterator does not skip over the
473f72c2db4SDanilo Krummrich * &drm_gpuvm's @kernel_alloc_node.
474f72c2db4SDanilo Krummrich */
475f72c2db4SDanilo Krummrich #define drm_gpuvm_for_each_va_range_safe(va__, next__, gpuvm__, start__, end__) \
476f72c2db4SDanilo Krummrich for (va__ = drm_gpuva_find_first((gpuvm__), (start__), (end__) - (start__)), \
477f72c2db4SDanilo Krummrich next__ = __drm_gpuva_next(va__); \
478f72c2db4SDanilo Krummrich va__ && (va__->va.addr < (end__)); \
479f72c2db4SDanilo Krummrich va__ = next__, next__ = __drm_gpuva_next(va__))
480f72c2db4SDanilo Krummrich
481f72c2db4SDanilo Krummrich /**
482f72c2db4SDanilo Krummrich * drm_gpuvm_for_each_va() - iterate over all &drm_gpuvas
483f72c2db4SDanilo Krummrich * @va__: &drm_gpuva to assign to in each iteration step
484f72c2db4SDanilo Krummrich * @gpuvm__: &drm_gpuvm to walk over
485f72c2db4SDanilo Krummrich *
486f72c2db4SDanilo Krummrich * This iterator walks over all &drm_gpuva structures associated with the given
487f72c2db4SDanilo Krummrich * &drm_gpuvm.
488f72c2db4SDanilo Krummrich */
489f72c2db4SDanilo Krummrich #define drm_gpuvm_for_each_va(va__, gpuvm__) \
490f72c2db4SDanilo Krummrich list_for_each_entry(va__, &(gpuvm__)->rb.list, rb.entry)
491f72c2db4SDanilo Krummrich
492f72c2db4SDanilo Krummrich /**
493f72c2db4SDanilo Krummrich * drm_gpuvm_for_each_va_safe() - safely iterate over all &drm_gpuvas
494f72c2db4SDanilo Krummrich * @va__: &drm_gpuva to assign to in each iteration step
495f72c2db4SDanilo Krummrich * @next__: another &drm_gpuva to use as temporary storage
496f72c2db4SDanilo Krummrich * @gpuvm__: &drm_gpuvm to walk over
497f72c2db4SDanilo Krummrich *
498f72c2db4SDanilo Krummrich * This iterator walks over all &drm_gpuva structures associated with the given
499f72c2db4SDanilo Krummrich * &drm_gpuvm. It is implemented with list_for_each_entry_safe(), and
500f72c2db4SDanilo Krummrich * hence safe against the removal of elements.
501f72c2db4SDanilo Krummrich */
502f72c2db4SDanilo Krummrich #define drm_gpuvm_for_each_va_safe(va__, next__, gpuvm__) \
503f72c2db4SDanilo Krummrich list_for_each_entry_safe(va__, next__, &(gpuvm__)->rb.list, rb.entry)
504f72c2db4SDanilo Krummrich
505f72c2db4SDanilo Krummrich /**
50650c1a36fSDanilo Krummrich * struct drm_gpuvm_exec - &drm_gpuvm abstraction of &drm_exec
50750c1a36fSDanilo Krummrich *
50850c1a36fSDanilo Krummrich * This structure should be created on the stack as &drm_exec should be.
50950c1a36fSDanilo Krummrich *
51050c1a36fSDanilo Krummrich * Optionally, @extra can be set in order to lock additional &drm_gem_objects.
51150c1a36fSDanilo Krummrich */
51250c1a36fSDanilo Krummrich struct drm_gpuvm_exec {
51350c1a36fSDanilo Krummrich /**
51450c1a36fSDanilo Krummrich * @exec: the &drm_exec structure
51550c1a36fSDanilo Krummrich */
51650c1a36fSDanilo Krummrich struct drm_exec exec;
51750c1a36fSDanilo Krummrich
51850c1a36fSDanilo Krummrich /**
51950c1a36fSDanilo Krummrich * @flags: the flags for the struct drm_exec
52050c1a36fSDanilo Krummrich */
521cf41cebfSThomas Hellström u32 flags;
52250c1a36fSDanilo Krummrich
52350c1a36fSDanilo Krummrich /**
52450c1a36fSDanilo Krummrich * @vm: the &drm_gpuvm to lock its DMA reservations
52550c1a36fSDanilo Krummrich */
52650c1a36fSDanilo Krummrich struct drm_gpuvm *vm;
52750c1a36fSDanilo Krummrich
52850c1a36fSDanilo Krummrich /**
52950c1a36fSDanilo Krummrich * @num_fences: the number of fences to reserve for the &dma_resv of the
53050c1a36fSDanilo Krummrich * locked &drm_gem_objects
53150c1a36fSDanilo Krummrich */
53250c1a36fSDanilo Krummrich unsigned int num_fences;
53350c1a36fSDanilo Krummrich
53450c1a36fSDanilo Krummrich /**
53550c1a36fSDanilo Krummrich * @extra: Callback and corresponding private data for the driver to
53650c1a36fSDanilo Krummrich * lock arbitrary additional &drm_gem_objects.
53750c1a36fSDanilo Krummrich */
53850c1a36fSDanilo Krummrich struct {
53950c1a36fSDanilo Krummrich /**
540200a6b3aSRandy Dunlap * @extra.fn: The driver callback to lock additional
541200a6b3aSRandy Dunlap * &drm_gem_objects.
54250c1a36fSDanilo Krummrich */
54350c1a36fSDanilo Krummrich int (*fn)(struct drm_gpuvm_exec *vm_exec);
54450c1a36fSDanilo Krummrich
54550c1a36fSDanilo Krummrich /**
546200a6b3aSRandy Dunlap * @extra.priv: driver private data for the @fn callback
54750c1a36fSDanilo Krummrich */
54850c1a36fSDanilo Krummrich void *priv;
54950c1a36fSDanilo Krummrich } extra;
55050c1a36fSDanilo Krummrich };
55150c1a36fSDanilo Krummrich
552e759f2caSDanilo Krummrich int drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
55350c1a36fSDanilo Krummrich struct drm_exec *exec,
554e759f2caSDanilo Krummrich unsigned int num_fences);
55550c1a36fSDanilo Krummrich
55650c1a36fSDanilo Krummrich int drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
55750c1a36fSDanilo Krummrich struct drm_exec *exec,
55850c1a36fSDanilo Krummrich unsigned int num_fences);
55950c1a36fSDanilo Krummrich
56050c1a36fSDanilo Krummrich int drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm,
56150c1a36fSDanilo Krummrich struct drm_exec *exec,
56250c1a36fSDanilo Krummrich u64 addr, u64 range,
56350c1a36fSDanilo Krummrich unsigned int num_fences);
56450c1a36fSDanilo Krummrich
56550c1a36fSDanilo Krummrich int drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec);
56650c1a36fSDanilo Krummrich
56750c1a36fSDanilo Krummrich int drm_gpuvm_exec_lock_array(struct drm_gpuvm_exec *vm_exec,
56850c1a36fSDanilo Krummrich struct drm_gem_object **objs,
56950c1a36fSDanilo Krummrich unsigned int num_objs);
57050c1a36fSDanilo Krummrich
57150c1a36fSDanilo Krummrich int drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
57250c1a36fSDanilo Krummrich u64 addr, u64 range);
57350c1a36fSDanilo Krummrich
57450c1a36fSDanilo Krummrich /**
57550c1a36fSDanilo Krummrich * drm_gpuvm_exec_unlock() - lock all dma-resv of all assoiciated BOs
57650c1a36fSDanilo Krummrich * @vm_exec: the &drm_gpuvm_exec wrapper
57750c1a36fSDanilo Krummrich *
57850c1a36fSDanilo Krummrich * Releases all dma-resv locks of all &drm_gem_objects previously acquired
57950c1a36fSDanilo Krummrich * through drm_gpuvm_exec_lock() or its variants.
58050c1a36fSDanilo Krummrich *
58150c1a36fSDanilo Krummrich * Returns: 0 on success, negative error code on failure.
58250c1a36fSDanilo Krummrich */
58350c1a36fSDanilo Krummrich static inline void
drm_gpuvm_exec_unlock(struct drm_gpuvm_exec * vm_exec)58450c1a36fSDanilo Krummrich drm_gpuvm_exec_unlock(struct drm_gpuvm_exec *vm_exec)
58550c1a36fSDanilo Krummrich {
58650c1a36fSDanilo Krummrich drm_exec_fini(&vm_exec->exec);
58750c1a36fSDanilo Krummrich }
58850c1a36fSDanilo Krummrich
58950c1a36fSDanilo Krummrich int drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec);
59050c1a36fSDanilo Krummrich void drm_gpuvm_resv_add_fence(struct drm_gpuvm *gpuvm,
59150c1a36fSDanilo Krummrich struct drm_exec *exec,
59250c1a36fSDanilo Krummrich struct dma_fence *fence,
59350c1a36fSDanilo Krummrich enum dma_resv_usage private_usage,
59450c1a36fSDanilo Krummrich enum dma_resv_usage extobj_usage);
59550c1a36fSDanilo Krummrich
59650c1a36fSDanilo Krummrich /**
597200a6b3aSRandy Dunlap * drm_gpuvm_exec_resv_add_fence() - add fence to private and all extobj
59850c1a36fSDanilo Krummrich * @vm_exec: the &drm_gpuvm_exec wrapper
59950c1a36fSDanilo Krummrich * @fence: fence to add
60050c1a36fSDanilo Krummrich * @private_usage: private dma-resv usage
60150c1a36fSDanilo Krummrich * @extobj_usage: extobj dma-resv usage
60250c1a36fSDanilo Krummrich *
60350c1a36fSDanilo Krummrich * See drm_gpuvm_resv_add_fence().
60450c1a36fSDanilo Krummrich */
60550c1a36fSDanilo Krummrich static inline void
drm_gpuvm_exec_resv_add_fence(struct drm_gpuvm_exec * vm_exec,struct dma_fence * fence,enum dma_resv_usage private_usage,enum dma_resv_usage extobj_usage)60650c1a36fSDanilo Krummrich drm_gpuvm_exec_resv_add_fence(struct drm_gpuvm_exec *vm_exec,
60750c1a36fSDanilo Krummrich struct dma_fence *fence,
60850c1a36fSDanilo Krummrich enum dma_resv_usage private_usage,
60950c1a36fSDanilo Krummrich enum dma_resv_usage extobj_usage)
61050c1a36fSDanilo Krummrich {
61150c1a36fSDanilo Krummrich drm_gpuvm_resv_add_fence(vm_exec->vm, &vm_exec->exec, fence,
61250c1a36fSDanilo Krummrich private_usage, extobj_usage);
61350c1a36fSDanilo Krummrich }
61450c1a36fSDanilo Krummrich
61550c1a36fSDanilo Krummrich /**
616200a6b3aSRandy Dunlap * drm_gpuvm_exec_validate() - validate all BOs marked as evicted
61750c1a36fSDanilo Krummrich * @vm_exec: the &drm_gpuvm_exec wrapper
61850c1a36fSDanilo Krummrich *
61950c1a36fSDanilo Krummrich * See drm_gpuvm_validate().
620200a6b3aSRandy Dunlap *
621200a6b3aSRandy Dunlap * Returns: 0 on success, negative error code on failure.
62250c1a36fSDanilo Krummrich */
62350c1a36fSDanilo Krummrich static inline int
drm_gpuvm_exec_validate(struct drm_gpuvm_exec * vm_exec)62450c1a36fSDanilo Krummrich drm_gpuvm_exec_validate(struct drm_gpuvm_exec *vm_exec)
62550c1a36fSDanilo Krummrich {
62650c1a36fSDanilo Krummrich return drm_gpuvm_validate(vm_exec->vm, &vm_exec->exec);
62750c1a36fSDanilo Krummrich }
62850c1a36fSDanilo Krummrich
62950c1a36fSDanilo Krummrich /**
63094bc2249SDanilo Krummrich * struct drm_gpuvm_bo - structure representing a &drm_gpuvm and
63194bc2249SDanilo Krummrich * &drm_gem_object combination
63294bc2249SDanilo Krummrich *
63394bc2249SDanilo Krummrich * This structure is an abstraction representing a &drm_gpuvm and
63494bc2249SDanilo Krummrich * &drm_gem_object combination. It serves as an indirection to accelerate
63594bc2249SDanilo Krummrich * iterating all &drm_gpuvas within a &drm_gpuvm backed by the same
63694bc2249SDanilo Krummrich * &drm_gem_object.
63794bc2249SDanilo Krummrich *
63894bc2249SDanilo Krummrich * Furthermore it is used cache evicted GEM objects for a certain GPU-VM to
63994bc2249SDanilo Krummrich * accelerate validation.
64094bc2249SDanilo Krummrich *
64194bc2249SDanilo Krummrich * Typically, drivers want to create an instance of a struct drm_gpuvm_bo once
64294bc2249SDanilo Krummrich * a GEM object is mapped first in a GPU-VM and release the instance once the
64394bc2249SDanilo Krummrich * last mapping of the GEM object in this GPU-VM is unmapped.
64494bc2249SDanilo Krummrich */
64594bc2249SDanilo Krummrich struct drm_gpuvm_bo {
64694bc2249SDanilo Krummrich /**
64794bc2249SDanilo Krummrich * @vm: The &drm_gpuvm the @obj is mapped in. This is a reference
64894bc2249SDanilo Krummrich * counted pointer.
64994bc2249SDanilo Krummrich */
65094bc2249SDanilo Krummrich struct drm_gpuvm *vm;
65194bc2249SDanilo Krummrich
65294bc2249SDanilo Krummrich /**
65394bc2249SDanilo Krummrich * @obj: The &drm_gem_object being mapped in @vm. This is a reference
65494bc2249SDanilo Krummrich * counted pointer.
65594bc2249SDanilo Krummrich */
65694bc2249SDanilo Krummrich struct drm_gem_object *obj;
65794bc2249SDanilo Krummrich
65894bc2249SDanilo Krummrich /**
65950c1a36fSDanilo Krummrich * @evicted: Indicates whether the &drm_gem_object is evicted; field
66050c1a36fSDanilo Krummrich * protected by the &drm_gem_object's dma-resv lock.
66150c1a36fSDanilo Krummrich */
66250c1a36fSDanilo Krummrich bool evicted;
66350c1a36fSDanilo Krummrich
66450c1a36fSDanilo Krummrich /**
66594bc2249SDanilo Krummrich * @kref: The reference count for this &drm_gpuvm_bo.
66694bc2249SDanilo Krummrich */
66794bc2249SDanilo Krummrich struct kref kref;
66894bc2249SDanilo Krummrich
66994bc2249SDanilo Krummrich /**
67094bc2249SDanilo Krummrich * @list: Structure containing all &list_heads.
67194bc2249SDanilo Krummrich */
67294bc2249SDanilo Krummrich struct {
67394bc2249SDanilo Krummrich /**
674200a6b3aSRandy Dunlap * @list.gpuva: The list of linked &drm_gpuvas.
67594bc2249SDanilo Krummrich *
67694bc2249SDanilo Krummrich * It is safe to access entries from this list as long as the
67794bc2249SDanilo Krummrich * GEM's gpuva lock is held. See also struct drm_gem_object.
67894bc2249SDanilo Krummrich */
67994bc2249SDanilo Krummrich struct list_head gpuva;
68094bc2249SDanilo Krummrich
68194bc2249SDanilo Krummrich /**
682200a6b3aSRandy Dunlap * @list.entry: Structure containing all &list_heads serving as
68394bc2249SDanilo Krummrich * entry.
68494bc2249SDanilo Krummrich */
68594bc2249SDanilo Krummrich struct {
68694bc2249SDanilo Krummrich /**
687200a6b3aSRandy Dunlap * @list.entry.gem: List entry to attach to the
688200a6b3aSRandy Dunlap * &drm_gem_objects gpuva list.
68994bc2249SDanilo Krummrich */
69094bc2249SDanilo Krummrich struct list_head gem;
69150c1a36fSDanilo Krummrich
69250c1a36fSDanilo Krummrich /**
693200a6b3aSRandy Dunlap * @list.entry.evict: List entry to attach to the
694200a6b3aSRandy Dunlap * &drm_gpuvms extobj list.
69550c1a36fSDanilo Krummrich */
69650c1a36fSDanilo Krummrich struct list_head extobj;
69750c1a36fSDanilo Krummrich
69850c1a36fSDanilo Krummrich /**
699200a6b3aSRandy Dunlap * @list.entry.evict: List entry to attach to the
700200a6b3aSRandy Dunlap * &drm_gpuvms evict list.
70150c1a36fSDanilo Krummrich */
70250c1a36fSDanilo Krummrich struct list_head evict;
70394bc2249SDanilo Krummrich } entry;
70494bc2249SDanilo Krummrich } list;
70594bc2249SDanilo Krummrich };
70694bc2249SDanilo Krummrich
70794bc2249SDanilo Krummrich struct drm_gpuvm_bo *
70894bc2249SDanilo Krummrich drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
70994bc2249SDanilo Krummrich struct drm_gem_object *obj);
71094bc2249SDanilo Krummrich
71194bc2249SDanilo Krummrich struct drm_gpuvm_bo *
71294bc2249SDanilo Krummrich drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,
71394bc2249SDanilo Krummrich struct drm_gem_object *obj);
71494bc2249SDanilo Krummrich struct drm_gpuvm_bo *
71594bc2249SDanilo Krummrich drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *vm_bo);
71694bc2249SDanilo Krummrich
71794bc2249SDanilo Krummrich /**
71894bc2249SDanilo Krummrich * drm_gpuvm_bo_get() - acquire a struct drm_gpuvm_bo reference
71994bc2249SDanilo Krummrich * @vm_bo: the &drm_gpuvm_bo to acquire the reference of
72094bc2249SDanilo Krummrich *
72194bc2249SDanilo Krummrich * This function acquires an additional reference to @vm_bo. It is illegal to
72294bc2249SDanilo Krummrich * call this without already holding a reference. No locks required.
723200a6b3aSRandy Dunlap *
724200a6b3aSRandy Dunlap * Returns: the &struct vm_bo pointer
72594bc2249SDanilo Krummrich */
72694bc2249SDanilo Krummrich static inline struct drm_gpuvm_bo *
drm_gpuvm_bo_get(struct drm_gpuvm_bo * vm_bo)72794bc2249SDanilo Krummrich drm_gpuvm_bo_get(struct drm_gpuvm_bo *vm_bo)
72894bc2249SDanilo Krummrich {
72994bc2249SDanilo Krummrich kref_get(&vm_bo->kref);
73094bc2249SDanilo Krummrich return vm_bo;
73194bc2249SDanilo Krummrich }
73294bc2249SDanilo Krummrich
733c50a291dSBoris Brezillon bool drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo);
73494bc2249SDanilo Krummrich
73594bc2249SDanilo Krummrich struct drm_gpuvm_bo *
73694bc2249SDanilo Krummrich drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
73794bc2249SDanilo Krummrich struct drm_gem_object *obj);
73894bc2249SDanilo Krummrich
73950c1a36fSDanilo Krummrich void drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict);
74050c1a36fSDanilo Krummrich
74150c1a36fSDanilo Krummrich /**
742200a6b3aSRandy Dunlap * drm_gpuvm_bo_gem_evict() - add/remove all &drm_gpuvm_bo's in the list
743200a6b3aSRandy Dunlap * to/from the &drm_gpuvms evicted list
74450c1a36fSDanilo Krummrich * @obj: the &drm_gem_object
74550c1a36fSDanilo Krummrich * @evict: indicates whether @obj is evicted
74650c1a36fSDanilo Krummrich *
74750c1a36fSDanilo Krummrich * See drm_gpuvm_bo_evict().
74850c1a36fSDanilo Krummrich */
74950c1a36fSDanilo Krummrich static inline void
drm_gpuvm_bo_gem_evict(struct drm_gem_object * obj,bool evict)75050c1a36fSDanilo Krummrich drm_gpuvm_bo_gem_evict(struct drm_gem_object *obj, bool evict)
75150c1a36fSDanilo Krummrich {
75250c1a36fSDanilo Krummrich struct drm_gpuvm_bo *vm_bo;
75350c1a36fSDanilo Krummrich
75450c1a36fSDanilo Krummrich drm_gem_gpuva_assert_lock_held(obj);
75550c1a36fSDanilo Krummrich drm_gem_for_each_gpuvm_bo(vm_bo, obj)
75650c1a36fSDanilo Krummrich drm_gpuvm_bo_evict(vm_bo, evict);
75750c1a36fSDanilo Krummrich }
75850c1a36fSDanilo Krummrich
75950c1a36fSDanilo Krummrich void drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo);
76050c1a36fSDanilo Krummrich
76194bc2249SDanilo Krummrich /**
76294bc2249SDanilo Krummrich * drm_gpuvm_bo_for_each_va() - iterator to walk over a list of &drm_gpuva
76394bc2249SDanilo Krummrich * @va__: &drm_gpuva structure to assign to in each iteration step
76494bc2249SDanilo Krummrich * @vm_bo__: the &drm_gpuvm_bo the &drm_gpuva to walk are associated with
76594bc2249SDanilo Krummrich *
76694bc2249SDanilo Krummrich * This iterator walks over all &drm_gpuva structures associated with the
76794bc2249SDanilo Krummrich * &drm_gpuvm_bo.
76894bc2249SDanilo Krummrich *
76994bc2249SDanilo Krummrich * The caller must hold the GEM's gpuva lock.
77094bc2249SDanilo Krummrich */
77194bc2249SDanilo Krummrich #define drm_gpuvm_bo_for_each_va(va__, vm_bo__) \
77294bc2249SDanilo Krummrich list_for_each_entry(va__, &(vm_bo)->list.gpuva, gem.entry)
77394bc2249SDanilo Krummrich
77494bc2249SDanilo Krummrich /**
77594bc2249SDanilo Krummrich * drm_gpuvm_bo_for_each_va_safe() - iterator to safely walk over a list of
77694bc2249SDanilo Krummrich * &drm_gpuva
77794bc2249SDanilo Krummrich * @va__: &drm_gpuva structure to assign to in each iteration step
77894bc2249SDanilo Krummrich * @next__: &next &drm_gpuva to store the next step
77994bc2249SDanilo Krummrich * @vm_bo__: the &drm_gpuvm_bo the &drm_gpuva to walk are associated with
78094bc2249SDanilo Krummrich *
78194bc2249SDanilo Krummrich * This iterator walks over all &drm_gpuva structures associated with the
78294bc2249SDanilo Krummrich * &drm_gpuvm_bo. It is implemented with list_for_each_entry_safe(), hence
78394bc2249SDanilo Krummrich * it is save against removal of elements.
78494bc2249SDanilo Krummrich *
78594bc2249SDanilo Krummrich * The caller must hold the GEM's gpuva lock.
78694bc2249SDanilo Krummrich */
78794bc2249SDanilo Krummrich #define drm_gpuvm_bo_for_each_va_safe(va__, next__, vm_bo__) \
78894bc2249SDanilo Krummrich list_for_each_entry_safe(va__, next__, &(vm_bo)->list.gpuva, gem.entry)
78994bc2249SDanilo Krummrich
79094bc2249SDanilo Krummrich /**
791f72c2db4SDanilo Krummrich * enum drm_gpuva_op_type - GPU VA operation type
792f72c2db4SDanilo Krummrich *
793f72c2db4SDanilo Krummrich * Operations to alter the GPU VA mappings tracked by the &drm_gpuvm.
794f72c2db4SDanilo Krummrich */
795f72c2db4SDanilo Krummrich enum drm_gpuva_op_type {
796f72c2db4SDanilo Krummrich /**
797f72c2db4SDanilo Krummrich * @DRM_GPUVA_OP_MAP: the map op type
798f72c2db4SDanilo Krummrich */
799f72c2db4SDanilo Krummrich DRM_GPUVA_OP_MAP,
800f72c2db4SDanilo Krummrich
801f72c2db4SDanilo Krummrich /**
802f72c2db4SDanilo Krummrich * @DRM_GPUVA_OP_REMAP: the remap op type
803f72c2db4SDanilo Krummrich */
804f72c2db4SDanilo Krummrich DRM_GPUVA_OP_REMAP,
805f72c2db4SDanilo Krummrich
806f72c2db4SDanilo Krummrich /**
807f72c2db4SDanilo Krummrich * @DRM_GPUVA_OP_UNMAP: the unmap op type
808f72c2db4SDanilo Krummrich */
809f72c2db4SDanilo Krummrich DRM_GPUVA_OP_UNMAP,
810f72c2db4SDanilo Krummrich
811f72c2db4SDanilo Krummrich /**
812f72c2db4SDanilo Krummrich * @DRM_GPUVA_OP_PREFETCH: the prefetch op type
813f72c2db4SDanilo Krummrich */
814f72c2db4SDanilo Krummrich DRM_GPUVA_OP_PREFETCH,
815*e53c1e26SMatthew Brost
816*e53c1e26SMatthew Brost /**
817*e53c1e26SMatthew Brost * @DRM_GPUVA_OP_DRIVER: the driver defined op type
818*e53c1e26SMatthew Brost */
819*e53c1e26SMatthew Brost DRM_GPUVA_OP_DRIVER,
820f72c2db4SDanilo Krummrich };
821f72c2db4SDanilo Krummrich
822f72c2db4SDanilo Krummrich /**
823f72c2db4SDanilo Krummrich * struct drm_gpuva_op_map - GPU VA map operation
824f72c2db4SDanilo Krummrich *
825f72c2db4SDanilo Krummrich * This structure represents a single map operation generated by the
826f72c2db4SDanilo Krummrich * DRM GPU VA manager.
827f72c2db4SDanilo Krummrich */
828f72c2db4SDanilo Krummrich struct drm_gpuva_op_map {
829f72c2db4SDanilo Krummrich /**
830f72c2db4SDanilo Krummrich * @va: structure containing address and range of a map
831f72c2db4SDanilo Krummrich * operation
832f72c2db4SDanilo Krummrich */
833f72c2db4SDanilo Krummrich struct {
834f72c2db4SDanilo Krummrich /**
835200a6b3aSRandy Dunlap * @va.addr: the base address of the new mapping
836f72c2db4SDanilo Krummrich */
837f72c2db4SDanilo Krummrich u64 addr;
838f72c2db4SDanilo Krummrich
839f72c2db4SDanilo Krummrich /**
840200a6b3aSRandy Dunlap * @va.range: the range of the new mapping
841f72c2db4SDanilo Krummrich */
842f72c2db4SDanilo Krummrich u64 range;
843f72c2db4SDanilo Krummrich } va;
844f72c2db4SDanilo Krummrich
845f72c2db4SDanilo Krummrich /**
846f72c2db4SDanilo Krummrich * @gem: structure containing the &drm_gem_object and it's offset
847f72c2db4SDanilo Krummrich */
848f72c2db4SDanilo Krummrich struct {
849f72c2db4SDanilo Krummrich /**
850200a6b3aSRandy Dunlap * @gem.offset: the offset within the &drm_gem_object
851f72c2db4SDanilo Krummrich */
852f72c2db4SDanilo Krummrich u64 offset;
853f72c2db4SDanilo Krummrich
854f72c2db4SDanilo Krummrich /**
855200a6b3aSRandy Dunlap * @gem.obj: the &drm_gem_object to map
856f72c2db4SDanilo Krummrich */
857f72c2db4SDanilo Krummrich struct drm_gem_object *obj;
858f72c2db4SDanilo Krummrich } gem;
859f72c2db4SDanilo Krummrich };
860f72c2db4SDanilo Krummrich
861f72c2db4SDanilo Krummrich /**
862f72c2db4SDanilo Krummrich * struct drm_gpuva_op_unmap - GPU VA unmap operation
863f72c2db4SDanilo Krummrich *
864f72c2db4SDanilo Krummrich * This structure represents a single unmap operation generated by the
865f72c2db4SDanilo Krummrich * DRM GPU VA manager.
866f72c2db4SDanilo Krummrich */
867f72c2db4SDanilo Krummrich struct drm_gpuva_op_unmap {
868f72c2db4SDanilo Krummrich /**
869f72c2db4SDanilo Krummrich * @va: the &drm_gpuva to unmap
870f72c2db4SDanilo Krummrich */
871f72c2db4SDanilo Krummrich struct drm_gpuva *va;
872f72c2db4SDanilo Krummrich
873f72c2db4SDanilo Krummrich /**
874f72c2db4SDanilo Krummrich * @keep:
875f72c2db4SDanilo Krummrich *
876f72c2db4SDanilo Krummrich * Indicates whether this &drm_gpuva is physically contiguous with the
877f72c2db4SDanilo Krummrich * original mapping request.
878f72c2db4SDanilo Krummrich *
879f72c2db4SDanilo Krummrich * Optionally, if &keep is set, drivers may keep the actual page table
880f72c2db4SDanilo Krummrich * mappings for this &drm_gpuva, adding the missing page table entries
881f72c2db4SDanilo Krummrich * only and update the &drm_gpuvm accordingly.
882f72c2db4SDanilo Krummrich */
883f72c2db4SDanilo Krummrich bool keep;
884f72c2db4SDanilo Krummrich };
885f72c2db4SDanilo Krummrich
886f72c2db4SDanilo Krummrich /**
887f72c2db4SDanilo Krummrich * struct drm_gpuva_op_remap - GPU VA remap operation
888f72c2db4SDanilo Krummrich *
889f72c2db4SDanilo Krummrich * This represents a single remap operation generated by the DRM GPU VA manager.
890f72c2db4SDanilo Krummrich *
891f72c2db4SDanilo Krummrich * A remap operation is generated when an existing GPU VA mmapping is split up
892f72c2db4SDanilo Krummrich * by inserting a new GPU VA mapping or by partially unmapping existent
893f72c2db4SDanilo Krummrich * mapping(s), hence it consists of a maximum of two map and one unmap
894f72c2db4SDanilo Krummrich * operation.
895f72c2db4SDanilo Krummrich *
896f72c2db4SDanilo Krummrich * The @unmap operation takes care of removing the original existing mapping.
897f72c2db4SDanilo Krummrich * @prev is used to remap the preceding part, @next the subsequent part.
898f72c2db4SDanilo Krummrich *
899f72c2db4SDanilo Krummrich * If either a new mapping's start address is aligned with the start address
900f72c2db4SDanilo Krummrich * of the old mapping or the new mapping's end address is aligned with the
901f72c2db4SDanilo Krummrich * end address of the old mapping, either @prev or @next is NULL.
902f72c2db4SDanilo Krummrich *
903f72c2db4SDanilo Krummrich * Note, the reason for a dedicated remap operation, rather than arbitrary
904f72c2db4SDanilo Krummrich * unmap and map operations, is to give drivers the chance of extracting driver
905f72c2db4SDanilo Krummrich * specific data for creating the new mappings from the unmap operations's
906f72c2db4SDanilo Krummrich * &drm_gpuva structure which typically is embedded in larger driver specific
907f72c2db4SDanilo Krummrich * structures.
908f72c2db4SDanilo Krummrich */
909f72c2db4SDanilo Krummrich struct drm_gpuva_op_remap {
910f72c2db4SDanilo Krummrich /**
911f72c2db4SDanilo Krummrich * @prev: the preceding part of a split mapping
912f72c2db4SDanilo Krummrich */
913f72c2db4SDanilo Krummrich struct drm_gpuva_op_map *prev;
914f72c2db4SDanilo Krummrich
915f72c2db4SDanilo Krummrich /**
916f72c2db4SDanilo Krummrich * @next: the subsequent part of a split mapping
917f72c2db4SDanilo Krummrich */
918f72c2db4SDanilo Krummrich struct drm_gpuva_op_map *next;
919f72c2db4SDanilo Krummrich
920f72c2db4SDanilo Krummrich /**
921f72c2db4SDanilo Krummrich * @unmap: the unmap operation for the original existing mapping
922f72c2db4SDanilo Krummrich */
923f72c2db4SDanilo Krummrich struct drm_gpuva_op_unmap *unmap;
924f72c2db4SDanilo Krummrich };
925f72c2db4SDanilo Krummrich
926f72c2db4SDanilo Krummrich /**
927f72c2db4SDanilo Krummrich * struct drm_gpuva_op_prefetch - GPU VA prefetch operation
928f72c2db4SDanilo Krummrich *
929f72c2db4SDanilo Krummrich * This structure represents a single prefetch operation generated by the
930f72c2db4SDanilo Krummrich * DRM GPU VA manager.
931f72c2db4SDanilo Krummrich */
932f72c2db4SDanilo Krummrich struct drm_gpuva_op_prefetch {
933f72c2db4SDanilo Krummrich /**
934f72c2db4SDanilo Krummrich * @va: the &drm_gpuva to prefetch
935f72c2db4SDanilo Krummrich */
936f72c2db4SDanilo Krummrich struct drm_gpuva *va;
937f72c2db4SDanilo Krummrich };
938f72c2db4SDanilo Krummrich
939f72c2db4SDanilo Krummrich /**
940f72c2db4SDanilo Krummrich * struct drm_gpuva_op - GPU VA operation
941f72c2db4SDanilo Krummrich *
942f72c2db4SDanilo Krummrich * This structure represents a single generic operation.
943f72c2db4SDanilo Krummrich *
944f72c2db4SDanilo Krummrich * The particular type of the operation is defined by @op.
945f72c2db4SDanilo Krummrich */
946f72c2db4SDanilo Krummrich struct drm_gpuva_op {
947f72c2db4SDanilo Krummrich /**
948f72c2db4SDanilo Krummrich * @entry:
949f72c2db4SDanilo Krummrich *
950f72c2db4SDanilo Krummrich * The &list_head used to distribute instances of this struct within
951f72c2db4SDanilo Krummrich * &drm_gpuva_ops.
952f72c2db4SDanilo Krummrich */
953f72c2db4SDanilo Krummrich struct list_head entry;
954f72c2db4SDanilo Krummrich
955f72c2db4SDanilo Krummrich /**
956f72c2db4SDanilo Krummrich * @op: the type of the operation
957f72c2db4SDanilo Krummrich */
958f72c2db4SDanilo Krummrich enum drm_gpuva_op_type op;
959f72c2db4SDanilo Krummrich
960f72c2db4SDanilo Krummrich union {
961f72c2db4SDanilo Krummrich /**
962f72c2db4SDanilo Krummrich * @map: the map operation
963f72c2db4SDanilo Krummrich */
964f72c2db4SDanilo Krummrich struct drm_gpuva_op_map map;
965f72c2db4SDanilo Krummrich
966f72c2db4SDanilo Krummrich /**
967f72c2db4SDanilo Krummrich * @remap: the remap operation
968f72c2db4SDanilo Krummrich */
969f72c2db4SDanilo Krummrich struct drm_gpuva_op_remap remap;
970f72c2db4SDanilo Krummrich
971f72c2db4SDanilo Krummrich /**
972f72c2db4SDanilo Krummrich * @unmap: the unmap operation
973f72c2db4SDanilo Krummrich */
974f72c2db4SDanilo Krummrich struct drm_gpuva_op_unmap unmap;
975f72c2db4SDanilo Krummrich
976f72c2db4SDanilo Krummrich /**
977f72c2db4SDanilo Krummrich * @prefetch: the prefetch operation
978f72c2db4SDanilo Krummrich */
979f72c2db4SDanilo Krummrich struct drm_gpuva_op_prefetch prefetch;
980f72c2db4SDanilo Krummrich };
981f72c2db4SDanilo Krummrich };
982f72c2db4SDanilo Krummrich
983f72c2db4SDanilo Krummrich /**
984f72c2db4SDanilo Krummrich * struct drm_gpuva_ops - wraps a list of &drm_gpuva_op
985f72c2db4SDanilo Krummrich */
986f72c2db4SDanilo Krummrich struct drm_gpuva_ops {
987f72c2db4SDanilo Krummrich /**
988f72c2db4SDanilo Krummrich * @list: the &list_head
989f72c2db4SDanilo Krummrich */
990f72c2db4SDanilo Krummrich struct list_head list;
991f72c2db4SDanilo Krummrich };
992f72c2db4SDanilo Krummrich
993f72c2db4SDanilo Krummrich /**
994f72c2db4SDanilo Krummrich * drm_gpuva_for_each_op() - iterator to walk over &drm_gpuva_ops
995f72c2db4SDanilo Krummrich * @op: &drm_gpuva_op to assign in each iteration step
996f72c2db4SDanilo Krummrich * @ops: &drm_gpuva_ops to walk
997f72c2db4SDanilo Krummrich *
998f72c2db4SDanilo Krummrich * This iterator walks over all ops within a given list of operations.
999f72c2db4SDanilo Krummrich */
1000f72c2db4SDanilo Krummrich #define drm_gpuva_for_each_op(op, ops) list_for_each_entry(op, &(ops)->list, entry)
1001f72c2db4SDanilo Krummrich
1002f72c2db4SDanilo Krummrich /**
1003f72c2db4SDanilo Krummrich * drm_gpuva_for_each_op_safe() - iterator to safely walk over &drm_gpuva_ops
1004f72c2db4SDanilo Krummrich * @op: &drm_gpuva_op to assign in each iteration step
1005f72c2db4SDanilo Krummrich * @next: &next &drm_gpuva_op to store the next step
1006f72c2db4SDanilo Krummrich * @ops: &drm_gpuva_ops to walk
1007f72c2db4SDanilo Krummrich *
1008f72c2db4SDanilo Krummrich * This iterator walks over all ops within a given list of operations. It is
1009f72c2db4SDanilo Krummrich * implemented with list_for_each_safe(), so save against removal of elements.
1010f72c2db4SDanilo Krummrich */
1011f72c2db4SDanilo Krummrich #define drm_gpuva_for_each_op_safe(op, next, ops) \
1012f72c2db4SDanilo Krummrich list_for_each_entry_safe(op, next, &(ops)->list, entry)
1013f72c2db4SDanilo Krummrich
1014f72c2db4SDanilo Krummrich /**
1015f72c2db4SDanilo Krummrich * drm_gpuva_for_each_op_from_reverse() - iterate backwards from the given point
1016f72c2db4SDanilo Krummrich * @op: &drm_gpuva_op to assign in each iteration step
1017f72c2db4SDanilo Krummrich * @ops: &drm_gpuva_ops to walk
1018f72c2db4SDanilo Krummrich *
1019f72c2db4SDanilo Krummrich * This iterator walks over all ops within a given list of operations beginning
1020f72c2db4SDanilo Krummrich * from the given operation in reverse order.
1021f72c2db4SDanilo Krummrich */
1022f72c2db4SDanilo Krummrich #define drm_gpuva_for_each_op_from_reverse(op, ops) \
1023f72c2db4SDanilo Krummrich list_for_each_entry_from_reverse(op, &(ops)->list, entry)
1024f72c2db4SDanilo Krummrich
1025f72c2db4SDanilo Krummrich /**
1026bbd52b61SMatthew Brost * drm_gpuva_for_each_op_reverse - iterator to walk over &drm_gpuva_ops in reverse
1027bbd52b61SMatthew Brost * @op: &drm_gpuva_op to assign in each iteration step
1028bbd52b61SMatthew Brost * @ops: &drm_gpuva_ops to walk
1029bbd52b61SMatthew Brost *
1030bbd52b61SMatthew Brost * This iterator walks over all ops within a given list of operations in reverse
1031bbd52b61SMatthew Brost */
1032bbd52b61SMatthew Brost #define drm_gpuva_for_each_op_reverse(op, ops) \
1033bbd52b61SMatthew Brost list_for_each_entry_reverse(op, &(ops)->list, entry)
1034bbd52b61SMatthew Brost
1035bbd52b61SMatthew Brost /**
1036f72c2db4SDanilo Krummrich * drm_gpuva_first_op() - returns the first &drm_gpuva_op from &drm_gpuva_ops
1037f72c2db4SDanilo Krummrich * @ops: the &drm_gpuva_ops to get the fist &drm_gpuva_op from
1038f72c2db4SDanilo Krummrich */
1039f72c2db4SDanilo Krummrich #define drm_gpuva_first_op(ops) \
1040f72c2db4SDanilo Krummrich list_first_entry(&(ops)->list, struct drm_gpuva_op, entry)
1041f72c2db4SDanilo Krummrich
1042f72c2db4SDanilo Krummrich /**
1043f72c2db4SDanilo Krummrich * drm_gpuva_last_op() - returns the last &drm_gpuva_op from &drm_gpuva_ops
1044f72c2db4SDanilo Krummrich * @ops: the &drm_gpuva_ops to get the last &drm_gpuva_op from
1045f72c2db4SDanilo Krummrich */
1046f72c2db4SDanilo Krummrich #define drm_gpuva_last_op(ops) \
1047f72c2db4SDanilo Krummrich list_last_entry(&(ops)->list, struct drm_gpuva_op, entry)
1048f72c2db4SDanilo Krummrich
1049f72c2db4SDanilo Krummrich /**
1050f72c2db4SDanilo Krummrich * drm_gpuva_prev_op() - previous &drm_gpuva_op in the list
1051f72c2db4SDanilo Krummrich * @op: the current &drm_gpuva_op
1052f72c2db4SDanilo Krummrich */
1053f72c2db4SDanilo Krummrich #define drm_gpuva_prev_op(op) list_prev_entry(op, entry)
1054f72c2db4SDanilo Krummrich
1055f72c2db4SDanilo Krummrich /**
1056f72c2db4SDanilo Krummrich * drm_gpuva_next_op() - next &drm_gpuva_op in the list
1057f72c2db4SDanilo Krummrich * @op: the current &drm_gpuva_op
1058f72c2db4SDanilo Krummrich */
1059f72c2db4SDanilo Krummrich #define drm_gpuva_next_op(op) list_next_entry(op, entry)
1060f72c2db4SDanilo Krummrich
1061f72c2db4SDanilo Krummrich struct drm_gpuva_ops *
1062f72c2db4SDanilo Krummrich drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
1063f72c2db4SDanilo Krummrich u64 addr, u64 range,
1064f72c2db4SDanilo Krummrich struct drm_gem_object *obj, u64 offset);
1065f72c2db4SDanilo Krummrich struct drm_gpuva_ops *
1066f72c2db4SDanilo Krummrich drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm,
1067f72c2db4SDanilo Krummrich u64 addr, u64 range);
1068f72c2db4SDanilo Krummrich
1069f72c2db4SDanilo Krummrich struct drm_gpuva_ops *
1070f72c2db4SDanilo Krummrich drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm,
1071f72c2db4SDanilo Krummrich u64 addr, u64 range);
1072f72c2db4SDanilo Krummrich
1073f72c2db4SDanilo Krummrich struct drm_gpuva_ops *
107494bc2249SDanilo Krummrich drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo);
1075f72c2db4SDanilo Krummrich
1076f72c2db4SDanilo Krummrich void drm_gpuva_ops_free(struct drm_gpuvm *gpuvm,
1077f72c2db4SDanilo Krummrich struct drm_gpuva_ops *ops);
1078f72c2db4SDanilo Krummrich
drm_gpuva_init_from_op(struct drm_gpuva * va,struct drm_gpuva_op_map * op)1079f72c2db4SDanilo Krummrich static inline void drm_gpuva_init_from_op(struct drm_gpuva *va,
1080f72c2db4SDanilo Krummrich struct drm_gpuva_op_map *op)
1081f72c2db4SDanilo Krummrich {
1082f72c2db4SDanilo Krummrich drm_gpuva_init(va, op->va.addr, op->va.range,
1083f72c2db4SDanilo Krummrich op->gem.obj, op->gem.offset);
1084f72c2db4SDanilo Krummrich }
1085f72c2db4SDanilo Krummrich
1086f72c2db4SDanilo Krummrich /**
1087f72c2db4SDanilo Krummrich * struct drm_gpuvm_ops - callbacks for split/merge steps
1088f72c2db4SDanilo Krummrich *
1089f72c2db4SDanilo Krummrich * This structure defines the callbacks used by &drm_gpuvm_sm_map and
1090f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_unmap to provide the split/merge steps for map and unmap
1091f72c2db4SDanilo Krummrich * operations to drivers.
1092f72c2db4SDanilo Krummrich */
1093f72c2db4SDanilo Krummrich struct drm_gpuvm_ops {
1094f72c2db4SDanilo Krummrich /**
10958af72338SDanilo Krummrich * @vm_free: called when the last reference of a struct drm_gpuvm is
10968af72338SDanilo Krummrich * dropped
10978af72338SDanilo Krummrich *
10988af72338SDanilo Krummrich * This callback is mandatory.
10998af72338SDanilo Krummrich */
11008af72338SDanilo Krummrich void (*vm_free)(struct drm_gpuvm *gpuvm);
11018af72338SDanilo Krummrich
11028af72338SDanilo Krummrich /**
1103f72c2db4SDanilo Krummrich * @op_alloc: called when the &drm_gpuvm allocates
1104f72c2db4SDanilo Krummrich * a struct drm_gpuva_op
1105f72c2db4SDanilo Krummrich *
1106f72c2db4SDanilo Krummrich * Some drivers may want to embed struct drm_gpuva_op into driver
1107f72c2db4SDanilo Krummrich * specific structures. By implementing this callback drivers can
1108f72c2db4SDanilo Krummrich * allocate memory accordingly.
1109f72c2db4SDanilo Krummrich *
1110f72c2db4SDanilo Krummrich * This callback is optional.
1111f72c2db4SDanilo Krummrich */
1112f72c2db4SDanilo Krummrich struct drm_gpuva_op *(*op_alloc)(void);
1113f72c2db4SDanilo Krummrich
1114f72c2db4SDanilo Krummrich /**
1115f72c2db4SDanilo Krummrich * @op_free: called when the &drm_gpuvm frees a
1116f72c2db4SDanilo Krummrich * struct drm_gpuva_op
1117f72c2db4SDanilo Krummrich *
1118f72c2db4SDanilo Krummrich * Some drivers may want to embed struct drm_gpuva_op into driver
1119f72c2db4SDanilo Krummrich * specific structures. By implementing this callback drivers can
1120f72c2db4SDanilo Krummrich * free the previously allocated memory accordingly.
1121f72c2db4SDanilo Krummrich *
1122f72c2db4SDanilo Krummrich * This callback is optional.
1123f72c2db4SDanilo Krummrich */
1124f72c2db4SDanilo Krummrich void (*op_free)(struct drm_gpuva_op *op);
1125f72c2db4SDanilo Krummrich
1126f72c2db4SDanilo Krummrich /**
112794bc2249SDanilo Krummrich * @vm_bo_alloc: called when the &drm_gpuvm allocates
112894bc2249SDanilo Krummrich * a struct drm_gpuvm_bo
112994bc2249SDanilo Krummrich *
113094bc2249SDanilo Krummrich * Some drivers may want to embed struct drm_gpuvm_bo into driver
113194bc2249SDanilo Krummrich * specific structures. By implementing this callback drivers can
113294bc2249SDanilo Krummrich * allocate memory accordingly.
113394bc2249SDanilo Krummrich *
113494bc2249SDanilo Krummrich * This callback is optional.
113594bc2249SDanilo Krummrich */
113694bc2249SDanilo Krummrich struct drm_gpuvm_bo *(*vm_bo_alloc)(void);
113794bc2249SDanilo Krummrich
113894bc2249SDanilo Krummrich /**
113994bc2249SDanilo Krummrich * @vm_bo_free: called when the &drm_gpuvm frees a
114094bc2249SDanilo Krummrich * struct drm_gpuvm_bo
114194bc2249SDanilo Krummrich *
114294bc2249SDanilo Krummrich * Some drivers may want to embed struct drm_gpuvm_bo into driver
114394bc2249SDanilo Krummrich * specific structures. By implementing this callback drivers can
114494bc2249SDanilo Krummrich * free the previously allocated memory accordingly.
114594bc2249SDanilo Krummrich *
114694bc2249SDanilo Krummrich * This callback is optional.
114794bc2249SDanilo Krummrich */
114894bc2249SDanilo Krummrich void (*vm_bo_free)(struct drm_gpuvm_bo *vm_bo);
114994bc2249SDanilo Krummrich
115094bc2249SDanilo Krummrich /**
115150c1a36fSDanilo Krummrich * @vm_bo_validate: called from drm_gpuvm_validate()
115250c1a36fSDanilo Krummrich *
115350c1a36fSDanilo Krummrich * Drivers receive this callback for every evicted &drm_gem_object being
115450c1a36fSDanilo Krummrich * mapped in the corresponding &drm_gpuvm.
115550c1a36fSDanilo Krummrich *
115650c1a36fSDanilo Krummrich * Typically, drivers would call their driver specific variant of
115750c1a36fSDanilo Krummrich * ttm_bo_validate() from within this callback.
115850c1a36fSDanilo Krummrich */
115950c1a36fSDanilo Krummrich int (*vm_bo_validate)(struct drm_gpuvm_bo *vm_bo,
116050c1a36fSDanilo Krummrich struct drm_exec *exec);
116150c1a36fSDanilo Krummrich
116250c1a36fSDanilo Krummrich /**
1163f72c2db4SDanilo Krummrich * @sm_step_map: called from &drm_gpuvm_sm_map to finally insert the
1164f72c2db4SDanilo Krummrich * mapping once all previous steps were completed
1165f72c2db4SDanilo Krummrich *
1166f72c2db4SDanilo Krummrich * The &priv pointer matches the one the driver passed to
1167f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_map or &drm_gpuvm_sm_unmap, respectively.
1168f72c2db4SDanilo Krummrich *
1169f72c2db4SDanilo Krummrich * Can be NULL if &drm_gpuvm_sm_map is used.
1170f72c2db4SDanilo Krummrich */
1171f72c2db4SDanilo Krummrich int (*sm_step_map)(struct drm_gpuva_op *op, void *priv);
1172f72c2db4SDanilo Krummrich
1173f72c2db4SDanilo Krummrich /**
1174f72c2db4SDanilo Krummrich * @sm_step_remap: called from &drm_gpuvm_sm_map and
1175f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_unmap to split up an existent mapping
1176f72c2db4SDanilo Krummrich *
1177f72c2db4SDanilo Krummrich * This callback is called when existent mapping needs to be split up.
1178f72c2db4SDanilo Krummrich * This is the case when either a newly requested mapping overlaps or
1179f72c2db4SDanilo Krummrich * is enclosed by an existent mapping or a partial unmap of an existent
1180f72c2db4SDanilo Krummrich * mapping is requested.
1181f72c2db4SDanilo Krummrich *
1182f72c2db4SDanilo Krummrich * The &priv pointer matches the one the driver passed to
1183f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_map or &drm_gpuvm_sm_unmap, respectively.
1184f72c2db4SDanilo Krummrich *
1185f72c2db4SDanilo Krummrich * Can be NULL if neither &drm_gpuvm_sm_map nor &drm_gpuvm_sm_unmap is
1186f72c2db4SDanilo Krummrich * used.
1187f72c2db4SDanilo Krummrich */
1188f72c2db4SDanilo Krummrich int (*sm_step_remap)(struct drm_gpuva_op *op, void *priv);
1189f72c2db4SDanilo Krummrich
1190f72c2db4SDanilo Krummrich /**
1191f72c2db4SDanilo Krummrich * @sm_step_unmap: called from &drm_gpuvm_sm_map and
1192f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_unmap to unmap an existent mapping
1193f72c2db4SDanilo Krummrich *
1194f72c2db4SDanilo Krummrich * This callback is called when existent mapping needs to be unmapped.
1195f72c2db4SDanilo Krummrich * This is the case when either a newly requested mapping encloses an
1196f72c2db4SDanilo Krummrich * existent mapping or an unmap of an existent mapping is requested.
1197f72c2db4SDanilo Krummrich *
1198f72c2db4SDanilo Krummrich * The &priv pointer matches the one the driver passed to
1199f72c2db4SDanilo Krummrich * &drm_gpuvm_sm_map or &drm_gpuvm_sm_unmap, respectively.
1200f72c2db4SDanilo Krummrich *
1201f72c2db4SDanilo Krummrich * Can be NULL if neither &drm_gpuvm_sm_map nor &drm_gpuvm_sm_unmap is
1202f72c2db4SDanilo Krummrich * used.
1203f72c2db4SDanilo Krummrich */
1204f72c2db4SDanilo Krummrich int (*sm_step_unmap)(struct drm_gpuva_op *op, void *priv);
1205f72c2db4SDanilo Krummrich };
1206f72c2db4SDanilo Krummrich
1207f72c2db4SDanilo Krummrich int drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv,
1208f72c2db4SDanilo Krummrich u64 addr, u64 range,
1209f72c2db4SDanilo Krummrich struct drm_gem_object *obj, u64 offset);
1210f72c2db4SDanilo Krummrich
1211f72c2db4SDanilo Krummrich int drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv,
1212f72c2db4SDanilo Krummrich u64 addr, u64 range);
1213f72c2db4SDanilo Krummrich
1214f72c2db4SDanilo Krummrich void drm_gpuva_map(struct drm_gpuvm *gpuvm,
1215f72c2db4SDanilo Krummrich struct drm_gpuva *va,
1216f72c2db4SDanilo Krummrich struct drm_gpuva_op_map *op);
1217f72c2db4SDanilo Krummrich
1218f72c2db4SDanilo Krummrich void drm_gpuva_remap(struct drm_gpuva *prev,
1219f72c2db4SDanilo Krummrich struct drm_gpuva *next,
1220f72c2db4SDanilo Krummrich struct drm_gpuva_op_remap *op);
1221f72c2db4SDanilo Krummrich
1222f72c2db4SDanilo Krummrich void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op);
1223f72c2db4SDanilo Krummrich
1224a191f73dSDonald Robson /**
1225a191f73dSDonald Robson * drm_gpuva_op_remap_to_unmap_range() - Helper to get the start and range of
1226a191f73dSDonald Robson * the unmap stage of a remap op.
1227a191f73dSDonald Robson * @op: Remap op.
1228a191f73dSDonald Robson * @start_addr: Output pointer for the start of the required unmap.
1229a191f73dSDonald Robson * @range: Output pointer for the length of the required unmap.
1230a191f73dSDonald Robson *
1231a191f73dSDonald Robson * The given start address and range will be set such that they represent the
1232a191f73dSDonald Robson * range of the address space that was previously covered by the mapping being
1233a191f73dSDonald Robson * re-mapped, but is now empty.
1234a191f73dSDonald Robson */
1235a191f73dSDonald Robson static inline void
drm_gpuva_op_remap_to_unmap_range(const struct drm_gpuva_op_remap * op,u64 * start_addr,u64 * range)1236a191f73dSDonald Robson drm_gpuva_op_remap_to_unmap_range(const struct drm_gpuva_op_remap *op,
1237a191f73dSDonald Robson u64 *start_addr, u64 *range)
1238a191f73dSDonald Robson {
1239a191f73dSDonald Robson const u64 va_start = op->prev ?
1240a191f73dSDonald Robson op->prev->va.addr + op->prev->va.range :
1241a191f73dSDonald Robson op->unmap->va->va.addr;
1242a191f73dSDonald Robson const u64 va_end = op->next ?
1243a191f73dSDonald Robson op->next->va.addr :
1244a191f73dSDonald Robson op->unmap->va->va.addr + op->unmap->va->va.range;
1245a191f73dSDonald Robson
1246a191f73dSDonald Robson if (start_addr)
1247a191f73dSDonald Robson *start_addr = va_start;
1248a191f73dSDonald Robson if (range)
1249a191f73dSDonald Robson *range = va_end - va_start;
1250a191f73dSDonald Robson }
1251a191f73dSDonald Robson
1252f72c2db4SDanilo Krummrich #endif /* __DRM_GPUVM_H__ */
1253