projects/linux·blob master · refs

3206 lines · 92.7 KiB

1// SPDX-License-Identifier: GPL-2.0-only OR MIT
2/*
3 * Copyright (c) 2022 Red Hat.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Danilo Krummrich <[email protected]>
25 *
26 */
27
28#include <drm/drm_drv.h>
29#include <drm/drm_gpuvm.h>
30#include <drm/drm_print.h>
31
32#include <linux/export.h>
33#include <linux/interval_tree_generic.h>
34#include <linux/mm.h>
35
36/**
37 * DOC: Overview
38 *
39 * The DRM GPU VA Manager, represented by struct drm_gpuvm keeps track of a
40 * GPU's virtual address (VA) space and manages the corresponding virtual
41 * mappings represented by &drm_gpuva objects. It also keeps track of the
42 * mapping's backing &drm_gem_object buffers.
43 *
44 * &drm_gem_object buffers maintain a list of &drm_gpuva objects representing
45 * all existing GPU VA mappings using this &drm_gem_object as backing buffer.
46 *
47 * GPU VAs can be flagged as sparse, such that drivers may use GPU VAs to also
48 * keep track of sparse PTEs in order to support Vulkan 'Sparse Resources'.
49 *
50 * The GPU VA manager internally uses a rb-tree to manage the
51 * &drm_gpuva mappings within a GPU's virtual address space.
52 *
53 * The &drm_gpuvm structure contains a special &drm_gpuva representing the
54 * portion of VA space reserved by the kernel. This node is initialized together
55 * with the GPU VA manager instance and removed when the GPU VA manager is
56 * destroyed.
57 *
58 * In a typical application drivers would embed struct drm_gpuvm and
59 * struct drm_gpuva within their own driver specific structures, there won't be
60 * any memory allocations of its own nor memory allocations of &drm_gpuva
61 * entries.
62 *
63 * The data structures needed to store &drm_gpuvas within the &drm_gpuvm are
64 * contained within struct drm_gpuva already. Hence, for inserting &drm_gpuva
65 * entries from within dma-fence signalling critical sections it is enough to
66 * pre-allocate the &drm_gpuva structures.
67 *
68 * &drm_gem_objects which are private to a single VM can share a common
69 * &dma_resv in order to improve locking efficiency (e.g. with &drm_exec).
70 * For this purpose drivers must pass a &drm_gem_object to drm_gpuvm_init(), in
71 * the following called 'resv object', which serves as the container of the
72 * GPUVM's shared &dma_resv. This resv object can be a driver specific
73 * &drm_gem_object, such as the &drm_gem_object containing the root page table,
74 * but it can also be a 'dummy' object, which can be allocated with
75 * drm_gpuvm_resv_object_alloc().
76 *
77 * In order to connect a struct drm_gpuva to its backing &drm_gem_object each
78 * &drm_gem_object maintains a list of &drm_gpuvm_bo structures, and each
79 * &drm_gpuvm_bo contains a list of &drm_gpuva structures.
80 *
81 * A &drm_gpuvm_bo is an abstraction that represents a combination of a
82 * &drm_gpuvm and a &drm_gem_object. Every such combination should be unique.
83 * This is ensured by the API through drm_gpuvm_bo_obtain() and
84 * drm_gpuvm_bo_obtain_prealloc() which first look into the corresponding
85 * &drm_gem_object list of &drm_gpuvm_bos for an existing instance of this
86 * particular combination. If not present, a new instance is created and linked
87 * to the &drm_gem_object.
88 *
89 * &drm_gpuvm_bo structures, since unique for a given &drm_gpuvm, are also used
90 * as entry for the &drm_gpuvm's lists of external and evicted objects. Those
91 * lists are maintained in order to accelerate locking of dma-resv locks and
92 * validation of evicted objects bound in a &drm_gpuvm. For instance, all
93 * &drm_gem_object's &dma_resv of a given &drm_gpuvm can be locked by calling
94 * drm_gpuvm_exec_lock(). Once locked drivers can call drm_gpuvm_validate() in
95 * order to validate all evicted &drm_gem_objects. It is also possible to lock
96 * additional &drm_gem_objects by providing the corresponding parameters to
97 * drm_gpuvm_exec_lock() as well as open code the &drm_exec loop while making
98 * use of helper functions such as drm_gpuvm_prepare_range() or
99 * drm_gpuvm_prepare_objects().
100 *
101 * Every bound &drm_gem_object is treated as external object when its &dma_resv
102 * structure is different than the &drm_gpuvm's common &dma_resv structure.
103 */
104
105/**
106 * DOC: Split and Merge
107 *
108 * Besides its capability to manage and represent a GPU VA space, the
109 * GPU VA manager also provides functions to let the &drm_gpuvm calculate a
110 * sequence of operations to satisfy a given map or unmap request.
111 *
112 * Therefore the DRM GPU VA manager provides an algorithm implementing splitting
113 * and merging of existing GPU VA mappings with the ones that are requested to
114 * be mapped or unmapped. This feature is required by the Vulkan API to
115 * implement Vulkan 'Sparse Memory Bindings' - drivers UAPIs often refer to this
116 * as VM BIND.
117 *
118 * Drivers can call drm_gpuvm_sm_map() to receive a sequence of callbacks
119 * containing map, unmap and remap operations for a given newly requested
120 * mapping. The sequence of callbacks represents the set of operations to
121 * execute in order to integrate the new mapping cleanly into the current state
122 * of the GPU VA space.
123 *
124 * Depending on how the new GPU VA mapping intersects with the existing mappings
125 * of the GPU VA space the &drm_gpuvm_ops callbacks contain an arbitrary amount
126 * of unmap operations, a maximum of two remap operations and a single map
127 * operation. The caller might receive no callback at all if no operation is
128 * required, e.g. if the requested mapping already exists in the exact same way.
129 *
130 * The single map operation represents the original map operation requested by
131 * the caller.
132 *
133 * &drm_gpuva_op_unmap contains a 'keep' field, which indicates whether the
134 * &drm_gpuva to unmap is physically contiguous with the original mapping
135 * request. Optionally, if 'keep' is set, drivers may keep the actual page table
136 * entries for this &drm_gpuva, adding the missing page table entries only and
137 * update the &drm_gpuvm's view of things accordingly.
138 *
139 * Drivers may do the same optimization, namely delta page table updates, also
140 * for remap operations. This is possible since &drm_gpuva_op_remap consists of
141 * one unmap operation and one or two map operations, such that drivers can
142 * derive the page table update delta accordingly.
143 *
144 * Note that there can't be more than two existing mappings to split up, one at
145 * the beginning and one at the end of the new mapping, hence there is a
146 * maximum of two remap operations.
147 *
148 * Analogous to drm_gpuvm_sm_map() drm_gpuvm_sm_unmap() uses &drm_gpuvm_ops to
149 * call back into the driver in order to unmap a range of GPU VA space. The
150 * logic behind this function is way simpler though: For all existing mappings
151 * enclosed by the given range unmap operations are created. For mappings which
152 * are only partially located within the given range, remap operations are
153 * created such that those mappings are split up and re-mapped partially.
154 *
155 * As an alternative to drm_gpuvm_sm_map() and drm_gpuvm_sm_unmap(),
156 * drm_gpuvm_sm_map_ops_create() and drm_gpuvm_sm_unmap_ops_create() can be used
157 * to directly obtain an instance of struct drm_gpuva_ops containing a list of
158 * &drm_gpuva_op, which can be iterated with drm_gpuva_for_each_op(). This list
159 * contains the &drm_gpuva_ops analogous to the callbacks one would receive when
160 * calling drm_gpuvm_sm_map() or drm_gpuvm_sm_unmap(). While this way requires
161 * more memory (to allocate the &drm_gpuva_ops), it provides drivers a way to
162 * iterate the &drm_gpuva_op multiple times, e.g. once in a context where memory
163 * allocations are possible (e.g. to allocate GPU page tables) and once in the
164 * dma-fence signalling critical path.
165 *
166 * To update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert() and
167 * drm_gpuva_remove() may be used. These functions can safely be used from
168 * &drm_gpuvm_ops callbacks originating from drm_gpuvm_sm_map() or
169 * drm_gpuvm_sm_unmap(). However, it might be more convenient to use the
170 * provided helper functions drm_gpuva_map(), drm_gpuva_remap() and
171 * drm_gpuva_unmap() instead.
172 *
173 * The following diagram depicts the basic relationships of existing GPU VA
174 * mappings, a newly requested mapping and the resulting mappings as implemented
175 * by drm_gpuvm_sm_map() - it doesn't cover any arbitrary combinations of these.
176 *
177 * 1) Requested mapping is identical. Replace it, but indicate the backing PTEs
178 * could be kept.
179 *
180 * ::
181 *
182 * 0 a 1
183 * old: |-----------| (bo_offset=n)
184 *
185 * 0 a 1
186 * req: |-----------| (bo_offset=n)
187 *
188 * 0 a 1
189 * new: |-----------| (bo_offset=n)
190 *
191 *
192 * 2) Requested mapping is identical, except for the BO offset, hence replace
193 * the mapping.
194 *
195 * ::
196 *
197 * 0 a 1
198 * old: |-----------| (bo_offset=n)
199 *
200 * 0 a 1
201 * req: |-----------| (bo_offset=m)
202 *
203 * 0 a 1
204 * new: |-----------| (bo_offset=m)
205 *
206 *
207 * 3) Requested mapping is identical, except for the backing BO, hence replace
208 * the mapping.
209 *
210 * ::
211 *
212 * 0 a 1
213 * old: |-----------| (bo_offset=n)
214 *
215 * 0 b 1
216 * req: |-----------| (bo_offset=n)
217 *
218 * 0 b 1
219 * new: |-----------| (bo_offset=n)
220 *
221 *
222 * 4) Existent mapping is a left aligned subset of the requested one, hence
223 * replace the existing one.
224 *
225 * ::
226 *
227 * 0 a 1
228 * old: |-----| (bo_offset=n)
229 *
230 * 0 a 2
231 * req: |-----------| (bo_offset=n)
232 *
233 * 0 a 2
234 * new: |-----------| (bo_offset=n)
235 *
236 * .. note::
237 * We expect to see the same result for a request with a different BO
238 * and/or non-contiguous BO offset.
239 *
240 *
241 * 5) Requested mapping's range is a left aligned subset of the existing one,
242 * but backed by a different BO. Hence, map the requested mapping and split
243 * the existing one adjusting its BO offset.
244 *
245 * ::
246 *
247 * 0 a 2
248 * old: |-----------| (bo_offset=n)
249 *
250 * 0 b 1
251 * req: |-----| (bo_offset=n)
252 *
253 * 0 b 1 a' 2
254 * new: |-----|-----| (b.bo_offset=n, a.bo_offset=n+1)
255 *
256 * .. note::
257 * We expect to see the same result for a request with a different BO
258 * and/or non-contiguous BO offset.
259 *
260 *
261 * 6) Existent mapping is a superset of the requested mapping. Split it up, but
262 * indicate that the backing PTEs could be kept.
263 *
264 * ::
265 *
266 * 0 a 2
267 * old: |-----------| (bo_offset=n)
268 *
269 * 0 a 1
270 * req: |-----| (bo_offset=n)
271 *
272 * 0 a 1 a' 2
273 * new: |-----|-----| (a.bo_offset=n, a'.bo_offset=n+1)
274 *
275 *
276 * 7) Requested mapping's range is a right aligned subset of the existing one,
277 * but backed by a different BO. Hence, map the requested mapping and split
278 * the existing one, without adjusting the BO offset.
279 *
280 * ::
281 *
282 * 0 a 2
283 * old: |-----------| (bo_offset=n)
284 *
285 * 1 b 2
286 * req: |-----| (bo_offset=m)
287 *
288 * 0 a 1 b 2
289 * new: |-----|-----| (a.bo_offset=n,b.bo_offset=m)
290 *
291 *
292 * 8) Existent mapping is a superset of the requested mapping. Split it up, but
293 * indicate that the backing PTEs could be kept.
294 *
295 * ::
296 *
297 * 0 a 2
298 * old: |-----------| (bo_offset=n)
299 *
300 * 1 a 2
301 * req: |-----| (bo_offset=n+1)
302 *
303 * 0 a' 1 a 2
304 * new: |-----|-----| (a'.bo_offset=n, a.bo_offset=n+1)
305 *
306 *
307 * 9) Existent mapping is overlapped at the end by the requested mapping backed
308 * by a different BO. Hence, map the requested mapping and split up the
309 * existing one, without adjusting the BO offset.
310 *
311 * ::
312 *
313 * 0 a 2
314 * old: |-----------| (bo_offset=n)
315 *
316 * 1 b 3
317 * req: |-----------| (bo_offset=m)
318 *
319 * 0 a 1 b 3
320 * new: |-----|-----------| (a.bo_offset=n,b.bo_offset=m)
321 *
322 *
323 * 10) Existent mapping is overlapped by the requested mapping, both having the
324 * same backing BO with a contiguous offset. Indicate the backing PTEs of
325 * the old mapping could be kept.
326 *
327 * ::
328 *
329 * 0 a 2
330 * old: |-----------| (bo_offset=n)
331 *
332 * 1 a 3
333 * req: |-----------| (bo_offset=n+1)
334 *
335 * 0 a' 1 a 3
336 * new: |-----|-----------| (a'.bo_offset=n, a.bo_offset=n+1)
337 *
338 *
339 * 11) Requested mapping's range is a centered subset of the existing one
340 * having a different backing BO. Hence, map the requested mapping and split
341 * up the existing one in two mappings, adjusting the BO offset of the right
342 * one accordingly.
343 *
344 * ::
345 *
346 * 0 a 3
347 * old: |-----------------| (bo_offset=n)
348 *
349 * 1 b 2
350 * req: |-----| (bo_offset=m)
351 *
352 * 0 a 1 b 2 a' 3
353 * new: |-----|-----|-----| (a.bo_offset=n,b.bo_offset=m,a'.bo_offset=n+2)
354 *
355 *
356 * 12) Requested mapping is a contiguous subset of the existing one. Split it
357 * up, but indicate that the backing PTEs could be kept.
358 *
359 * ::
360 *
361 * 0 a 3
362 * old: |-----------------| (bo_offset=n)
363 *
364 * 1 a 2
365 * req: |-----| (bo_offset=n+1)
366 *
367 * 0 a' 1 a 2 a'' 3
368 * old: |-----|-----|-----| (a'.bo_offset=n, a.bo_offset=n+1, a''.bo_offset=n+2)
369 *
370 *
371 * 13) Existent mapping is a right aligned subset of the requested one, hence
372 * replace the existing one.
373 *
374 * ::
375 *
376 * 1 a 2
377 * old: |-----| (bo_offset=n+1)
378 *
379 * 0 a 2
380 * req: |-----------| (bo_offset=n)
381 *
382 * 0 a 2
383 * new: |-----------| (bo_offset=n)
384 *
385 * .. note::
386 * We expect to see the same result for a request with a different bo
387 * and/or non-contiguous bo_offset.
388 *
389 *
390 * 14) Existent mapping is a centered subset of the requested one, hence
391 * replace the existing one.
392 *
393 * ::
394 *
395 * 1 a 2
396 * old: |-----| (bo_offset=n+1)
397 *
398 * 0 a 3
399 * req: |----------------| (bo_offset=n)
400 *
401 * 0 a 3
402 * new: |----------------| (bo_offset=n)
403 *
404 * .. note::
405 * We expect to see the same result for a request with a different bo
406 * and/or non-contiguous bo_offset.
407 *
408 *
409 * 15) Existent mappings is overlapped at the beginning by the requested mapping
410 * backed by a different BO. Hence, map the requested mapping and split up
411 * the existing one, adjusting its BO offset accordingly.
412 *
413 * ::
414 *
415 * 1 a 3
416 * old: |-----------| (bo_offset=n)
417 *
418 * 0 b 2
419 * req: |-----------| (bo_offset=m)
420 *
421 * 0 b 2 a' 3
422 * new: |-----------|-----| (b.bo_offset=m,a.bo_offset=n+2)
423 */
424
425/**
426 * DOC: Madvise Logic - Splitting and Traversal
427 *
428 * This logic handles GPU VA range updates by generating remap and map operations
429 * without performing unmaps or merging existing mappings.
430 *
431 * 1) The requested range lies entirely within a single drm_gpuva. The logic splits
432 * the existing mapping at the start and end boundaries and inserts a new map.
433 *
434 * ::
435 * a start end b
436 * pre: |-----------------------|
437 * drm_gpuva1
438 *
439 * a start end b
440 * new: |-----|=========|-------|
441 * remap map remap
442 *
443 * one REMAP and one MAP : Same behaviour as SPLIT and MERGE
444 *
445 * 2) The requested range spans multiple drm_gpuva regions. The logic traverses
446 * across boundaries, remapping the start and end segments, and inserting two
447 * map operations to cover the full range.
448 *
449 * :: a start b c end d
450 * pre: |------------------|--------------|------------------|
451 * drm_gpuva1 drm_gpuva2 drm_gpuva3
452 *
453 * a start b c end d
454 * new: |-------|==========|--------------|========|---------|
455 * remap1 map1 drm_gpuva2 map2 remap2
456 *
457 * two REMAPS and two MAPS
458 *
459 * 3) Either start or end lies within a drm_gpuva. A single remap and map operation
460 * are generated to update the affected portion.
461 *
462 *
463 * :: a/start b c end d
464 * pre: |------------------|--------------|------------------|
465 * drm_gpuva1 drm_gpuva2 drm_gpuva3
466 *
467 * a/start b c end d
468 * new: |------------------|--------------|========|---------|
469 * drm_gpuva1 drm_gpuva2 map1 remap1
470 *
471 * :: a start b c/end d
472 * pre: |------------------|--------------|------------------|
473 * drm_gpuva1 drm_gpuva2 drm_gpuva3
474 *
475 * a start b c/end d
476 * new: |-------|==========|--------------|------------------|
477 * remap1 map1 drm_gpuva2 drm_gpuva3
478 *
479 * one REMAP and one MAP
480 *
481 * 4) Both start and end align with existing drm_gpuva boundaries. No operations
482 * are needed as the range is already covered.
483 *
484 * 5) No existing drm_gpuvas. No operations.
485 *
486 * Unlike drm_gpuvm_sm_map_ops_create, this logic avoids unmaps and merging,
487 * focusing solely on remap and map operations for efficient traversal and update.
488 */
489
490/**
491 * DOC: Locking
492 *
493 * In terms of managing &drm_gpuva entries DRM GPUVM does not take care of
494 * locking itself, it is the drivers responsibility to take care about locking.
495 * Drivers might want to protect the following operations: inserting, removing
496 * and iterating &drm_gpuva objects as well as generating all kinds of
497 * operations, such as split / merge or prefetch.
498 *
499 * DRM GPUVM also does not take care of the locking of the backing
500 * &drm_gem_object buffers GPU VA lists and &drm_gpuvm_bo abstractions by
501 * itself; drivers are responsible to enforce mutual exclusion using either the
502 * GEMs dma_resv lock or the GEMs gpuva.lock mutex.
503 *
504 * However, DRM GPUVM contains lockdep checks to ensure callers of its API hold
505 * the corresponding lock whenever the &drm_gem_objects GPU VA list is accessed
506 * by functions such as drm_gpuva_link() or drm_gpuva_unlink(), but also
507 * drm_gpuvm_bo_obtain() and drm_gpuvm_bo_put().
508 *
509 * The latter is required since on creation and destruction of a &drm_gpuvm_bo
510 * the &drm_gpuvm_bo is attached / removed from the &drm_gem_objects gpuva list.
511 * Subsequent calls to drm_gpuvm_bo_obtain() for the same &drm_gpuvm and
512 * &drm_gem_object must be able to observe previous creations and destructions
513 * of &drm_gpuvm_bos in order to keep instances unique.
514 *
515 * The &drm_gpuvm's lists for keeping track of external and evicted objects are
516 * protected against concurrent insertion / removal and iteration internally.
517 *
518 * However, drivers still need ensure to protect concurrent calls to functions
519 * iterating those lists, namely drm_gpuvm_prepare_objects() and
520 * drm_gpuvm_validate().
521 *
522 * Alternatively, drivers can set the &DRM_GPUVM_RESV_PROTECTED flag to indicate
523 * that the corresponding &dma_resv locks are held in order to protect the
524 * lists. If &DRM_GPUVM_RESV_PROTECTED is set, internal locking is disabled and
525 * the corresponding lockdep checks are enabled. This is an optimization for
526 * drivers which are capable of taking the corresponding &dma_resv locks and
527 * hence do not require internal locking.
528 */
529
530/**
531 * DOC: Examples
532 *
533 * This section gives two examples on how to let the DRM GPUVA Manager generate
534 * &drm_gpuva_op in order to satisfy a given map or unmap request and how to
535 * make use of them.
536 *
537 * The below code is strictly limited to illustrate the generic usage pattern.
538 * To maintain simplicity, it doesn't make use of any abstractions for common
539 * code, different (asynchronous) stages with fence signalling critical paths,
540 * any other helpers or error handling in terms of freeing memory and dropping
541 * previously taken locks.
542 *
543 * 1) Obtain a list of &drm_gpuva_op to create a new mapping::
544 *
545 * // Allocates a new &drm_gpuva.
546 * struct drm_gpuva * driver_gpuva_alloc(void);
547 *
548 * // Typically drivers would embed the &drm_gpuvm and &drm_gpuva
549 * // structure in individual driver structures and lock the dma-resv with
550 * // drm_exec or similar helpers.
551 * int driver_mapping_create(struct drm_gpuvm *gpuvm,
552 * u64 addr, u64 range,
553 * struct drm_gem_object *obj, u64 offset)
554 * {
555 * struct drm_gpuvm_map_req map_req = {
556 * .map.va.addr = addr,
557 * .map.va.range = range,
558 * .map.gem.obj = obj,
559 * .map.gem.offset = offset,
560 * };
561 * struct drm_gpuva_ops *ops;
562 * struct drm_gpuva_op *op
563 * struct drm_gpuvm_bo *vm_bo;
564 *
565 * driver_lock_va_space();
566 * ops = drm_gpuvm_sm_map_ops_create(gpuvm, &map_req);
567 * if (IS_ERR(ops))
568 * return PTR_ERR(ops);
569 *
570 * vm_bo = drm_gpuvm_bo_obtain(gpuvm, obj);
571 * if (IS_ERR(vm_bo))
572 * return PTR_ERR(vm_bo);
573 *
574 * drm_gpuva_for_each_op(op, ops) {
575 * struct drm_gpuva *va;
576 *
577 * switch (op->op) {
578 * case DRM_GPUVA_OP_MAP:
579 * va = driver_gpuva_alloc();
580 * if (!va)
581 * ; // unwind previous VA space updates,
582 * // free memory and unlock
583 *
584 * driver_vm_map();
585 * drm_gpuva_map(gpuvm, va, &op->map);
586 * drm_gpuva_link(va, vm_bo);
587 *
588 * break;
589 * case DRM_GPUVA_OP_REMAP: {
590 * struct drm_gpuva *prev = NULL, *next = NULL;
591 *
592 * va = op->remap.unmap->va;
593 *
594 * if (op->remap.prev) {
595 * prev = driver_gpuva_alloc();
596 * if (!prev)
597 * ; // unwind previous VA space
598 * // updates, free memory and
599 * // unlock
600 * }
601 *
602 * if (op->remap.next) {
603 * next = driver_gpuva_alloc();
604 * if (!next)
605 * ; // unwind previous VA space
606 * // updates, free memory and
607 * // unlock
608 * }
609 *
610 * driver_vm_remap();
611 * drm_gpuva_remap(prev, next, &op->remap);
612 *
613 * if (prev)
614 * drm_gpuva_link(prev, va->vm_bo);
615 * if (next)
616 * drm_gpuva_link(next, va->vm_bo);
617 * drm_gpuva_unlink(va);
618 *
619 * break;
620 * }
621 * case DRM_GPUVA_OP_UNMAP:
622 * va = op->unmap->va;
623 *
624 * driver_vm_unmap();
625 * drm_gpuva_unlink(va);
626 * drm_gpuva_unmap(&op->unmap);
627 *
628 * break;
629 * default:
630 * break;
631 * }
632 * }
633 * drm_gpuvm_bo_put(vm_bo);
634 * driver_unlock_va_space();
635 *
636 * return 0;
637 * }
638 *
639 * 2) Receive a callback for each &drm_gpuva_op to create a new mapping::
640 *
641 * struct driver_context {
642 * struct drm_gpuvm *gpuvm;
643 * struct drm_gpuvm_bo *vm_bo;
644 * struct drm_gpuva *new_va;
645 * struct drm_gpuva *prev_va;
646 * struct drm_gpuva *next_va;
647 * };
648 *
649 * // ops to pass to drm_gpuvm_init()
650 * static const struct drm_gpuvm_ops driver_gpuvm_ops = {
651 * .sm_step_map = driver_gpuva_map,
652 * .sm_step_remap = driver_gpuva_remap,
653 * .sm_step_unmap = driver_gpuva_unmap,
654 * };
655 *
656 * // Typically drivers would embed the &drm_gpuvm and &drm_gpuva
657 * // structure in individual driver structures and lock the dma-resv with
658 * // drm_exec or similar helpers.
659 * int driver_mapping_create(struct drm_gpuvm *gpuvm,
660 * u64 addr, u64 range,
661 * struct drm_gem_object *obj, u64 offset)
662 * {
663 * struct driver_context ctx;
664 * struct drm_gpuvm_bo *vm_bo;
665 * struct drm_gpuva_ops *ops;
666 * struct drm_gpuva_op *op;
667 * int ret = 0;
668 *
669 * ctx.gpuvm = gpuvm;
670 *
671 * ctx.new_va = kzalloc(sizeof(*ctx.new_va), GFP_KERNEL);
672 * ctx.prev_va = kzalloc(sizeof(*ctx.prev_va), GFP_KERNEL);
673 * ctx.next_va = kzalloc(sizeof(*ctx.next_va), GFP_KERNEL);
674 * ctx.vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
675 * if (!ctx.new_va || !ctx.prev_va || !ctx.next_va || !vm_bo) {
676 * ret = -ENOMEM;
677 * goto out;
678 * }
679 *
680 * // Typically protected with a driver specific GEM gpuva lock
681 * // used in the fence signaling path for drm_gpuva_link() and
682 * // drm_gpuva_unlink(), hence pre-allocate.
683 * ctx.vm_bo = drm_gpuvm_bo_obtain_prealloc(ctx.vm_bo);
684 *
685 * driver_lock_va_space();
686 * ret = drm_gpuvm_sm_map(gpuvm, &ctx, addr, range, obj, offset);
687 * driver_unlock_va_space();
688 *
689 * out:
690 * drm_gpuvm_bo_put(ctx.vm_bo);
691 * kfree(ctx.new_va);
692 * kfree(ctx.prev_va);
693 * kfree(ctx.next_va);
694 * return ret;
695 * }
696 *
697 * int driver_gpuva_map(struct drm_gpuva_op *op, void *__ctx)
698 * {
699 * struct driver_context *ctx = __ctx;
700 *
701 * drm_gpuva_map(ctx->vm, ctx->new_va, &op->map);
702 *
703 * drm_gpuva_link(ctx->new_va, ctx->vm_bo);
704 *
705 * // prevent the new GPUVA from being freed in
706 * // driver_mapping_create()
707 * ctx->new_va = NULL;
708 *
709 * return 0;
710 * }
711 *
712 * int driver_gpuva_remap(struct drm_gpuva_op *op, void *__ctx)
713 * {
714 * struct driver_context *ctx = __ctx;
715 * struct drm_gpuva *va = op->remap.unmap->va;
716 *
717 * drm_gpuva_remap(ctx->prev_va, ctx->next_va, &op->remap);
718 *
719 * if (op->remap.prev) {
720 * drm_gpuva_link(ctx->prev_va, va->vm_bo);
721 * ctx->prev_va = NULL;
722 * }
723 *
724 * if (op->remap.next) {
725 * drm_gpuva_link(ctx->next_va, va->vm_bo);
726 * ctx->next_va = NULL;
727 * }
728 *
729 * drm_gpuva_unlink(va);
730 * kfree(va);
731 *
732 * return 0;
733 * }
734 *
735 * int driver_gpuva_unmap(struct drm_gpuva_op *op, void *__ctx)
736 * {
737 * drm_gpuva_unlink(op->unmap.va);
738 * drm_gpuva_unmap(&op->unmap);
739 * kfree(op->unmap.va);
740 *
741 * return 0;
742 * }
743 */
744
745/**
746 * get_next_vm_bo_from_list() - get the next vm_bo element
747 * @__gpuvm: the &drm_gpuvm
748 * @__list_name: the name of the list we're iterating on
749 * @__local_list: a pointer to the local list used to store already iterated items
750 * @__prev_vm_bo: the previous element we got from get_next_vm_bo_from_list()
751 *
752 * This helper is here to provide lockless list iteration. Lockless as in, the
753 * iterator releases the lock immediately after picking the first element from
754 * the list, so list insertion and deletion can happen concurrently.
755 *
756 * Elements popped from the original list are kept in a local list, so removal
757 * and is_empty checks can still happen while we're iterating the list.
758 */
759#define get_next_vm_bo_from_list(__gpuvm, __list_name, __local_list, __prev_vm_bo) \
760 ({ \
761 struct drm_gpuvm_bo *__vm_bo = NULL; \
762 \
763 drm_gpuvm_bo_put(__prev_vm_bo); \
764 \
765 spin_lock(&(__gpuvm)->__list_name.lock); \
766 if (!(__gpuvm)->__list_name.local_list) \
767 (__gpuvm)->__list_name.local_list = __local_list; \
768 else \
769 drm_WARN_ON((__gpuvm)->drm, \
770 (__gpuvm)->__list_name.local_list != __local_list); \
771 \
772 while (!list_empty(&(__gpuvm)->__list_name.list)) { \
773 __vm_bo = list_first_entry(&(__gpuvm)->__list_name.list, \
774 struct drm_gpuvm_bo, \
775 list.entry.__list_name); \
776 if (kref_get_unless_zero(&__vm_bo->kref)) { \
777 list_move_tail(&(__vm_bo)->list.entry.__list_name, \
778 __local_list); \
779 break; \
780 } else { \
781 list_del_init(&(__vm_bo)->list.entry.__list_name); \
782 __vm_bo = NULL; \
783 } \
784 } \
785 spin_unlock(&(__gpuvm)->__list_name.lock); \
786 \
787 __vm_bo; \
788 })
789
790/**
791 * for_each_vm_bo_in_list() - internal vm_bo list iterator
792 * @__gpuvm: the &drm_gpuvm
793 * @__list_name: the name of the list we're iterating on
794 * @__local_list: a pointer to the local list used to store already iterated items
795 * @__vm_bo: the struct drm_gpuvm_bo to assign in each iteration step
796 *
797 * This helper is here to provide lockless list iteration. Lockless as in, the
798 * iterator releases the lock immediately after picking the first element from the
799 * list, hence list insertion and deletion can happen concurrently.
800 *
801 * It is not allowed to re-assign the vm_bo pointer from inside this loop.
802 *
803 * Typical use:
804 *
805 * struct drm_gpuvm_bo *vm_bo;
806 * LIST_HEAD(my_local_list);
807 *
808 * ret = 0;
809 * for_each_vm_bo_in_list(gpuvm, <list_name>, &my_local_list, vm_bo) {
810 * ret = do_something_with_vm_bo(..., vm_bo);
811 * if (ret)
812 * break;
813 * }
814 * // Drop ref in case we break out of the loop.
815 * drm_gpuvm_bo_put(vm_bo);
816 * restore_vm_bo_list(gpuvm, <list_name>, &my_local_list);
817 *
818 *
819 * Only used for internal list iterations, not meant to be exposed to the outside
820 * world.
821 */
822#define for_each_vm_bo_in_list(__gpuvm, __list_name, __local_list, __vm_bo) \
823 for (__vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name, \
824 __local_list, NULL); \
825 __vm_bo; \
826 __vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name, \
827 __local_list, __vm_bo))
828
829static void
830__restore_vm_bo_list(struct drm_gpuvm *gpuvm, spinlock_t *lock,
831 struct list_head *list, struct list_head **local_list)
832{
833 /* Merge back the two lists, moving local list elements to the
834 * head to preserve previous ordering, in case it matters.
835 */
836 spin_lock(lock);
837 if (*local_list) {
838 list_splice(*local_list, list);
839 *local_list = NULL;
840 }
841 spin_unlock(lock);
842}
843
844/**
845 * restore_vm_bo_list() - move vm_bo elements back to their original list
846 * @__gpuvm: the &drm_gpuvm
847 * @__list_name: the name of the list we're iterating on
848 *
849 * When we're done iterating a vm_bo list, we should call restore_vm_bo_list()
850 * to restore the original state and let new iterations take place.
851 */
852#define restore_vm_bo_list(__gpuvm, __list_name) \
853 __restore_vm_bo_list((__gpuvm), &(__gpuvm)->__list_name.lock, \
854 &(__gpuvm)->__list_name.list, \
855 &(__gpuvm)->__list_name.local_list)
856
857static void
858cond_spin_lock(spinlock_t *lock, bool cond)
859{
860 if (cond)
861 spin_lock(lock);
862}
863
864static void
865cond_spin_unlock(spinlock_t *lock, bool cond)
866{
867 if (cond)
868 spin_unlock(lock);
869}
870
871static void
872__drm_gpuvm_bo_list_add(struct drm_gpuvm *gpuvm, spinlock_t *lock,
873 struct list_head *entry, struct list_head *list)
874{
875 cond_spin_lock(lock, !!lock);
876 if (list_empty(entry))
877 list_add_tail(entry, list);
878 cond_spin_unlock(lock, !!lock);
879}
880
881/**
882 * drm_gpuvm_bo_is_zombie() - check whether this vm_bo is scheduled for cleanup
883 * @vm_bo: the &drm_gpuvm_bo
884 *
885 * When a vm_bo is scheduled for cleanup using the bo_defer list, it is not
886 * immediately removed from the evict and extobj lists. Therefore, anyone
887 * iterating these lists should skip entries that are being destroyed.
888 *
889 * Checking the refcount without incrementing it is okay as long as the lock
890 * protecting the evict/extobj list is held for as long as you are using the
891 * vm_bo, because even if the refcount hits zero while you are using it, freeing
892 * the vm_bo requires taking the list's lock.
893 *
894 * Zombie entries can be observed on the evict and extobj lists regardless of
895 * whether DRM_GPUVM_RESV_PROTECTED is used, but they remain on the lists for a
896 * longer time when the resv lock is used because we can't take the resv lock
897 * during run_job() in immediate mode, meaning that they need to remain on the
898 * lists until drm_gpuvm_bo_deferred_cleanup() is called.
899 */
900static bool
901drm_gpuvm_bo_is_zombie(struct drm_gpuvm_bo *vm_bo)
902{
903 return !kref_read(&vm_bo->kref);
904}
905
906/**
907 * drm_gpuvm_bo_list_add() - insert a vm_bo into the given list
908 * @__vm_bo: the &drm_gpuvm_bo
909 * @__list_name: the name of the list to insert into
910 * @__lock: whether to lock with the internal spinlock
911 *
912 * Inserts the given @__vm_bo into the list specified by @__list_name.
913 */
914#define drm_gpuvm_bo_list_add(__vm_bo, __list_name, __lock) \
915 __drm_gpuvm_bo_list_add((__vm_bo)->vm, \
916 __lock ? &(__vm_bo)->vm->__list_name.lock : \
917 NULL, \
918 &(__vm_bo)->list.entry.__list_name, \
919 &(__vm_bo)->vm->__list_name.list)
920
921static void
922__drm_gpuvm_bo_list_del(struct drm_gpuvm *gpuvm, spinlock_t *lock,
923 struct list_head *entry, bool init)
924{
925 cond_spin_lock(lock, !!lock);
926 if (init) {
927 if (!list_empty(entry))
928 list_del_init(entry);
929 } else {
930 list_del(entry);
931 }
932 cond_spin_unlock(lock, !!lock);
933}
934
935/**
936 * drm_gpuvm_bo_list_del_init() - remove a vm_bo from the given list
937 * @__vm_bo: the &drm_gpuvm_bo
938 * @__list_name: the name of the list to insert into
939 * @__lock: whether to lock with the internal spinlock
940 *
941 * Removes the given @__vm_bo from the list specified by @__list_name.
942 */
943#define drm_gpuvm_bo_list_del_init(__vm_bo, __list_name, __lock) \
944 __drm_gpuvm_bo_list_del((__vm_bo)->vm, \
945 __lock ? &(__vm_bo)->vm->__list_name.lock : \
946 NULL, \
947 &(__vm_bo)->list.entry.__list_name, \
948 true)
949
950/**
951 * drm_gpuvm_bo_list_del() - remove a vm_bo from the given list
952 * @__vm_bo: the &drm_gpuvm_bo
953 * @__list_name: the name of the list to insert into
954 * @__lock: whether to lock with the internal spinlock
955 *
956 * Removes the given @__vm_bo from the list specified by @__list_name.
957 */
958#define drm_gpuvm_bo_list_del(__vm_bo, __list_name, __lock) \
959 __drm_gpuvm_bo_list_del((__vm_bo)->vm, \
960 __lock ? &(__vm_bo)->vm->__list_name.lock : \
961 NULL, \
962 &(__vm_bo)->list.entry.__list_name, \
963 false)
964
965#define to_drm_gpuva(__node) container_of((__node), struct drm_gpuva, rb.node)
966
967#define GPUVA_START(node) ((node)->va.addr)
968#define GPUVA_LAST(node) ((node)->va.addr + (node)->va.range - 1)
969
970/* We do not actually use drm_gpuva_it_next(), tell the compiler to not complain
971 * about this.
972 */
973INTERVAL_TREE_DEFINE(struct drm_gpuva, rb.node, u64, rb.__subtree_last,
974 GPUVA_START, GPUVA_LAST, static __maybe_unused,
975 drm_gpuva_it)
976
977static int __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
978 struct drm_gpuva *va);
979static void __drm_gpuva_remove(struct drm_gpuva *va);
980
981static bool
982drm_gpuvm_check_overflow(u64 addr, u64 range)
983{
984 u64 end;
985
986 return check_add_overflow(addr, range, &end);
987}
988
989static bool
990drm_gpuvm_warn_check_overflow(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
991{
992 return drm_WARN(gpuvm->drm, drm_gpuvm_check_overflow(addr, range),
993 "GPUVA address limited to %zu bytes.\n", sizeof(addr));
994}
995
996static bool
997drm_gpuvm_in_mm_range(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
998{
999 u64 end = addr + range;
1000 u64 mm_start = gpuvm->mm_start;
1001 u64 mm_end = mm_start + gpuvm->mm_range;
1002
1003 return addr >= mm_start && end <= mm_end;
1004}
1005
1006static bool
1007drm_gpuvm_in_kernel_node(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
1008{
1009 u64 end = addr + range;
1010 u64 kstart = gpuvm->kernel_alloc_node.va.addr;
1011 u64 krange = gpuvm->kernel_alloc_node.va.range;
1012 u64 kend = kstart + krange;
1013
1014 return krange && addr < kend && kstart < end;
1015}
1016
1017/**
1018 * drm_gpuvm_range_valid() - checks whether the given range is valid for the
1019 * given &drm_gpuvm
1020 * @gpuvm: the GPUVM to check the range for
1021 * @addr: the base address
1022 * @range: the range starting from the base address
1023 *
1024 * Checks whether the range is within the GPUVM's managed boundaries.
1025 *
1026 * Returns: true for a valid range, false otherwise
1027 */
1028bool
1029drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
1030 u64 addr, u64 range)
1031{
1032 return !drm_gpuvm_check_overflow(addr, range) &&
1033 drm_gpuvm_in_mm_range(gpuvm, addr, range) &&
1034 !drm_gpuvm_in_kernel_node(gpuvm, addr, range);
1035}
1036EXPORT_SYMBOL_GPL(drm_gpuvm_range_valid);
1037
1038static void
1039drm_gpuvm_gem_object_free(struct drm_gem_object *obj)
1040{
1041 drm_gem_object_release(obj);
1042 kfree(obj);
1043}
1044
1045static const struct drm_gem_object_funcs drm_gpuvm_object_funcs = {
1046 .free = drm_gpuvm_gem_object_free,
1047};
1048
1049/**
1050 * drm_gpuvm_resv_object_alloc() - allocate a dummy &drm_gem_object
1051 * @drm: the drivers &drm_device
1052 *
1053 * Allocates a dummy &drm_gem_object which can be passed to drm_gpuvm_init() in
1054 * order to serve as root GEM object providing the &drm_resv shared across
1055 * &drm_gem_objects local to a single GPUVM.
1056 *
1057 * Returns: the &drm_gem_object on success, NULL on failure
1058 */
1059struct drm_gem_object *
1060drm_gpuvm_resv_object_alloc(struct drm_device *drm)
1061{
1062 struct drm_gem_object *obj;
1063
1064 obj = kzalloc_obj(*obj);
1065 if (!obj)
1066 return NULL;
1067
1068 obj->funcs = &drm_gpuvm_object_funcs;
1069 drm_gem_private_object_init(drm, obj, 0);
1070
1071 return obj;
1072}
1073EXPORT_SYMBOL_GPL(drm_gpuvm_resv_object_alloc);
1074
1075/**
1076 * drm_gpuvm_init() - initialize a &drm_gpuvm
1077 * @gpuvm: pointer to the &drm_gpuvm to initialize
1078 * @name: the name of the GPU VA space
1079 * @flags: the &drm_gpuvm_flags for this GPUVM
1080 * @drm: the &drm_device this VM resides in
1081 * @r_obj: the resv &drm_gem_object providing the GPUVM's common &dma_resv
1082 * @start_offset: the start offset of the GPU VA space
1083 * @range: the size of the GPU VA space
1084 * @reserve_offset: the start of the kernel reserved GPU VA area
1085 * @reserve_range: the size of the kernel reserved GPU VA area
1086 * @ops: &drm_gpuvm_ops called on &drm_gpuvm_sm_map / &drm_gpuvm_sm_unmap
1087 *
1088 * The &drm_gpuvm must be initialized with this function before use.
1089 *
1090 * Note that @gpuvm must be cleared to 0 before calling this function. The given
1091 * &name is expected to be managed by the surrounding driver structures.
1092 */
1093void
1094drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
1095 enum drm_gpuvm_flags flags,
1096 struct drm_device *drm,
1097 struct drm_gem_object *r_obj,
1098 u64 start_offset, u64 range,
1099 u64 reserve_offset, u64 reserve_range,
1100 const struct drm_gpuvm_ops *ops)
1101{
1102 gpuvm->rb.tree = RB_ROOT_CACHED;
1103 INIT_LIST_HEAD(&gpuvm->rb.list);
1104
1105 INIT_LIST_HEAD(&gpuvm->extobj.list);
1106 spin_lock_init(&gpuvm->extobj.lock);
1107
1108 INIT_LIST_HEAD(&gpuvm->evict.list);
1109 spin_lock_init(&gpuvm->evict.lock);
1110
1111 init_llist_head(&gpuvm->bo_defer);
1112
1113 kref_init(&gpuvm->kref);
1114
1115 gpuvm->name = name ? name : "unknown";
1116 gpuvm->flags = flags;
1117 gpuvm->ops = ops;
1118 gpuvm->drm = drm;
1119 gpuvm->r_obj = r_obj;
1120
1121 drm_dev_get(drm);
1122 drm_gem_object_get(r_obj);
1123
1124 drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range);
1125 gpuvm->mm_start = start_offset;
1126 gpuvm->mm_range = range;
1127
1128 memset(&gpuvm->kernel_alloc_node, 0, sizeof(struct drm_gpuva));
1129 if (reserve_range) {
1130 gpuvm->kernel_alloc_node.va.addr = reserve_offset;
1131 gpuvm->kernel_alloc_node.va.range = reserve_range;
1132
1133 if (likely(!drm_gpuvm_warn_check_overflow(gpuvm, reserve_offset,
1134 reserve_range)))
1135 __drm_gpuva_insert(gpuvm, &gpuvm->kernel_alloc_node);
1136 }
1137}
1138EXPORT_SYMBOL_GPL(drm_gpuvm_init);
1139
1140static void
1141drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
1142{
1143 gpuvm->name = NULL;
1144
1145 if (gpuvm->kernel_alloc_node.va.range)
1146 __drm_gpuva_remove(&gpuvm->kernel_alloc_node);
1147
1148 drm_WARN(gpuvm->drm, !RB_EMPTY_ROOT(&gpuvm->rb.tree.rb_root),
1149 "GPUVA tree is not empty, potentially leaking memory.\n");
1150
1151 drm_WARN(gpuvm->drm, !list_empty(&gpuvm->extobj.list),
1152 "Extobj list should be empty.\n");
1153 drm_WARN(gpuvm->drm, !list_empty(&gpuvm->evict.list),
1154 "Evict list should be empty.\n");
1155 drm_WARN(gpuvm->drm, !llist_empty(&gpuvm->bo_defer),
1156 "VM BO cleanup list should be empty.\n");
1157
1158 drm_gem_object_put(gpuvm->r_obj);
1159}
1160
1161static void
1162drm_gpuvm_free(struct kref *kref)
1163{
1164 struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref);
1165 struct drm_device *drm = gpuvm->drm;
1166
1167 drm_gpuvm_fini(gpuvm);
1168
1169 if (drm_WARN_ON(drm, !gpuvm->ops->vm_free))
1170 return;
1171
1172 gpuvm->ops->vm_free(gpuvm);
1173 drm_dev_put(drm);
1174}
1175
1176/**
1177 * drm_gpuvm_put() - drop a struct drm_gpuvm reference
1178 * @gpuvm: the &drm_gpuvm to release the reference of
1179 *
1180 * This releases a reference to @gpuvm.
1181 *
1182 * This function may be called from atomic context.
1183 */
1184void
1185drm_gpuvm_put(struct drm_gpuvm *gpuvm)
1186{
1187 if (gpuvm)
1188 kref_put(&gpuvm->kref, drm_gpuvm_free);
1189}
1190EXPORT_SYMBOL_GPL(drm_gpuvm_put);
1191
1192static int
1193exec_prepare_obj(struct drm_exec *exec, struct drm_gem_object *obj,
1194 unsigned int num_fences)
1195{
1196 return num_fences ? drm_exec_prepare_obj(exec, obj, num_fences) :
1197 drm_exec_lock_obj(exec, obj);
1198}
1199
1200/**
1201 * drm_gpuvm_prepare_vm() - prepare the GPUVMs common dma-resv
1202 * @gpuvm: the &drm_gpuvm
1203 * @exec: the &drm_exec context
1204 * @num_fences: the amount of &dma_fences to reserve
1205 *
1206 * Calls drm_exec_prepare_obj() for the GPUVMs dummy &drm_gem_object; if
1207 * @num_fences is zero drm_exec_lock_obj() is called instead.
1208 *
1209 * Using this function directly, it is the drivers responsibility to call
1210 * drm_exec_init() and drm_exec_fini() accordingly.
1211 *
1212 * Returns: 0 on success, negative error code on failure.
1213 */
1214int
1215drm_gpuvm_prepare_vm(struct drm_gpuvm *gpuvm,
1216 struct drm_exec *exec,
1217 unsigned int num_fences)
1218{
1219 return exec_prepare_obj(exec, gpuvm->r_obj, num_fences);
1220}
1221EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_vm);
1222
1223static int
1224__drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1225 struct drm_exec *exec,
1226 unsigned int num_fences)
1227{
1228 struct drm_gpuvm_bo *vm_bo;
1229 LIST_HEAD(extobjs);
1230 int ret = 0;
1231
1232 for_each_vm_bo_in_list(gpuvm, extobj, &extobjs, vm_bo) {
1233 ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
1234 if (ret)
1235 break;
1236 }
1237 /* Drop ref in case we break out of the loop. */
1238 drm_gpuvm_bo_put(vm_bo);
1239 restore_vm_bo_list(gpuvm, extobj);
1240
1241 return ret;
1242}
1243
1244static int
1245drm_gpuvm_prepare_objects_locked(struct drm_gpuvm *gpuvm,
1246 struct drm_exec *exec,
1247 unsigned int num_fences)
1248{
1249 struct drm_gpuvm_bo *vm_bo;
1250 int ret = 0;
1251
1252 drm_gpuvm_resv_assert_held(gpuvm);
1253 list_for_each_entry(vm_bo, &gpuvm->extobj.list, list.entry.extobj) {
1254 if (drm_gpuvm_bo_is_zombie(vm_bo))
1255 continue;
1256
1257 ret = exec_prepare_obj(exec, vm_bo->obj, num_fences);
1258 if (ret)
1259 break;
1260
1261 if (vm_bo->evicted)
1262 drm_gpuvm_bo_list_add(vm_bo, evict, false);
1263 }
1264
1265 return ret;
1266}
1267
1268/**
1269 * drm_gpuvm_prepare_objects() - prepare all associated BOs
1270 * @gpuvm: the &drm_gpuvm
1271 * @exec: the &drm_exec locking context
1272 * @num_fences: the amount of &dma_fences to reserve
1273 *
1274 * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given
1275 * &drm_gpuvm contains mappings of; if @num_fences is zero drm_exec_lock_obj()
1276 * is called instead.
1277 *
1278 * Using this function directly, it is the drivers responsibility to call
1279 * drm_exec_init() and drm_exec_fini() accordingly.
1280 *
1281 * Note: This function is safe against concurrent insertion and removal of
1282 * external objects, however it is not safe against concurrent usage itself.
1283 *
1284 * Drivers need to make sure to protect this case with either an outer VM lock
1285 * or by calling drm_gpuvm_prepare_vm() before this function within the
1286 * drm_exec_until_all_locked() loop, such that the GPUVM's dma-resv lock ensures
1287 * mutual exclusion.
1288 *
1289 * Returns: 0 on success, negative error code on failure.
1290 */
1291int
1292drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1293 struct drm_exec *exec,
1294 unsigned int num_fences)
1295{
1296 if (drm_gpuvm_resv_protected(gpuvm))
1297 return drm_gpuvm_prepare_objects_locked(gpuvm, exec,
1298 num_fences);
1299 else
1300 return __drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1301}
1302EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_objects);
1303
1304/**
1305 * drm_gpuvm_prepare_range() - prepare all BOs mapped within a given range
1306 * @gpuvm: the &drm_gpuvm
1307 * @exec: the &drm_exec locking context
1308 * @addr: the start address within the VA space
1309 * @range: the range to iterate within the VA space
1310 * @num_fences: the amount of &dma_fences to reserve
1311 *
1312 * Calls drm_exec_prepare_obj() for all &drm_gem_objects mapped between @addr
1313 * and @addr + @range; if @num_fences is zero drm_exec_lock_obj() is called
1314 * instead.
1315 *
1316 * Returns: 0 on success, negative error code on failure.
1317 */
1318int
1319drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm, struct drm_exec *exec,
1320 u64 addr, u64 range, unsigned int num_fences)
1321{
1322 struct drm_gpuva *va;
1323 u64 end = addr + range;
1324 int ret;
1325
1326 drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
1327 struct drm_gem_object *obj = va->gem.obj;
1328
1329 if (unlikely(!obj))
1330 continue;
1331
1332 ret = exec_prepare_obj(exec, obj, num_fences);
1333 if (ret)
1334 return ret;
1335 }
1336
1337 return 0;
1338}
1339EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_range);
1340
1341/**
1342 * drm_gpuvm_exec_lock() - lock all dma-resv of all associated BOs
1343 * @vm_exec: the &drm_gpuvm_exec wrapper
1344 *
1345 * Acquires all dma-resv locks of all &drm_gem_objects the given
1346 * &drm_gpuvm contains mappings of.
1347 *
1348 * Additionally, when calling this function with struct drm_gpuvm_exec::extra
1349 * being set the driver receives the given @fn callback to lock additional
1350 * dma-resv in the context of the &drm_gpuvm_exec instance. Typically, drivers
1351 * would call drm_exec_prepare_obj() from within this callback.
1352 *
1353 * Returns: 0 on success, negative error code on failure.
1354 */
1355int
1356drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
1357{
1358 struct drm_gpuvm *gpuvm = vm_exec->vm;
1359 struct drm_exec *exec = &vm_exec->exec;
1360 unsigned int num_fences = vm_exec->num_fences;
1361 int ret;
1362
1363 drm_exec_init(exec, vm_exec->flags, 0);
1364
1365 drm_exec_until_all_locked(exec) {
1366 ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
1367 drm_exec_retry_on_contention(exec);
1368 if (ret)
1369 goto err;
1370
1371 ret = drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1372 drm_exec_retry_on_contention(exec);
1373 if (ret)
1374 goto err;
1375
1376 if (vm_exec->extra.fn) {
1377 ret = vm_exec->extra.fn(vm_exec);
1378 drm_exec_retry_on_contention(exec);
1379 if (ret)
1380 goto err;
1381 }
1382 }
1383
1384 return 0;
1385
1386err:
1387 drm_exec_fini(exec);
1388 return ret;
1389}
1390EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock);
1391
1392static int
1393fn_lock_array(struct drm_gpuvm_exec *vm_exec)
1394{
1395 struct {
1396 struct drm_gem_object **objs;
1397 unsigned int num_objs;
1398 } *args = vm_exec->extra.priv;
1399
1400 return drm_exec_prepare_array(&vm_exec->exec, args->objs,
1401 args->num_objs, vm_exec->num_fences);
1402}
1403
1404/**
1405 * drm_gpuvm_exec_lock_array() - lock all dma-resv of all associated BOs
1406 * @vm_exec: the &drm_gpuvm_exec wrapper
1407 * @objs: additional &drm_gem_objects to lock
1408 * @num_objs: the number of additional &drm_gem_objects to lock
1409 *
1410 * Acquires all dma-resv locks of all &drm_gem_objects the given &drm_gpuvm
1411 * contains mappings of, plus the ones given through @objs.
1412 *
1413 * Returns: 0 on success, negative error code on failure.
1414 */
1415int
1416drm_gpuvm_exec_lock_array(struct drm_gpuvm_exec *vm_exec,
1417 struct drm_gem_object **objs,
1418 unsigned int num_objs)
1419{
1420 struct {
1421 struct drm_gem_object **objs;
1422 unsigned int num_objs;
1423 } args;
1424
1425 args.objs = objs;
1426 args.num_objs = num_objs;
1427
1428 vm_exec->extra.fn = fn_lock_array;
1429 vm_exec->extra.priv = &args;
1430
1431 return drm_gpuvm_exec_lock(vm_exec);
1432}
1433EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_array);
1434
1435/**
1436 * drm_gpuvm_exec_lock_range() - prepare all BOs mapped within a given range
1437 * @vm_exec: the &drm_gpuvm_exec wrapper
1438 * @addr: the start address within the VA space
1439 * @range: the range to iterate within the VA space
1440 *
1441 * Acquires all dma-resv locks of all &drm_gem_objects mapped between @addr and
1442 * @addr + @range.
1443 *
1444 * Returns: 0 on success, negative error code on failure.
1445 */
1446int
1447drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
1448 u64 addr, u64 range)
1449{
1450 struct drm_gpuvm *gpuvm = vm_exec->vm;
1451 struct drm_exec *exec = &vm_exec->exec;
1452 int ret;
1453
1454 drm_exec_init(exec, vm_exec->flags, 0);
1455
1456 drm_exec_until_all_locked(exec) {
1457 ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
1458 vm_exec->num_fences);
1459 drm_exec_retry_on_contention(exec);
1460 if (ret)
1461 goto err;
1462 }
1463
1464 return ret;
1465
1466err:
1467 drm_exec_fini(exec);
1468 return ret;
1469}
1470EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_range);
1471
1472static int
1473__drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1474{
1475 const struct drm_gpuvm_ops *ops = gpuvm->ops;
1476 struct drm_gpuvm_bo *vm_bo;
1477 LIST_HEAD(evict);
1478 int ret = 0;
1479
1480 for_each_vm_bo_in_list(gpuvm, evict, &evict, vm_bo) {
1481 ret = ops->vm_bo_validate(vm_bo, exec);
1482 if (ret)
1483 break;
1484 }
1485 /* Drop ref in case we break out of the loop. */
1486 drm_gpuvm_bo_put(vm_bo);
1487 restore_vm_bo_list(gpuvm, evict);
1488
1489 return ret;
1490}
1491
1492static int
1493drm_gpuvm_validate_locked(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1494{
1495 const struct drm_gpuvm_ops *ops = gpuvm->ops;
1496 struct drm_gpuvm_bo *vm_bo, *next;
1497 int ret = 0;
1498
1499 drm_gpuvm_resv_assert_held(gpuvm);
1500
1501 list_for_each_entry_safe(vm_bo, next, &gpuvm->evict.list,
1502 list.entry.evict) {
1503 if (drm_gpuvm_bo_is_zombie(vm_bo))
1504 continue;
1505
1506 ret = ops->vm_bo_validate(vm_bo, exec);
1507 if (ret)
1508 break;
1509
1510 dma_resv_assert_held(vm_bo->obj->resv);
1511 if (!vm_bo->evicted)
1512 drm_gpuvm_bo_list_del_init(vm_bo, evict, false);
1513 }
1514
1515 return ret;
1516}
1517
1518/**
1519 * drm_gpuvm_validate() - validate all BOs marked as evicted
1520 * @gpuvm: the &drm_gpuvm to validate evicted BOs
1521 * @exec: the &drm_exec instance used for locking the GPUVM
1522 *
1523 * Calls the &drm_gpuvm_ops::vm_bo_validate callback for all evicted buffer
1524 * objects being mapped in the given &drm_gpuvm.
1525 *
1526 * Returns: 0 on success, negative error code on failure.
1527 */
1528int
1529drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1530{
1531 const struct drm_gpuvm_ops *ops = gpuvm->ops;
1532
1533 if (unlikely(!ops || !ops->vm_bo_validate))
1534 return -EOPNOTSUPP;
1535
1536 if (drm_gpuvm_resv_protected(gpuvm))
1537 return drm_gpuvm_validate_locked(gpuvm, exec);
1538 else
1539 return __drm_gpuvm_validate(gpuvm, exec);
1540}
1541EXPORT_SYMBOL_GPL(drm_gpuvm_validate);
1542
1543/**
1544 * drm_gpuvm_resv_add_fence - add fence to private and all extobj
1545 * dma-resv
1546 * @gpuvm: the &drm_gpuvm to add a fence to
1547 * @exec: the &drm_exec locking context
1548 * @fence: fence to add
1549 * @private_usage: private dma-resv usage
1550 * @extobj_usage: extobj dma-resv usage
1551 */
1552void
1553drm_gpuvm_resv_add_fence(struct drm_gpuvm *gpuvm,
1554 struct drm_exec *exec,
1555 struct dma_fence *fence,
1556 enum dma_resv_usage private_usage,
1557 enum dma_resv_usage extobj_usage)
1558{
1559 struct drm_gem_object *obj;
1560
1561 drm_exec_for_each_locked_object(exec, obj) {
1562 dma_resv_assert_held(obj->resv);
1563 dma_resv_add_fence(obj->resv, fence,
1564 drm_gpuvm_is_extobj(gpuvm, obj) ?
1565 extobj_usage : private_usage);
1566 }
1567}
1568EXPORT_SYMBOL_GPL(drm_gpuvm_resv_add_fence);
1569
1570/**
1571 * drm_gpuvm_bo_create() - create a new instance of struct drm_gpuvm_bo
1572 * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1573 * @obj: The &drm_gem_object being mapped in the @gpuvm.
1574 *
1575 * If provided by the driver, this function uses the &drm_gpuvm_ops
1576 * vm_bo_alloc() callback to allocate.
1577 *
1578 * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1579 */
1580struct drm_gpuvm_bo *
1581drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
1582 struct drm_gem_object *obj)
1583{
1584 const struct drm_gpuvm_ops *ops = gpuvm->ops;
1585 struct drm_gpuvm_bo *vm_bo;
1586
1587 if (ops && ops->vm_bo_alloc)
1588 vm_bo = ops->vm_bo_alloc();
1589 else
1590 vm_bo = kzalloc_obj(*vm_bo);
1591
1592 if (unlikely(!vm_bo))
1593 return NULL;
1594
1595 vm_bo->vm = drm_gpuvm_get(gpuvm);
1596 vm_bo->obj = obj;
1597 drm_gem_object_get(obj);
1598
1599 kref_init(&vm_bo->kref);
1600 INIT_LIST_HEAD(&vm_bo->list.gpuva);
1601 INIT_LIST_HEAD(&vm_bo->list.entry.gem);
1602
1603 INIT_LIST_HEAD(&vm_bo->list.entry.extobj);
1604 INIT_LIST_HEAD(&vm_bo->list.entry.evict);
1605 init_llist_node(&vm_bo->list.entry.bo_defer);
1606
1607 return vm_bo;
1608}
1609EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create);
1610
1611/*
1612 * drm_gpuvm_bo_destroy_not_in_lists() - final part of drm_gpuvm_bo cleanup
1613 * @vm_bo: the &drm_gpuvm_bo to destroy
1614 *
1615 * It is illegal to call this method if the @vm_bo is present in the GEMs gpuva
1616 * list, the extobj list, or the evicted list.
1617 *
1618 * Note that this puts a refcount on the GEM object, which may destroy the GEM
1619 * object if the refcount reaches zero. It's illegal for this to happen if the
1620 * caller holds the GEMs gpuva mutex because it would free the mutex.
1621 */
1622static void
1623drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo)
1624{
1625 struct drm_gpuvm *gpuvm = vm_bo->vm;
1626 const struct drm_gpuvm_ops *ops = gpuvm->ops;
1627 struct drm_gem_object *obj = vm_bo->obj;
1628
1629 if (ops && ops->vm_bo_free)
1630 ops->vm_bo_free(vm_bo);
1631 else
1632 kfree(vm_bo);
1633
1634 drm_gpuvm_put(gpuvm);
1635 drm_gem_object_put(obj);
1636}
1637
1638static void
1639drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref)
1640{
1641 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1642 kref);
1643
1644 drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
1645}
1646
1647static void
1648drm_gpuvm_bo_destroy(struct kref *kref)
1649{
1650 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1651 kref);
1652 struct drm_gpuvm *gpuvm = vm_bo->vm;
1653 bool lock = !drm_gpuvm_resv_protected(gpuvm);
1654
1655 if (!lock)
1656 drm_gpuvm_resv_assert_held(gpuvm);
1657
1658 drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
1659 drm_gpuvm_bo_list_del(vm_bo, evict, lock);
1660
1661 drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj);
1662 list_del(&vm_bo->list.entry.gem);
1663
1664 drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
1665}
1666
1667/**
1668 * drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference
1669 * @vm_bo: the &drm_gpuvm_bo to release the reference of
1670 *
1671 * This releases a reference to @vm_bo.
1672 *
1673 * If the reference count drops to zero, the &gpuvm_bo is destroyed, which
1674 * includes removing it from the GEMs gpuva list. Hence, if a call to this
1675 * function can potentially let the reference count drop to zero the caller must
1676 * hold the lock that the GEM uses for its gpuva list (either the GEM's
1677 * dma-resv or gpuva.lock mutex).
1678 *
1679 * This function may only be called from non-atomic context.
1680 *
1681 * Returns: true if vm_bo was destroyed, false otherwise.
1682 */
1683bool
1684drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo)
1685{
1686 might_sleep();
1687
1688 if (vm_bo)
1689 return !!kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy);
1690
1691 return false;
1692}
1693EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put);
1694
1695/*
1696 * drm_gpuvm_bo_into_zombie() - called when the vm_bo becomes a zombie due to
1697 * deferred cleanup
1698 *
1699 * If deferred cleanup is used, then this must be called right after the vm_bo
1700 * refcount drops to zero. Must be called with GEM mutex held. After releasing
1701 * the GEM mutex, drm_gpuvm_bo_defer_zombie_cleanup() must be called.
1702 */
1703static void
1704drm_gpuvm_bo_into_zombie(struct kref *kref)
1705{
1706 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1707 kref);
1708
1709 if (!drm_gpuvm_resv_protected(vm_bo->vm)) {
1710 drm_gpuvm_bo_list_del(vm_bo, extobj, true);
1711 drm_gpuvm_bo_list_del(vm_bo, evict, true);
1712 }
1713
1714 list_del(&vm_bo->list.entry.gem);
1715}
1716
1717/*
1718 * drm_gpuvm_bo_defer_zombie_cleanup() - adds a new zombie vm_bo to the
1719 * bo_defer list
1720 *
1721 * Called after drm_gpuvm_bo_into_zombie(). GEM mutex must not be held.
1722 *
1723 * It's important that the GEM stays alive for the duration in which we hold
1724 * the mutex, but the instant we add the vm_bo to bo_defer, another thread
1725 * might call drm_gpuvm_bo_deferred_cleanup() and put the GEM. Therefore, to
1726 * avoid kfreeing a mutex we are holding, the GEM mutex must be released
1727 * *before* calling this function.
1728 */
1729static void
1730drm_gpuvm_bo_defer_zombie_cleanup(struct drm_gpuvm_bo *vm_bo)
1731{
1732 llist_add(&vm_bo->list.entry.bo_defer, &vm_bo->vm->bo_defer);
1733}
1734
1735static void
1736drm_gpuvm_bo_defer_free(struct kref *kref)
1737{
1738 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1739 kref);
1740
1741 drm_gpuvm_bo_into_zombie(kref);
1742 mutex_unlock(&vm_bo->obj->gpuva.lock);
1743 drm_gpuvm_bo_defer_zombie_cleanup(vm_bo);
1744}
1745
1746/**
1747 * drm_gpuvm_bo_put_deferred() - drop a struct drm_gpuvm_bo reference with
1748 * deferred cleanup
1749 * @vm_bo: the &drm_gpuvm_bo to release the reference of
1750 *
1751 * This releases a reference to @vm_bo.
1752 *
1753 * This might take and release the GEMs GPUVA lock. You should call
1754 * drm_gpuvm_bo_deferred_cleanup() later to complete the cleanup process.
1755 *
1756 * Returns: true if vm_bo is being destroyed, false otherwise.
1757 */
1758bool
1759drm_gpuvm_bo_put_deferred(struct drm_gpuvm_bo *vm_bo)
1760{
1761 if (!vm_bo)
1762 return false;
1763
1764 drm_WARN_ON(vm_bo->vm->drm, !drm_gpuvm_immediate_mode(vm_bo->vm));
1765
1766 return !!kref_put_mutex(&vm_bo->kref,
1767 drm_gpuvm_bo_defer_free,
1768 &vm_bo->obj->gpuva.lock);
1769}
1770EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put_deferred);
1771
1772/**
1773 * drm_gpuvm_bo_deferred_cleanup() - clean up BOs in the deferred list
1774 * deferred cleanup
1775 * @gpuvm: the VM to clean up
1776 *
1777 * Cleans up &drm_gpuvm_bo instances in the deferred cleanup list.
1778 */
1779void
1780drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm)
1781{
1782 struct drm_gpuvm_bo *vm_bo;
1783 struct llist_node *bo_defer;
1784
1785 bo_defer = llist_del_all(&gpuvm->bo_defer);
1786 if (!bo_defer)
1787 return;
1788
1789 if (drm_gpuvm_resv_protected(gpuvm)) {
1790 dma_resv_lock(drm_gpuvm_resv(gpuvm), NULL);
1791 llist_for_each_entry(vm_bo, bo_defer, list.entry.bo_defer) {
1792 drm_gpuvm_bo_list_del(vm_bo, extobj, false);
1793 drm_gpuvm_bo_list_del(vm_bo, evict, false);
1794 }
1795 dma_resv_unlock(drm_gpuvm_resv(gpuvm));
1796 }
1797
1798 while (bo_defer) {
1799 vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer);
1800 bo_defer = bo_defer->next;
1801 drm_gpuvm_bo_destroy_not_in_lists(vm_bo);
1802 }
1803}
1804EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup);
1805
1806static struct drm_gpuvm_bo *
1807__drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1808 struct drm_gem_object *obj)
1809{
1810 struct drm_gpuvm_bo *vm_bo;
1811
1812 drm_gem_gpuva_assert_lock_held(gpuvm, obj);
1813 drm_gem_for_each_gpuvm_bo(vm_bo, obj)
1814 if (vm_bo->vm == gpuvm)
1815 return vm_bo;
1816
1817 return NULL;
1818}
1819
1820/**
1821 * drm_gpuvm_bo_find() - find the &drm_gpuvm_bo for the given
1822 * &drm_gpuvm and &drm_gem_object
1823 * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1824 * @obj: The &drm_gem_object being mapped in the @gpuvm.
1825 *
1826 * Find the &drm_gpuvm_bo representing the combination of the given
1827 * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1828 * count of the &drm_gpuvm_bo accordingly.
1829 *
1830 * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1831 */
1832struct drm_gpuvm_bo *
1833drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1834 struct drm_gem_object *obj)
1835{
1836 struct drm_gpuvm_bo *vm_bo = __drm_gpuvm_bo_find(gpuvm, obj);
1837
1838 return vm_bo ? drm_gpuvm_bo_get(vm_bo) : NULL;
1839}
1840EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find);
1841
1842/**
1843 * drm_gpuvm_bo_obtain_locked() - obtains an instance of the &drm_gpuvm_bo for
1844 * the given &drm_gpuvm and &drm_gem_object
1845 * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1846 * @obj: The &drm_gem_object being mapped in the @gpuvm.
1847 *
1848 * Find the &drm_gpuvm_bo representing the combination of the given
1849 * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1850 * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new
1851 * &drm_gpuvm_bo.
1852 *
1853 * Requires the lock for the GEMs gpuva list.
1854 *
1855 * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1856 *
1857 * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure
1858 */
1859struct drm_gpuvm_bo *
1860drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm,
1861 struct drm_gem_object *obj)
1862{
1863 struct drm_gpuvm_bo *vm_bo;
1864
1865 /*
1866 * In immediate mode this would require the caller to hold the GEMs
1867 * gpuva mutex, but it's not okay to allocate while holding that lock,
1868 * and this method allocates. Immediate mode drivers should use
1869 * drm_gpuvm_bo_obtain_prealloc() instead.
1870 */
1871 drm_WARN_ON(gpuvm->drm, drm_gpuvm_immediate_mode(gpuvm));
1872
1873 vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1874 if (vm_bo)
1875 return vm_bo;
1876
1877 vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
1878 if (!vm_bo)
1879 return ERR_PTR(-ENOMEM);
1880
1881 drm_gem_gpuva_assert_lock_held(gpuvm, obj);
1882 list_add_tail(&vm_bo->list.entry.gem, &obj->gpuva.list);
1883
1884 return vm_bo;
1885}
1886EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_locked);
1887
1888/**
1889 * drm_gpuvm_bo_obtain_prealloc() - obtains an instance of the &drm_gpuvm_bo
1890 * for the given &drm_gpuvm and &drm_gem_object
1891 * @__vm_bo: A pre-allocated struct drm_gpuvm_bo.
1892 *
1893 * Find the &drm_gpuvm_bo representing the combination of the given
1894 * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1895 * count of the found &drm_gpuvm_bo accordingly, while the @__vm_bo reference
1896 * count is decreased. If not found @__vm_bo is returned without further
1897 * increase of the reference count.
1898 *
1899 * The provided @__vm_bo must not already be in the gpuva, evict, or extobj
1900 * lists prior to calling this method.
1901 *
1902 * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1903 *
1904 * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing
1905 * &drm_gpuvm_bo was found
1906 */
1907struct drm_gpuvm_bo *
1908drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo)
1909{
1910 struct drm_gpuvm *gpuvm = __vm_bo->vm;
1911 struct drm_gem_object *obj = __vm_bo->obj;
1912 struct drm_gpuvm_bo *vm_bo;
1913
1914 drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm));
1915
1916 mutex_lock(&obj->gpuva.lock);
1917 vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1918 if (vm_bo) {
1919 mutex_unlock(&obj->gpuva.lock);
1920 kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref);
1921 return vm_bo;
1922 }
1923
1924 drm_gem_gpuva_assert_lock_held(gpuvm, obj);
1925 list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list);
1926 mutex_unlock(&obj->gpuva.lock);
1927
1928 return __vm_bo;
1929}
1930EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_prealloc);
1931
1932/**
1933 * drm_gpuvm_bo_extobj_add() - adds the &drm_gpuvm_bo to its &drm_gpuvm's
1934 * extobj list
1935 * @vm_bo: The &drm_gpuvm_bo to add to its &drm_gpuvm's the extobj list.
1936 *
1937 * Adds the given @vm_bo to its &drm_gpuvm's extobj list if not on the list
1938 * already and if the corresponding &drm_gem_object is an external object,
1939 * actually.
1940 */
1941void
1942drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo)
1943{
1944 struct drm_gpuvm *gpuvm = vm_bo->vm;
1945 bool lock = !drm_gpuvm_resv_protected(gpuvm);
1946
1947 if (!lock)
1948 drm_gpuvm_resv_assert_held(gpuvm);
1949
1950 if (drm_gpuvm_is_extobj(gpuvm, vm_bo->obj))
1951 drm_gpuvm_bo_list_add(vm_bo, extobj, lock);
1952}
1953EXPORT_SYMBOL_GPL(drm_gpuvm_bo_extobj_add);
1954
1955/**
1956 * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to / from the &drm_gpuvms
1957 * evicted list
1958 * @vm_bo: the &drm_gpuvm_bo to add or remove
1959 * @evict: indicates whether the object is evicted
1960 *
1961 * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvm's evicted list.
1962 */
1963void
1964drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
1965{
1966 struct drm_gpuvm *gpuvm = vm_bo->vm;
1967 struct drm_gem_object *obj = vm_bo->obj;
1968 bool lock = !drm_gpuvm_resv_protected(gpuvm);
1969
1970 dma_resv_assert_held(obj->resv);
1971 vm_bo->evicted = evict;
1972
1973 /* Can't add external objects to the evicted list directly if not using
1974 * internal spinlocks, since in this case the evicted list is protected
1975 * with the VM's common dma-resv lock.
1976 */
1977 if (drm_gpuvm_is_extobj(gpuvm, obj) && !lock)
1978 return;
1979
1980 if (evict)
1981 drm_gpuvm_bo_list_add(vm_bo, evict, lock);
1982 else
1983 drm_gpuvm_bo_list_del_init(vm_bo, evict, lock);
1984}
1985EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict);
1986
1987static int
1988__drm_gpuva_insert(struct drm_gpuvm *gpuvm,
1989 struct drm_gpuva *va)
1990{
1991 struct rb_node *node;
1992 struct list_head *head;
1993
1994 if (drm_gpuva_it_iter_first(&gpuvm->rb.tree,
1995 GPUVA_START(va),
1996 GPUVA_LAST(va)))
1997 return -EEXIST;
1998
1999 va->vm = gpuvm;
2000
2001 drm_gpuva_it_insert(va, &gpuvm->rb.tree);
2002
2003 node = rb_prev(&va->rb.node);
2004 if (node)
2005 head = &(to_drm_gpuva(node))->rb.entry;
2006 else
2007 head = &gpuvm->rb.list;
2008
2009 list_add(&va->rb.entry, head);
2010
2011 return 0;
2012}
2013
2014/**
2015 * drm_gpuva_insert() - insert a &drm_gpuva
2016 * @gpuvm: the &drm_gpuvm to insert the &drm_gpuva in
2017 * @va: the &drm_gpuva to insert
2018 *
2019 * Insert a &drm_gpuva with a given address and range into a
2020 * &drm_gpuvm.
2021 *
2022 * It is safe to use this function using the safe versions of iterating the GPU
2023 * VA space, such as drm_gpuvm_for_each_va_safe() and
2024 * drm_gpuvm_for_each_va_range_safe().
2025 *
2026 * Returns: 0 on success, negative error code on failure.
2027 */
2028int
2029drm_gpuva_insert(struct drm_gpuvm *gpuvm,
2030 struct drm_gpuva *va)
2031{
2032 u64 addr = va->va.addr;
2033 u64 range = va->va.range;
2034 int ret;
2035
2036 if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range)))
2037 return -EINVAL;
2038
2039 ret = __drm_gpuva_insert(gpuvm, va);
2040 if (likely(!ret))
2041 /* Take a reference of the GPUVM for the successfully inserted
2042 * drm_gpuva. We can't take the reference in
2043 * __drm_gpuva_insert() itself, since we don't want to increse
2044 * the reference count for the GPUVM's kernel_alloc_node.
2045 */
2046 drm_gpuvm_get(gpuvm);
2047
2048 return ret;
2049}
2050EXPORT_SYMBOL_GPL(drm_gpuva_insert);
2051
2052static void
2053__drm_gpuva_remove(struct drm_gpuva *va)
2054{
2055 drm_gpuva_it_remove(va, &va->vm->rb.tree);
2056 list_del_init(&va->rb.entry);
2057}
2058
2059/**
2060 * drm_gpuva_remove() - remove a &drm_gpuva
2061 * @va: the &drm_gpuva to remove
2062 *
2063 * This removes the given &va from the underlying tree.
2064 *
2065 * It is safe to use this function using the safe versions of iterating the GPU
2066 * VA space, such as drm_gpuvm_for_each_va_safe() and
2067 * drm_gpuvm_for_each_va_range_safe().
2068 */
2069void
2070drm_gpuva_remove(struct drm_gpuva *va)
2071{
2072 struct drm_gpuvm *gpuvm = va->vm;
2073
2074 if (unlikely(va == &gpuvm->kernel_alloc_node)) {
2075 drm_WARN(gpuvm->drm, 1,
2076 "Can't destroy kernel reserved node.\n");
2077 return;
2078 }
2079
2080 __drm_gpuva_remove(va);
2081 drm_gpuvm_put(va->vm);
2082}
2083EXPORT_SYMBOL_GPL(drm_gpuva_remove);
2084
2085/**
2086 * drm_gpuva_link() - link a &drm_gpuva
2087 * @va: the &drm_gpuva to link
2088 * @vm_bo: the &drm_gpuvm_bo to add the &drm_gpuva to
2089 *
2090 * This adds the given &va to the GPU VA list of the &drm_gpuvm_bo and the
2091 * &drm_gpuvm_bo to the &drm_gem_object it is associated with.
2092 *
2093 * For every &drm_gpuva entry added to the &drm_gpuvm_bo an additional
2094 * reference of the latter is taken.
2095 *
2096 * This function expects the caller to protect the GEM's GPUVA list against
2097 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex.
2098 */
2099void
2100drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo)
2101{
2102 struct drm_gem_object *obj = va->gem.obj;
2103 struct drm_gpuvm *gpuvm = va->vm;
2104
2105 if (unlikely(!obj))
2106 return;
2107
2108 drm_WARN_ON(gpuvm->drm, obj != vm_bo->obj);
2109
2110 va->vm_bo = drm_gpuvm_bo_get(vm_bo);
2111
2112 drm_gem_gpuva_assert_lock_held(gpuvm, obj);
2113 list_add_tail(&va->gem.entry, &vm_bo->list.gpuva);
2114}
2115EXPORT_SYMBOL_GPL(drm_gpuva_link);
2116
2117/**
2118 * drm_gpuva_unlink() - unlink a &drm_gpuva
2119 * @va: the &drm_gpuva to unlink
2120 *
2121 * This removes the given &va from the GPU VA list of the &drm_gem_object it is
2122 * associated with.
2123 *
2124 * This removes the given &va from the GPU VA list of the &drm_gpuvm_bo and
2125 * the &drm_gpuvm_bo from the &drm_gem_object it is associated with in case
2126 * this call unlinks the last &drm_gpuva from the &drm_gpuvm_bo.
2127 *
2128 * For every &drm_gpuva entry removed from the &drm_gpuvm_bo a reference of
2129 * the latter is dropped.
2130 *
2131 * This function expects the caller to protect the GEM's GPUVA list against
2132 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex.
2133 */
2134void
2135drm_gpuva_unlink(struct drm_gpuva *va)
2136{
2137 struct drm_gem_object *obj = va->gem.obj;
2138 struct drm_gpuvm_bo *vm_bo = va->vm_bo;
2139
2140 if (unlikely(!obj))
2141 return;
2142
2143 drm_gem_gpuva_assert_lock_held(va->vm, obj);
2144 list_del_init(&va->gem.entry);
2145
2146 va->vm_bo = NULL;
2147 drm_gpuvm_bo_put(vm_bo);
2148}
2149EXPORT_SYMBOL_GPL(drm_gpuva_unlink);
2150
2151/**
2152 * drm_gpuva_unlink_defer() - unlink a &drm_gpuva with deferred vm_bo cleanup
2153 * @va: the &drm_gpuva to unlink
2154 *
2155 * Similar to drm_gpuva_unlink(), but uses drm_gpuvm_bo_put_deferred() and takes
2156 * the lock for the caller.
2157 */
2158void
2159drm_gpuva_unlink_defer(struct drm_gpuva *va)
2160{
2161 struct drm_gem_object *obj = va->gem.obj;
2162 struct drm_gpuvm_bo *vm_bo = va->vm_bo;
2163 bool should_defer_bo;
2164
2165 if (unlikely(!obj))
2166 return;
2167
2168 drm_WARN_ON(vm_bo->vm->drm, !drm_gpuvm_immediate_mode(vm_bo->vm));
2169
2170 mutex_lock(&obj->gpuva.lock);
2171 list_del_init(&va->gem.entry);
2172
2173 /*
2174 * This is drm_gpuvm_bo_put_deferred() except we already hold the mutex.
2175 */
2176 should_defer_bo = kref_put(&vm_bo->kref, drm_gpuvm_bo_into_zombie);
2177 mutex_unlock(&obj->gpuva.lock);
2178 if (should_defer_bo)
2179 drm_gpuvm_bo_defer_zombie_cleanup(vm_bo);
2180
2181 va->vm_bo = NULL;
2182}
2183EXPORT_SYMBOL_GPL(drm_gpuva_unlink_defer);
2184
2185/**
2186 * drm_gpuva_find_first() - find the first &drm_gpuva in the given range
2187 * @gpuvm: the &drm_gpuvm to search in
2188 * @addr: the &drm_gpuvas address
2189 * @range: the &drm_gpuvas range
2190 *
2191 * Returns: the first &drm_gpuva within the given range
2192 */
2193struct drm_gpuva *
2194drm_gpuva_find_first(struct drm_gpuvm *gpuvm,
2195 u64 addr, u64 range)
2196{
2197 u64 last = addr + range - 1;
2198
2199 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, addr, last);
2200}
2201EXPORT_SYMBOL_GPL(drm_gpuva_find_first);
2202
2203/**
2204 * drm_gpuva_find() - find a &drm_gpuva
2205 * @gpuvm: the &drm_gpuvm to search in
2206 * @addr: the &drm_gpuvas address
2207 * @range: the &drm_gpuvas range
2208 *
2209 * Returns: the &drm_gpuva at a given &addr and with a given &range
2210 */
2211struct drm_gpuva *
2212drm_gpuva_find(struct drm_gpuvm *gpuvm,
2213 u64 addr, u64 range)
2214{
2215 struct drm_gpuva *va;
2216
2217 va = drm_gpuva_find_first(gpuvm, addr, range);
2218 if (!va)
2219 goto out;
2220
2221 if (va->va.addr != addr ||
2222 va->va.range != range)
2223 goto out;
2224
2225 return va;
2226
2227out:
2228 return NULL;
2229}
2230EXPORT_SYMBOL_GPL(drm_gpuva_find);
2231
2232/**
2233 * drm_gpuvm_interval_empty() - indicate whether a given interval of the VA space
2234 * is empty
2235 * @gpuvm: the &drm_gpuvm to check the range for
2236 * @addr: the start address of the range
2237 * @range: the range of the interval
2238 *
2239 * Returns: true if the interval is empty, false otherwise
2240 */
2241bool
2242drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
2243{
2244 return !drm_gpuva_find_first(gpuvm, addr, range);
2245}
2246EXPORT_SYMBOL_GPL(drm_gpuvm_interval_empty);
2247
2248/**
2249 * drm_gpuva_map() - helper to insert a &drm_gpuva according to a
2250 * &drm_gpuva_op_map
2251 * @gpuvm: the &drm_gpuvm
2252 * @va: the &drm_gpuva to insert
2253 * @op: the &drm_gpuva_op_map to initialize @va with
2254 *
2255 * Initializes the @va from the @op and inserts it into the given @gpuvm.
2256 */
2257void
2258drm_gpuva_map(struct drm_gpuvm *gpuvm,
2259 struct drm_gpuva *va,
2260 const struct drm_gpuva_op_map *op)
2261{
2262 drm_gpuva_init_from_op(va, op);
2263 drm_gpuva_insert(gpuvm, va);
2264}
2265EXPORT_SYMBOL_GPL(drm_gpuva_map);
2266
2267/**
2268 * drm_gpuva_remap() - helper to remap a &drm_gpuva according to a
2269 * &drm_gpuva_op_remap
2270 * @prev: the &drm_gpuva to remap when keeping the start of a mapping
2271 * @next: the &drm_gpuva to remap when keeping the end of a mapping
2272 * @op: the &drm_gpuva_op_remap to initialize @prev and @next with
2273 *
2274 * Removes the currently mapped &drm_gpuva and remaps it using @prev and/or
2275 * @next.
2276 */
2277void
2278drm_gpuva_remap(struct drm_gpuva *prev,
2279 struct drm_gpuva *next,
2280 const struct drm_gpuva_op_remap *op)
2281{
2282 struct drm_gpuva *va = op->unmap->va;
2283 struct drm_gpuvm *gpuvm = va->vm;
2284
2285 drm_gpuva_remove(va);
2286
2287 if (op->prev) {
2288 drm_gpuva_init_from_op(prev, op->prev);
2289 drm_gpuva_insert(gpuvm, prev);
2290 }
2291
2292 if (op->next) {
2293 drm_gpuva_init_from_op(next, op->next);
2294 drm_gpuva_insert(gpuvm, next);
2295 }
2296}
2297EXPORT_SYMBOL_GPL(drm_gpuva_remap);
2298
2299/**
2300 * drm_gpuva_unmap() - helper to remove a &drm_gpuva according to a
2301 * &drm_gpuva_op_unmap
2302 * @op: the &drm_gpuva_op_unmap specifying the &drm_gpuva to remove
2303 *
2304 * Removes the &drm_gpuva associated with the &drm_gpuva_op_unmap.
2305 */
2306void
2307drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op)
2308{
2309 drm_gpuva_remove(op->va);
2310}
2311EXPORT_SYMBOL_GPL(drm_gpuva_unmap);
2312
2313static int
2314op_map_cb(const struct drm_gpuvm_ops *fn, void *priv,
2315 const struct drm_gpuvm_map_req *req)
2316{
2317 struct drm_gpuva_op op = {};
2318
2319 if (!req)
2320 return 0;
2321
2322 op.op = DRM_GPUVA_OP_MAP;
2323 op.map.va.addr = req->map.va.addr;
2324 op.map.va.range = req->map.va.range;
2325 op.map.gem.obj = req->map.gem.obj;
2326 op.map.gem.offset = req->map.gem.offset;
2327
2328 return fn->sm_step_map(&op, priv);
2329}
2330
2331static int
2332op_remap_cb(const struct drm_gpuvm_ops *fn, void *priv,
2333 struct drm_gpuva_op_map *prev,
2334 struct drm_gpuva_op_map *next,
2335 struct drm_gpuva_op_unmap *unmap)
2336{
2337 struct drm_gpuva_op op = {};
2338 struct drm_gpuva_op_remap *r;
2339
2340 op.op = DRM_GPUVA_OP_REMAP;
2341 r = &op.remap;
2342 r->prev = prev;
2343 r->next = next;
2344 r->unmap = unmap;
2345
2346 return fn->sm_step_remap(&op, priv);
2347}
2348
2349static int
2350op_unmap_cb(const struct drm_gpuvm_ops *fn, void *priv,
2351 struct drm_gpuva *va, bool merge, bool madvise)
2352{
2353 struct drm_gpuva_op op = {};
2354
2355 if (madvise)
2356 return 0;
2357
2358 op.op = DRM_GPUVA_OP_UNMAP;
2359 op.unmap.va = va;
2360 op.unmap.keep = merge;
2361
2362 return fn->sm_step_unmap(&op, priv);
2363}
2364
2365static int
2366__drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
2367 const struct drm_gpuvm_ops *ops, void *priv,
2368 const struct drm_gpuvm_map_req *req,
2369 bool madvise)
2370{
2371 struct drm_gem_object *req_obj = req->map.gem.obj;
2372 const struct drm_gpuvm_map_req *op_map = madvise ? NULL : req;
2373 struct drm_gpuva *va, *next;
2374 u64 req_offset = req->map.gem.offset;
2375 u64 req_range = req->map.va.range;
2376 u64 req_addr = req->map.va.addr;
2377 u64 req_end = req_addr + req_range;
2378 int ret;
2379
2380 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
2381 return -EINVAL;
2382
2383 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
2384 struct drm_gem_object *obj = va->gem.obj;
2385 u64 offset = va->gem.offset;
2386 u64 addr = va->va.addr;
2387 u64 range = va->va.range;
2388 u64 end = addr + range;
2389 bool merge = !!va->gem.obj;
2390
2391 if (madvise && obj)
2392 continue;
2393
2394 if (addr == req_addr) {
2395 merge &= obj == req_obj &&
2396 offset == req_offset;
2397
2398 if (end == req_end) {
2399 ret = op_unmap_cb(ops, priv, va, merge, madvise);
2400 if (ret)
2401 return ret;
2402 break;
2403 }
2404
2405 if (end < req_end) {
2406 ret = op_unmap_cb(ops, priv, va, merge, madvise);
2407 if (ret)
2408 return ret;
2409 continue;
2410 }
2411
2412 if (end > req_end) {
2413 struct drm_gpuva_op_map n = {
2414 .va.addr = req_end,
2415 .va.range = range - req_range,
2416 .gem.obj = obj,
2417 .gem.offset = offset + req_range,
2418 };
2419 struct drm_gpuva_op_unmap u = {
2420 .va = va,
2421 .keep = merge,
2422 };
2423
2424 ret = op_remap_cb(ops, priv, NULL, &n, &u);
2425 if (ret)
2426 return ret;
2427
2428 if (madvise)
2429 op_map = req;
2430 break;
2431 }
2432 } else if (addr < req_addr) {
2433 u64 ls_range = req_addr - addr;
2434 struct drm_gpuva_op_map p = {
2435 .va.addr = addr,
2436 .va.range = ls_range,
2437 .gem.obj = obj,
2438 .gem.offset = offset,
2439 };
2440 struct drm_gpuva_op_unmap u = { .va = va };
2441
2442 merge &= obj == req_obj &&
2443 offset + ls_range == req_offset;
2444 u.keep = merge;
2445
2446 if (end == req_end) {
2447 ret = op_remap_cb(ops, priv, &p, NULL, &u);
2448 if (ret)
2449 return ret;
2450
2451 if (madvise)
2452 op_map = req;
2453 break;
2454 }
2455
2456 if (end < req_end) {
2457 ret = op_remap_cb(ops, priv, &p, NULL, &u);
2458 if (ret)
2459 return ret;
2460
2461 if (madvise) {
2462 struct drm_gpuvm_map_req map_req = {
2463 .map.va.addr = req_addr,
2464 .map.va.range = end - req_addr,
2465 };
2466
2467 ret = op_map_cb(ops, priv, &map_req);
2468 if (ret)
2469 return ret;
2470 }
2471
2472 continue;
2473 }
2474
2475 if (end > req_end) {
2476 struct drm_gpuva_op_map n = {
2477 .va.addr = req_end,
2478 .va.range = end - req_end,
2479 .gem.obj = obj,
2480 .gem.offset = offset + ls_range +
2481 req_range,
2482 };
2483
2484 ret = op_remap_cb(ops, priv, &p, &n, &u);
2485 if (ret)
2486 return ret;
2487
2488 if (madvise)
2489 op_map = req;
2490 break;
2491 }
2492 } else if (addr > req_addr) {
2493 merge &= obj == req_obj &&
2494 offset == req_offset +
2495 (addr - req_addr);
2496
2497 if (end == req_end) {
2498 ret = op_unmap_cb(ops, priv, va, merge, madvise);
2499 if (ret)
2500 return ret;
2501
2502 break;
2503 }
2504
2505 if (end < req_end) {
2506 ret = op_unmap_cb(ops, priv, va, merge, madvise);
2507 if (ret)
2508 return ret;
2509
2510 continue;
2511 }
2512
2513 if (end > req_end) {
2514 struct drm_gpuva_op_map n = {
2515 .va.addr = req_end,
2516 .va.range = end - req_end,
2517 .gem.obj = obj,
2518 .gem.offset = offset + req_end - addr,
2519 };
2520 struct drm_gpuva_op_unmap u = {
2521 .va = va,
2522 .keep = merge,
2523 };
2524
2525 ret = op_remap_cb(ops, priv, NULL, &n, &u);
2526 if (ret)
2527 return ret;
2528
2529 if (madvise) {
2530 struct drm_gpuvm_map_req map_req = {
2531 .map.va.addr = addr,
2532 .map.va.range = req_end - addr,
2533 };
2534
2535 return op_map_cb(ops, priv, &map_req);
2536 }
2537 break;
2538 }
2539 }
2540 }
2541 return op_map_cb(ops, priv, op_map);
2542}
2543
2544static int
2545__drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm,
2546 const struct drm_gpuvm_ops *ops, void *priv,
2547 u64 req_addr, u64 req_range)
2548{
2549 struct drm_gpuva *va, *next;
2550 u64 req_end = req_addr + req_range;
2551 int ret;
2552
2553 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
2554 return -EINVAL;
2555
2556 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
2557 struct drm_gpuva_op_map prev = {}, next = {};
2558 bool prev_split = false, next_split = false;
2559 struct drm_gem_object *obj = va->gem.obj;
2560 u64 offset = va->gem.offset;
2561 u64 addr = va->va.addr;
2562 u64 range = va->va.range;
2563 u64 end = addr + range;
2564
2565 if (addr < req_addr) {
2566 prev.va.addr = addr;
2567 prev.va.range = req_addr - addr;
2568 prev.gem.obj = obj;
2569 prev.gem.offset = offset;
2570
2571 prev_split = true;
2572 }
2573
2574 if (end > req_end) {
2575 next.va.addr = req_end;
2576 next.va.range = end - req_end;
2577 next.gem.obj = obj;
2578 next.gem.offset = offset + (req_end - addr);
2579
2580 next_split = true;
2581 }
2582
2583 if (prev_split || next_split) {
2584 struct drm_gpuva_op_unmap unmap = { .va = va };
2585
2586 ret = op_remap_cb(ops, priv,
2587 prev_split ? &prev : NULL,
2588 next_split ? &next : NULL,
2589 &unmap);
2590 if (ret)
2591 return ret;
2592 } else {
2593 ret = op_unmap_cb(ops, priv, va, false, false);
2594 if (ret)
2595 return ret;
2596 }
2597 }
2598
2599 return 0;
2600}
2601
2602/**
2603 * drm_gpuvm_sm_map() - calls the &drm_gpuva_op split/merge steps
2604 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2605 * @priv: pointer to a driver private data structure
2606 * @req: ptr to struct drm_gpuvm_map_req
2607 *
2608 * This function iterates the given range of the GPU VA space. It utilizes the
2609 * &drm_gpuvm_ops to call back into the driver providing the split and merge
2610 * steps.
2611 *
2612 * Drivers may use these callbacks to update the GPU VA space right away within
2613 * the callback. In case the driver decides to copy and store the operations for
2614 * later processing neither this function nor &drm_gpuvm_sm_unmap is allowed to
2615 * be called before the &drm_gpuvm's view of the GPU VA space was
2616 * updated with the previous set of operations. To update the
2617 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2618 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2619 * used.
2620 *
2621 * A sequence of callbacks can contain map, unmap and remap operations, but
2622 * the sequence of callbacks might also be empty if no operation is required,
2623 * e.g. if the requested mapping already exists in the exact same way.
2624 *
2625 * There can be an arbitrary amount of unmap operations, a maximum of two remap
2626 * operations and a single map operation. The latter one represents the original
2627 * map operation requested by the caller.
2628 *
2629 * Returns: 0 on success or a negative error code
2630 */
2631int
2632drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv,
2633 const struct drm_gpuvm_map_req *req)
2634{
2635 const struct drm_gpuvm_ops *ops = gpuvm->ops;
2636
2637 if (unlikely(!(ops && ops->sm_step_map &&
2638 ops->sm_step_remap &&
2639 ops->sm_step_unmap)))
2640 return -EINVAL;
2641
2642 return __drm_gpuvm_sm_map(gpuvm, ops, priv, req, false);
2643}
2644EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map);
2645
2646/**
2647 * drm_gpuvm_sm_unmap() - calls the &drm_gpuva_ops to split on unmap
2648 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2649 * @priv: pointer to a driver private data structure
2650 * @req_addr: the start address of the range to unmap
2651 * @req_range: the range of the mappings to unmap
2652 *
2653 * This function iterates the given range of the GPU VA space. It utilizes the
2654 * &drm_gpuvm_ops to call back into the driver providing the operations to
2655 * unmap and, if required, split existing mappings.
2656 *
2657 * Drivers may use these callbacks to update the GPU VA space right away within
2658 * the callback. In case the driver decides to copy and store the operations for
2659 * later processing neither this function nor &drm_gpuvm_sm_map is allowed to be
2660 * called before the &drm_gpuvm's view of the GPU VA space was updated
2661 * with the previous set of operations. To update the &drm_gpuvm's view
2662 * of the GPU VA space drm_gpuva_insert(), drm_gpuva_destroy_locked() and/or
2663 * drm_gpuva_destroy_unlocked() should be used.
2664 *
2665 * A sequence of callbacks can contain unmap and remap operations, depending on
2666 * whether there are actual overlapping mappings to split.
2667 *
2668 * There can be an arbitrary amount of unmap operations and a maximum of two
2669 * remap operations.
2670 *
2671 * Returns: 0 on success or a negative error code
2672 */
2673int
2674drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv,
2675 u64 req_addr, u64 req_range)
2676{
2677 const struct drm_gpuvm_ops *ops = gpuvm->ops;
2678
2679 if (unlikely(!(ops && ops->sm_step_remap &&
2680 ops->sm_step_unmap)))
2681 return -EINVAL;
2682
2683 return __drm_gpuvm_sm_unmap(gpuvm, ops, priv,
2684 req_addr, req_range);
2685}
2686EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap);
2687
2688static int
2689drm_gpuva_sm_step_lock(struct drm_gpuva_op *op, void *priv)
2690{
2691 struct drm_exec *exec = priv;
2692
2693 switch (op->op) {
2694 case DRM_GPUVA_OP_REMAP:
2695 if (op->remap.unmap->va->gem.obj)
2696 return drm_exec_lock_obj(exec, op->remap.unmap->va->gem.obj);
2697 return 0;
2698 case DRM_GPUVA_OP_UNMAP:
2699 if (op->unmap.va->gem.obj)
2700 return drm_exec_lock_obj(exec, op->unmap.va->gem.obj);
2701 return 0;
2702 default:
2703 return 0;
2704 }
2705}
2706
2707static const struct drm_gpuvm_ops lock_ops = {
2708 .sm_step_map = drm_gpuva_sm_step_lock,
2709 .sm_step_remap = drm_gpuva_sm_step_lock,
2710 .sm_step_unmap = drm_gpuva_sm_step_lock,
2711};
2712
2713/**
2714 * drm_gpuvm_sm_map_exec_lock() - locks the objects touched by a drm_gpuvm_sm_map()
2715 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2716 * @exec: the &drm_exec locking context
2717 * @num_fences: for newly mapped objects, the # of fences to reserve
2718 * @req: ptr to drm_gpuvm_map_req struct
2719 *
2720 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/
2721 * remapped, and locks+prepares (drm_exec_prepare_object()) objects that
2722 * will be newly mapped.
2723 *
2724 * The expected usage is::
2725 *
2726 * vm_bind {
2727 * struct drm_exec exec;
2728 *
2729 * // IGNORE_DUPLICATES is required, INTERRUPTIBLE_WAIT is recommended:
2730 * drm_exec_init(&exec, IGNORE_DUPLICATES | INTERRUPTIBLE_WAIT, 0);
2731 *
2732 * drm_exec_until_all_locked (&exec) {
2733 * for_each_vm_bind_operation {
2734 * switch (op->op) {
2735 * case DRIVER_OP_UNMAP:
2736 * ret = drm_gpuvm_sm_unmap_exec_lock(gpuvm, &exec, op->addr, op->range);
2737 * break;
2738 * case DRIVER_OP_MAP:
2739 * ret = drm_gpuvm_sm_map_exec_lock(gpuvm, &exec, num_fences, &req);
2740 * break;
2741 * }
2742 *
2743 * drm_exec_retry_on_contention(&exec);
2744 * if (ret)
2745 * return ret;
2746 * }
2747 * }
2748 * }
2749 *
2750 * This enables all locking to be performed before the driver begins modifying
2751 * the VM. This is safe to do in the case of overlapping DRIVER_VM_BIND_OPs,
2752 * where an earlier op can alter the sequence of steps generated for a later
2753 * op, because the later altered step will involve the same GEM object(s)
2754 * already seen in the earlier locking step. For example:
2755 *
2756 * 1) An earlier driver DRIVER_OP_UNMAP op removes the need for a
2757 * DRM_GPUVA_OP_REMAP/UNMAP step. This is safe because we've already
2758 * locked the GEM object in the earlier DRIVER_OP_UNMAP op.
2759 *
2760 * 2) An earlier DRIVER_OP_MAP op overlaps with a later DRIVER_OP_MAP/UNMAP
2761 * op, introducing a DRM_GPUVA_OP_REMAP/UNMAP that wouldn't have been
2762 * required without the earlier DRIVER_OP_MAP. This is safe because we've
2763 * already locked the GEM object in the earlier DRIVER_OP_MAP step.
2764 *
2765 * Returns: 0 on success or a negative error code
2766 */
2767int
2768drm_gpuvm_sm_map_exec_lock(struct drm_gpuvm *gpuvm,
2769 struct drm_exec *exec, unsigned int num_fences,
2770 struct drm_gpuvm_map_req *req)
2771{
2772 struct drm_gem_object *req_obj = req->map.gem.obj;
2773
2774 if (req_obj) {
2775 int ret = drm_exec_prepare_obj(exec, req_obj, num_fences);
2776 if (ret)
2777 return ret;
2778 }
2779
2780 return __drm_gpuvm_sm_map(gpuvm, &lock_ops, exec, req, false);
2781
2782}
2783EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_exec_lock);
2784
2785/**
2786 * drm_gpuvm_sm_unmap_exec_lock() - locks the objects touched by drm_gpuvm_sm_unmap()
2787 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2788 * @exec: the &drm_exec locking context
2789 * @req_addr: the start address of the range to unmap
2790 * @req_range: the range of the mappings to unmap
2791 *
2792 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/
2793 * remapped by drm_gpuvm_sm_unmap().
2794 *
2795 * See drm_gpuvm_sm_map_exec_lock() for expected usage.
2796 *
2797 * Returns: 0 on success or a negative error code
2798 */
2799int
2800drm_gpuvm_sm_unmap_exec_lock(struct drm_gpuvm *gpuvm, struct drm_exec *exec,
2801 u64 req_addr, u64 req_range)
2802{
2803 return __drm_gpuvm_sm_unmap(gpuvm, &lock_ops, exec,
2804 req_addr, req_range);
2805}
2806EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_exec_lock);
2807
2808static struct drm_gpuva_op *
2809gpuva_op_alloc(struct drm_gpuvm *gpuvm)
2810{
2811 const struct drm_gpuvm_ops *fn = gpuvm->ops;
2812 struct drm_gpuva_op *op;
2813
2814 if (fn && fn->op_alloc)
2815 op = fn->op_alloc();
2816 else
2817 op = kzalloc_obj(*op);
2818
2819 if (unlikely(!op))
2820 return NULL;
2821
2822 return op;
2823}
2824
2825static void
2826gpuva_op_free(struct drm_gpuvm *gpuvm,
2827 struct drm_gpuva_op *op)
2828{
2829 const struct drm_gpuvm_ops *fn = gpuvm->ops;
2830
2831 if (fn && fn->op_free)
2832 fn->op_free(op);
2833 else
2834 kfree(op);
2835}
2836
2837static int
2838drm_gpuva_sm_step(struct drm_gpuva_op *__op,
2839 void *priv)
2840{
2841 struct {
2842 struct drm_gpuvm *vm;
2843 struct drm_gpuva_ops *ops;
2844 } *args = priv;
2845 struct drm_gpuvm *gpuvm = args->vm;
2846 struct drm_gpuva_ops *ops = args->ops;
2847 struct drm_gpuva_op *op;
2848
2849 op = gpuva_op_alloc(gpuvm);
2850 if (unlikely(!op))
2851 goto err;
2852
2853 memcpy(op, __op, sizeof(*op));
2854
2855 if (op->op == DRM_GPUVA_OP_REMAP) {
2856 struct drm_gpuva_op_remap *__r = &__op->remap;
2857 struct drm_gpuva_op_remap *r = &op->remap;
2858
2859 r->unmap = kmemdup(__r->unmap, sizeof(*r->unmap),
2860 GFP_KERNEL);
2861 if (unlikely(!r->unmap))
2862 goto err_free_op;
2863
2864 if (__r->prev) {
2865 r->prev = kmemdup(__r->prev, sizeof(*r->prev),
2866 GFP_KERNEL);
2867 if (unlikely(!r->prev))
2868 goto err_free_unmap;
2869 }
2870
2871 if (__r->next) {
2872 r->next = kmemdup(__r->next, sizeof(*r->next),
2873 GFP_KERNEL);
2874 if (unlikely(!r->next))
2875 goto err_free_prev;
2876 }
2877 }
2878
2879 list_add_tail(&op->entry, &ops->list);
2880
2881 return 0;
2882
2883err_free_unmap:
2884 kfree(op->remap.unmap);
2885err_free_prev:
2886 kfree(op->remap.prev);
2887err_free_op:
2888 gpuva_op_free(gpuvm, op);
2889err:
2890 return -ENOMEM;
2891}
2892
2893static const struct drm_gpuvm_ops gpuvm_list_ops = {
2894 .sm_step_map = drm_gpuva_sm_step,
2895 .sm_step_remap = drm_gpuva_sm_step,
2896 .sm_step_unmap = drm_gpuva_sm_step,
2897};
2898
2899static struct drm_gpuva_ops *
2900__drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
2901 const struct drm_gpuvm_map_req *req,
2902 bool madvise)
2903{
2904 struct drm_gpuva_ops *ops;
2905 struct {
2906 struct drm_gpuvm *vm;
2907 struct drm_gpuva_ops *ops;
2908 } args;
2909 int ret;
2910
2911 ops = kzalloc_obj(*ops);
2912 if (unlikely(!ops))
2913 return ERR_PTR(-ENOMEM);
2914
2915 INIT_LIST_HEAD(&ops->list);
2916
2917 args.vm = gpuvm;
2918 args.ops = ops;
2919
2920 ret = __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args, req, madvise);
2921 if (ret)
2922 goto err_free_ops;
2923
2924 return ops;
2925
2926err_free_ops:
2927 drm_gpuva_ops_free(gpuvm, ops);
2928 return ERR_PTR(ret);
2929}
2930
2931/**
2932 * drm_gpuvm_sm_map_ops_create() - creates the &drm_gpuva_ops to split and merge
2933 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2934 * @req: map request arguments
2935 *
2936 * This function creates a list of operations to perform splitting and merging
2937 * of existing mapping(s) with the newly requested one.
2938 *
2939 * The list can be iterated with &drm_gpuva_for_each_op and must be processed
2940 * in the given order. It can contain map, unmap and remap operations, but it
2941 * also can be empty if no operation is required, e.g. if the requested mapping
2942 * already exists in the exact same way.
2943 *
2944 * There can be an arbitrary amount of unmap operations, a maximum of two remap
2945 * operations and a single map operation. The latter one represents the original
2946 * map operation requested by the caller.
2947 *
2948 * Note that before calling this function again with another mapping request it
2949 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The
2950 * previously obtained operations must be either processed or abandoned. To
2951 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2952 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2953 * used.
2954 *
2955 * After the caller finished processing the returned &drm_gpuva_ops, they must
2956 * be freed with &drm_gpuva_ops_free.
2957 *
2958 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2959 */
2960struct drm_gpuva_ops *
2961drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
2962 const struct drm_gpuvm_map_req *req)
2963{
2964 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, false);
2965}
2966EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create);
2967
2968/**
2969 * drm_gpuvm_madvise_ops_create() - creates the &drm_gpuva_ops to split
2970 * @gpuvm: the &drm_gpuvm representing the GPU VA space
2971 * @req: map request arguments
2972 *
2973 * This function creates a list of operations to perform splitting
2974 * of existent mapping(s) at start or end, based on the request map.
2975 *
2976 * The list can be iterated with &drm_gpuva_for_each_op and must be processed
2977 * in the given order. It can contain map and remap operations, but it
2978 * also can be empty if no operation is required, e.g. if the requested mapping
2979 * already exists is the exact same way.
2980 *
2981 * There will be no unmap operations, a maximum of two remap operations and two
2982 * map operations. The two map operations correspond to: one from start to the
2983 * end of drm_gpuvaX, and another from the start of drm_gpuvaY to end.
2984 *
2985 * Note that before calling this function again with another mapping request it
2986 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The
2987 * previously obtained operations must be either processed or abandoned. To
2988 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2989 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2990 * used.
2991 *
2992 * After the caller finished processing the returned &drm_gpuva_ops, they must
2993 * be freed with &drm_gpuva_ops_free.
2994 *
2995 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2996 */
2997struct drm_gpuva_ops *
2998drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm,
2999 const struct drm_gpuvm_map_req *req)
3000{
3001 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, true);
3002}
3003EXPORT_SYMBOL_GPL(drm_gpuvm_madvise_ops_create);
3004
3005/**
3006 * drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on
3007 * unmap
3008 * @gpuvm: the &drm_gpuvm representing the GPU VA space
3009 * @req_addr: the start address of the range to unmap
3010 * @req_range: the range of the mappings to unmap
3011 *
3012 * This function creates a list of operations to perform unmapping and, if
3013 * required, splitting of the mappings overlapping the unmap range.
3014 *
3015 * The list can be iterated with &drm_gpuva_for_each_op and must be processed
3016 * in the given order. It can contain unmap and remap operations, depending on
3017 * whether there are actual overlapping mappings to split.
3018 *
3019 * There can be an arbitrary amount of unmap operations and a maximum of two
3020 * remap operations.
3021 *
3022 * Note that before calling this function again with another range to unmap it
3023 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The
3024 * previously obtained operations must be processed or abandoned. To update the
3025 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
3026 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
3027 * used.
3028 *
3029 * After the caller finished processing the returned &drm_gpuva_ops, they must
3030 * be freed with &drm_gpuva_ops_free.
3031 *
3032 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
3033 */
3034struct drm_gpuva_ops *
3035drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm,
3036 u64 req_addr, u64 req_range)
3037{
3038 struct drm_gpuva_ops *ops;
3039 struct {
3040 struct drm_gpuvm *vm;
3041 struct drm_gpuva_ops *ops;
3042 } args;
3043 int ret;
3044
3045 ops = kzalloc_obj(*ops);
3046 if (unlikely(!ops))
3047 return ERR_PTR(-ENOMEM);
3048
3049 INIT_LIST_HEAD(&ops->list);
3050
3051 args.vm = gpuvm;
3052 args.ops = ops;
3053
3054 ret = __drm_gpuvm_sm_unmap(gpuvm, &gpuvm_list_ops, &args,
3055 req_addr, req_range);
3056 if (ret)
3057 goto err_free_ops;
3058
3059 return ops;
3060
3061err_free_ops:
3062 drm_gpuva_ops_free(gpuvm, ops);
3063 return ERR_PTR(ret);
3064}
3065EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_ops_create);
3066
3067/**
3068 * drm_gpuvm_prefetch_ops_create() - creates the &drm_gpuva_ops to prefetch
3069 * @gpuvm: the &drm_gpuvm representing the GPU VA space
3070 * @addr: the start address of the range to prefetch
3071 * @range: the range of the mappings to prefetch
3072 *
3073 * This function creates a list of operations to perform prefetching.
3074 *
3075 * The list can be iterated with &drm_gpuva_for_each_op and must be processed
3076 * in the given order. It can contain prefetch operations.
3077 *
3078 * There can be an arbitrary amount of prefetch operations.
3079 *
3080 * After the caller finished processing the returned &drm_gpuva_ops, they must
3081 * be freed with &drm_gpuva_ops_free.
3082 *
3083 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
3084 */
3085struct drm_gpuva_ops *
3086drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm,
3087 u64 addr, u64 range)
3088{
3089 struct drm_gpuva_ops *ops;
3090 struct drm_gpuva_op *op;
3091 struct drm_gpuva *va;
3092 u64 end = addr + range;
3093 int ret;
3094
3095 ops = kzalloc_obj(*ops);
3096 if (!ops)
3097 return ERR_PTR(-ENOMEM);
3098
3099 INIT_LIST_HEAD(&ops->list);
3100
3101 drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
3102 op = gpuva_op_alloc(gpuvm);
3103 if (!op) {
3104 ret = -ENOMEM;
3105 goto err_free_ops;
3106 }
3107
3108 op->op = DRM_GPUVA_OP_PREFETCH;
3109 op->prefetch.va = va;
3110 list_add_tail(&op->entry, &ops->list);
3111 }
3112
3113 return ops;
3114
3115err_free_ops:
3116 drm_gpuva_ops_free(gpuvm, ops);
3117 return ERR_PTR(ret);
3118}
3119EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create);
3120
3121/**
3122 * drm_gpuvm_bo_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM
3123 * @vm_bo: the &drm_gpuvm_bo abstraction
3124 *
3125 * This function creates a list of operations to perform unmapping for every
3126 * GPUVA attached to a GEM.
3127 *
3128 * The list can be iterated with &drm_gpuva_for_each_op and consists out of an
3129 * arbitrary amount of unmap operations.
3130 *
3131 * After the caller finished processing the returned &drm_gpuva_ops, they must
3132 * be freed with &drm_gpuva_ops_free.
3133 *
3134 * This function expects the caller to protect the GEM's GPUVA list against
3135 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex.
3136 *
3137 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
3138 */
3139struct drm_gpuva_ops *
3140drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo)
3141{
3142 struct drm_gpuva_ops *ops;
3143 struct drm_gpuva_op *op;
3144 struct drm_gpuva *va;
3145 int ret;
3146
3147 drm_gem_gpuva_assert_lock_held(vm_bo->vm, vm_bo->obj);
3148
3149 ops = kzalloc_obj(*ops);
3150 if (!ops)
3151 return ERR_PTR(-ENOMEM);
3152
3153 INIT_LIST_HEAD(&ops->list);
3154
3155 drm_gpuvm_bo_for_each_va(va, vm_bo) {
3156 op = gpuva_op_alloc(vm_bo->vm);
3157 if (!op) {
3158 ret = -ENOMEM;
3159 goto err_free_ops;
3160 }
3161
3162 op->op = DRM_GPUVA_OP_UNMAP;
3163 op->unmap.va = va;
3164 list_add_tail(&op->entry, &ops->list);
3165 }
3166
3167 return ops;
3168
3169err_free_ops:
3170 drm_gpuva_ops_free(vm_bo->vm, ops);
3171 return ERR_PTR(ret);
3172}
3173EXPORT_SYMBOL_GPL(drm_gpuvm_bo_unmap_ops_create);
3174
3175/**
3176 * drm_gpuva_ops_free() - free the given &drm_gpuva_ops
3177 * @gpuvm: the &drm_gpuvm the ops were created for
3178 * @ops: the &drm_gpuva_ops to free
3179 *
3180 * Frees the given &drm_gpuva_ops structure including all the ops associated
3181 * with it.
3182 */
3183void
3184drm_gpuva_ops_free(struct drm_gpuvm *gpuvm,
3185 struct drm_gpuva_ops *ops)
3186{
3187 struct drm_gpuva_op *op, *next;
3188
3189 drm_gpuva_for_each_op_safe(op, next, ops) {
3190 list_del(&op->entry);
3191
3192 if (op->op == DRM_GPUVA_OP_REMAP) {
3193 kfree(op->remap.prev);
3194 kfree(op->remap.next);
3195 kfree(op->remap.unmap);
3196 }
3197
3198 gpuva_op_free(gpuvm, op);
3199 }
3200
3201 kfree(ops);
3202}
3203EXPORT_SYMBOL_GPL(drm_gpuva_ops_free);
3204
3205MODULE_DESCRIPTION("DRM GPUVM");
3206MODULE_LICENSE("GPL");