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 <dakr@redhat.com> 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 829 static 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 857 static void 858 cond_spin_lock(spinlock_t *lock, bool cond) 859 { 860 if (cond) 861 spin_lock(lock); 862 } 863 864 static void 865 cond_spin_unlock(spinlock_t *lock, bool cond) 866 { 867 if (cond) 868 spin_unlock(lock); 869 } 870 871 static 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 */ 900 static bool 901 drm_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 921 static 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 */ 973 INTERVAL_TREE_DEFINE(struct drm_gpuva, rb.node, u64, rb.__subtree_last, 974 GPUVA_START, GPUVA_LAST, static __maybe_unused, 975 drm_gpuva_it) 976 977 static int __drm_gpuva_insert(struct drm_gpuvm *gpuvm, 978 struct drm_gpuva *va); 979 static void __drm_gpuva_remove(struct drm_gpuva *va); 980 981 static bool 982 drm_gpuvm_check_overflow(u64 addr, u64 range) 983 { 984 u64 end; 985 986 return check_add_overflow(addr, range, &end); 987 } 988 989 static bool 990 drm_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 996 static bool 997 drm_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 1006 static bool 1007 drm_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 */ 1028 bool 1029 drm_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 } 1036 EXPORT_SYMBOL_GPL(drm_gpuvm_range_valid); 1037 1038 static void 1039 drm_gpuvm_gem_object_free(struct drm_gem_object *obj) 1040 { 1041 drm_gem_object_release(obj); 1042 kfree(obj); 1043 } 1044 1045 static 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 */ 1059 struct drm_gem_object * 1060 drm_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 } 1073 EXPORT_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 */ 1093 void 1094 drm_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 } 1138 EXPORT_SYMBOL_GPL(drm_gpuvm_init); 1139 1140 static void 1141 drm_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 1161 static void 1162 drm_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 */ 1184 void 1185 drm_gpuvm_put(struct drm_gpuvm *gpuvm) 1186 { 1187 if (gpuvm) 1188 kref_put(&gpuvm->kref, drm_gpuvm_free); 1189 } 1190 EXPORT_SYMBOL_GPL(drm_gpuvm_put); 1191 1192 static int 1193 exec_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 */ 1214 int 1215 drm_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 } 1221 EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_vm); 1222 1223 static 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 1244 static int 1245 drm_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 */ 1291 int 1292 drm_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 } 1302 EXPORT_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 */ 1318 int 1319 drm_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 } 1339 EXPORT_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 */ 1355 int 1356 drm_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 1386 err: 1387 drm_exec_fini(exec); 1388 return ret; 1389 } 1390 EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock); 1391 1392 static int 1393 fn_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 */ 1415 int 1416 drm_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 } 1433 EXPORT_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 */ 1446 int 1447 drm_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 1466 err: 1467 drm_exec_fini(exec); 1468 return ret; 1469 } 1470 EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_range); 1471 1472 static 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 1492 static int 1493 drm_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 */ 1528 int 1529 drm_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 } 1541 EXPORT_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 */ 1552 void 1553 drm_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 } 1568 EXPORT_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 */ 1580 struct drm_gpuvm_bo * 1581 drm_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 } 1609 EXPORT_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 */ 1622 static void 1623 drm_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 1638 static void 1639 drm_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 1647 static void 1648 drm_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 */ 1683 bool 1684 drm_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 } 1693 EXPORT_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 */ 1703 static void 1704 drm_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 */ 1729 static void 1730 drm_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 1735 static void 1736 drm_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 */ 1758 bool 1759 drm_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 } 1770 EXPORT_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 */ 1779 void 1780 drm_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 } 1804 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup); 1805 1806 static 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 */ 1832 struct drm_gpuvm_bo * 1833 drm_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 } 1840 EXPORT_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 */ 1859 struct drm_gpuvm_bo * 1860 drm_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 } 1886 EXPORT_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 */ 1907 struct drm_gpuvm_bo * 1908 drm_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 } 1930 EXPORT_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 */ 1941 void 1942 drm_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 } 1953 EXPORT_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 */ 1963 void 1964 drm_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 } 1985 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict); 1986 1987 static 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 */ 2028 int 2029 drm_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 } 2050 EXPORT_SYMBOL_GPL(drm_gpuva_insert); 2051 2052 static 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 */ 2069 void 2070 drm_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 } 2083 EXPORT_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 */ 2099 void 2100 drm_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 } 2115 EXPORT_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 */ 2134 void 2135 drm_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 } 2149 EXPORT_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 */ 2158 void 2159 drm_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 } 2183 EXPORT_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 */ 2193 struct drm_gpuva * 2194 drm_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 } 2201 EXPORT_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 */ 2211 struct drm_gpuva * 2212 drm_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 2227 out: 2228 return NULL; 2229 } 2230 EXPORT_SYMBOL_GPL(drm_gpuva_find); 2231 2232 /** 2233 * drm_gpuva_find_prev() - find the &drm_gpuva before the given address 2234 * @gpuvm: the &drm_gpuvm to search in 2235 * @start: the given GPU VA's start address 2236 * 2237 * Find the adjacent &drm_gpuva before the GPU VA with given &start address. 2238 * 2239 * Note that if there is any free space between the GPU VA mappings no mapping 2240 * is returned. 2241 * 2242 * Returns: a pointer to the found &drm_gpuva or NULL if none was found 2243 */ 2244 struct drm_gpuva * 2245 drm_gpuva_find_prev(struct drm_gpuvm *gpuvm, u64 start) 2246 { 2247 if (!drm_gpuvm_range_valid(gpuvm, start - 1, 1)) 2248 return NULL; 2249 2250 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, start - 1, start); 2251 } 2252 EXPORT_SYMBOL_GPL(drm_gpuva_find_prev); 2253 2254 /** 2255 * drm_gpuva_find_next() - find the &drm_gpuva after the given address 2256 * @gpuvm: the &drm_gpuvm to search in 2257 * @end: the given GPU VA's end address 2258 * 2259 * Find the adjacent &drm_gpuva after the GPU VA with given &end address. 2260 * 2261 * Note that if there is any free space between the GPU VA mappings no mapping 2262 * is returned. 2263 * 2264 * Returns: a pointer to the found &drm_gpuva or NULL if none was found 2265 */ 2266 struct drm_gpuva * 2267 drm_gpuva_find_next(struct drm_gpuvm *gpuvm, u64 end) 2268 { 2269 if (!drm_gpuvm_range_valid(gpuvm, end, 1)) 2270 return NULL; 2271 2272 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, end, end + 1); 2273 } 2274 EXPORT_SYMBOL_GPL(drm_gpuva_find_next); 2275 2276 /** 2277 * drm_gpuvm_interval_empty() - indicate whether a given interval of the VA space 2278 * is empty 2279 * @gpuvm: the &drm_gpuvm to check the range for 2280 * @addr: the start address of the range 2281 * @range: the range of the interval 2282 * 2283 * Returns: true if the interval is empty, false otherwise 2284 */ 2285 bool 2286 drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range) 2287 { 2288 return !drm_gpuva_find_first(gpuvm, addr, range); 2289 } 2290 EXPORT_SYMBOL_GPL(drm_gpuvm_interval_empty); 2291 2292 /** 2293 * drm_gpuva_map() - helper to insert a &drm_gpuva according to a 2294 * &drm_gpuva_op_map 2295 * @gpuvm: the &drm_gpuvm 2296 * @va: the &drm_gpuva to insert 2297 * @op: the &drm_gpuva_op_map to initialize @va with 2298 * 2299 * Initializes the @va from the @op and inserts it into the given @gpuvm. 2300 */ 2301 void 2302 drm_gpuva_map(struct drm_gpuvm *gpuvm, 2303 struct drm_gpuva *va, 2304 const struct drm_gpuva_op_map *op) 2305 { 2306 drm_gpuva_init_from_op(va, op); 2307 drm_gpuva_insert(gpuvm, va); 2308 } 2309 EXPORT_SYMBOL_GPL(drm_gpuva_map); 2310 2311 /** 2312 * drm_gpuva_remap() - helper to remap a &drm_gpuva according to a 2313 * &drm_gpuva_op_remap 2314 * @prev: the &drm_gpuva to remap when keeping the start of a mapping 2315 * @next: the &drm_gpuva to remap when keeping the end of a mapping 2316 * @op: the &drm_gpuva_op_remap to initialize @prev and @next with 2317 * 2318 * Removes the currently mapped &drm_gpuva and remaps it using @prev and/or 2319 * @next. 2320 */ 2321 void 2322 drm_gpuva_remap(struct drm_gpuva *prev, 2323 struct drm_gpuva *next, 2324 const struct drm_gpuva_op_remap *op) 2325 { 2326 struct drm_gpuva *va = op->unmap->va; 2327 struct drm_gpuvm *gpuvm = va->vm; 2328 2329 drm_gpuva_remove(va); 2330 2331 if (op->prev) { 2332 drm_gpuva_init_from_op(prev, op->prev); 2333 drm_gpuva_insert(gpuvm, prev); 2334 } 2335 2336 if (op->next) { 2337 drm_gpuva_init_from_op(next, op->next); 2338 drm_gpuva_insert(gpuvm, next); 2339 } 2340 } 2341 EXPORT_SYMBOL_GPL(drm_gpuva_remap); 2342 2343 /** 2344 * drm_gpuva_unmap() - helper to remove a &drm_gpuva according to a 2345 * &drm_gpuva_op_unmap 2346 * @op: the &drm_gpuva_op_unmap specifying the &drm_gpuva to remove 2347 * 2348 * Removes the &drm_gpuva associated with the &drm_gpuva_op_unmap. 2349 */ 2350 void 2351 drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op) 2352 { 2353 drm_gpuva_remove(op->va); 2354 } 2355 EXPORT_SYMBOL_GPL(drm_gpuva_unmap); 2356 2357 static int 2358 op_map_cb(const struct drm_gpuvm_ops *fn, void *priv, 2359 const struct drm_gpuvm_map_req *req) 2360 { 2361 struct drm_gpuva_op op = {}; 2362 2363 if (!req) 2364 return 0; 2365 2366 op.op = DRM_GPUVA_OP_MAP; 2367 op.map.va.addr = req->map.va.addr; 2368 op.map.va.range = req->map.va.range; 2369 op.map.gem.obj = req->map.gem.obj; 2370 op.map.gem.offset = req->map.gem.offset; 2371 2372 return fn->sm_step_map(&op, priv); 2373 } 2374 2375 static int 2376 op_remap_cb(const struct drm_gpuvm_ops *fn, void *priv, 2377 struct drm_gpuva_op_map *prev, 2378 struct drm_gpuva_op_map *next, 2379 struct drm_gpuva_op_unmap *unmap) 2380 { 2381 struct drm_gpuva_op op = {}; 2382 struct drm_gpuva_op_remap *r; 2383 2384 op.op = DRM_GPUVA_OP_REMAP; 2385 r = &op.remap; 2386 r->prev = prev; 2387 r->next = next; 2388 r->unmap = unmap; 2389 2390 return fn->sm_step_remap(&op, priv); 2391 } 2392 2393 static int 2394 op_unmap_cb(const struct drm_gpuvm_ops *fn, void *priv, 2395 struct drm_gpuva *va, bool merge, bool madvise) 2396 { 2397 struct drm_gpuva_op op = {}; 2398 2399 if (madvise) 2400 return 0; 2401 2402 op.op = DRM_GPUVA_OP_UNMAP; 2403 op.unmap.va = va; 2404 op.unmap.keep = merge; 2405 2406 return fn->sm_step_unmap(&op, priv); 2407 } 2408 2409 static int 2410 __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, 2411 const struct drm_gpuvm_ops *ops, void *priv, 2412 const struct drm_gpuvm_map_req *req, 2413 bool madvise) 2414 { 2415 struct drm_gem_object *req_obj = req->map.gem.obj; 2416 const struct drm_gpuvm_map_req *op_map = madvise ? NULL : req; 2417 struct drm_gpuva *va, *next; 2418 u64 req_offset = req->map.gem.offset; 2419 u64 req_range = req->map.va.range; 2420 u64 req_addr = req->map.va.addr; 2421 u64 req_end = req_addr + req_range; 2422 int ret; 2423 2424 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range))) 2425 return -EINVAL; 2426 2427 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) { 2428 struct drm_gem_object *obj = va->gem.obj; 2429 u64 offset = va->gem.offset; 2430 u64 addr = va->va.addr; 2431 u64 range = va->va.range; 2432 u64 end = addr + range; 2433 bool merge = !!va->gem.obj; 2434 2435 if (madvise && obj) 2436 continue; 2437 2438 if (addr == req_addr) { 2439 merge &= obj == req_obj && 2440 offset == req_offset; 2441 2442 if (end == req_end) { 2443 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2444 if (ret) 2445 return ret; 2446 break; 2447 } 2448 2449 if (end < req_end) { 2450 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2451 if (ret) 2452 return ret; 2453 continue; 2454 } 2455 2456 if (end > req_end) { 2457 struct drm_gpuva_op_map n = { 2458 .va.addr = req_end, 2459 .va.range = range - req_range, 2460 .gem.obj = obj, 2461 .gem.offset = offset + req_range, 2462 }; 2463 struct drm_gpuva_op_unmap u = { 2464 .va = va, 2465 .keep = merge, 2466 }; 2467 2468 ret = op_remap_cb(ops, priv, NULL, &n, &u); 2469 if (ret) 2470 return ret; 2471 2472 if (madvise) 2473 op_map = req; 2474 break; 2475 } 2476 } else if (addr < req_addr) { 2477 u64 ls_range = req_addr - addr; 2478 struct drm_gpuva_op_map p = { 2479 .va.addr = addr, 2480 .va.range = ls_range, 2481 .gem.obj = obj, 2482 .gem.offset = offset, 2483 }; 2484 struct drm_gpuva_op_unmap u = { .va = va }; 2485 2486 merge &= obj == req_obj && 2487 offset + ls_range == req_offset; 2488 u.keep = merge; 2489 2490 if (end == req_end) { 2491 ret = op_remap_cb(ops, priv, &p, NULL, &u); 2492 if (ret) 2493 return ret; 2494 2495 if (madvise) 2496 op_map = req; 2497 break; 2498 } 2499 2500 if (end < req_end) { 2501 ret = op_remap_cb(ops, priv, &p, NULL, &u); 2502 if (ret) 2503 return ret; 2504 2505 if (madvise) { 2506 struct drm_gpuvm_map_req map_req = { 2507 .map.va.addr = req_addr, 2508 .map.va.range = end - req_addr, 2509 }; 2510 2511 ret = op_map_cb(ops, priv, &map_req); 2512 if (ret) 2513 return ret; 2514 } 2515 2516 continue; 2517 } 2518 2519 if (end > req_end) { 2520 struct drm_gpuva_op_map n = { 2521 .va.addr = req_end, 2522 .va.range = end - req_end, 2523 .gem.obj = obj, 2524 .gem.offset = offset + ls_range + 2525 req_range, 2526 }; 2527 2528 ret = op_remap_cb(ops, priv, &p, &n, &u); 2529 if (ret) 2530 return ret; 2531 2532 if (madvise) 2533 op_map = req; 2534 break; 2535 } 2536 } else if (addr > req_addr) { 2537 merge &= obj == req_obj && 2538 offset == req_offset + 2539 (addr - req_addr); 2540 2541 if (end == req_end) { 2542 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2543 if (ret) 2544 return ret; 2545 2546 break; 2547 } 2548 2549 if (end < req_end) { 2550 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2551 if (ret) 2552 return ret; 2553 2554 continue; 2555 } 2556 2557 if (end > req_end) { 2558 struct drm_gpuva_op_map n = { 2559 .va.addr = req_end, 2560 .va.range = end - req_end, 2561 .gem.obj = obj, 2562 .gem.offset = offset + req_end - addr, 2563 }; 2564 struct drm_gpuva_op_unmap u = { 2565 .va = va, 2566 .keep = merge, 2567 }; 2568 2569 ret = op_remap_cb(ops, priv, NULL, &n, &u); 2570 if (ret) 2571 return ret; 2572 2573 if (madvise) { 2574 struct drm_gpuvm_map_req map_req = { 2575 .map.va.addr = addr, 2576 .map.va.range = req_end - addr, 2577 }; 2578 2579 return op_map_cb(ops, priv, &map_req); 2580 } 2581 break; 2582 } 2583 } 2584 } 2585 return op_map_cb(ops, priv, op_map); 2586 } 2587 2588 static int 2589 __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, 2590 const struct drm_gpuvm_ops *ops, void *priv, 2591 u64 req_addr, u64 req_range) 2592 { 2593 struct drm_gpuva *va, *next; 2594 u64 req_end = req_addr + req_range; 2595 int ret; 2596 2597 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range))) 2598 return -EINVAL; 2599 2600 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) { 2601 struct drm_gpuva_op_map prev = {}, next = {}; 2602 bool prev_split = false, next_split = false; 2603 struct drm_gem_object *obj = va->gem.obj; 2604 u64 offset = va->gem.offset; 2605 u64 addr = va->va.addr; 2606 u64 range = va->va.range; 2607 u64 end = addr + range; 2608 2609 if (addr < req_addr) { 2610 prev.va.addr = addr; 2611 prev.va.range = req_addr - addr; 2612 prev.gem.obj = obj; 2613 prev.gem.offset = offset; 2614 2615 prev_split = true; 2616 } 2617 2618 if (end > req_end) { 2619 next.va.addr = req_end; 2620 next.va.range = end - req_end; 2621 next.gem.obj = obj; 2622 next.gem.offset = offset + (req_end - addr); 2623 2624 next_split = true; 2625 } 2626 2627 if (prev_split || next_split) { 2628 struct drm_gpuva_op_unmap unmap = { .va = va }; 2629 2630 ret = op_remap_cb(ops, priv, 2631 prev_split ? &prev : NULL, 2632 next_split ? &next : NULL, 2633 &unmap); 2634 if (ret) 2635 return ret; 2636 } else { 2637 ret = op_unmap_cb(ops, priv, va, false, false); 2638 if (ret) 2639 return ret; 2640 } 2641 } 2642 2643 return 0; 2644 } 2645 2646 /** 2647 * drm_gpuvm_sm_map() - calls the &drm_gpuva_op split/merge steps 2648 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2649 * @priv: pointer to a driver private data structure 2650 * @req: ptr to struct drm_gpuvm_map_req 2651 * 2652 * This function iterates the given range of the GPU VA space. It utilizes the 2653 * &drm_gpuvm_ops to call back into the driver providing the split and merge 2654 * steps. 2655 * 2656 * Drivers may use these callbacks to update the GPU VA space right away within 2657 * the callback. In case the driver decides to copy and store the operations for 2658 * later processing neither this function nor &drm_gpuvm_sm_unmap is allowed to 2659 * be called before the &drm_gpuvm's view of the GPU VA space was 2660 * updated with the previous set of operations. To update the 2661 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 2662 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 2663 * used. 2664 * 2665 * A sequence of callbacks can contain map, unmap and remap operations, but 2666 * the sequence of callbacks might also be empty if no operation is required, 2667 * e.g. if the requested mapping already exists in the exact same way. 2668 * 2669 * There can be an arbitrary amount of unmap operations, a maximum of two remap 2670 * operations and a single map operation. The latter one represents the original 2671 * map operation requested by the caller. 2672 * 2673 * Returns: 0 on success or a negative error code 2674 */ 2675 int 2676 drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv, 2677 const struct drm_gpuvm_map_req *req) 2678 { 2679 const struct drm_gpuvm_ops *ops = gpuvm->ops; 2680 2681 if (unlikely(!(ops && ops->sm_step_map && 2682 ops->sm_step_remap && 2683 ops->sm_step_unmap))) 2684 return -EINVAL; 2685 2686 return __drm_gpuvm_sm_map(gpuvm, ops, priv, req, false); 2687 } 2688 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map); 2689 2690 /** 2691 * drm_gpuvm_sm_unmap() - calls the &drm_gpuva_ops to split on unmap 2692 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2693 * @priv: pointer to a driver private data structure 2694 * @req_addr: the start address of the range to unmap 2695 * @req_range: the range of the mappings to unmap 2696 * 2697 * This function iterates the given range of the GPU VA space. It utilizes the 2698 * &drm_gpuvm_ops to call back into the driver providing the operations to 2699 * unmap and, if required, split existing mappings. 2700 * 2701 * Drivers may use these callbacks to update the GPU VA space right away within 2702 * the callback. In case the driver decides to copy and store the operations for 2703 * later processing neither this function nor &drm_gpuvm_sm_map is allowed to be 2704 * called before the &drm_gpuvm's view of the GPU VA space was updated 2705 * with the previous set of operations. To update the &drm_gpuvm's view 2706 * of the GPU VA space drm_gpuva_insert(), drm_gpuva_destroy_locked() and/or 2707 * drm_gpuva_destroy_unlocked() should be used. 2708 * 2709 * A sequence of callbacks can contain unmap and remap operations, depending on 2710 * whether there are actual overlapping mappings to split. 2711 * 2712 * There can be an arbitrary amount of unmap operations and a maximum of two 2713 * remap operations. 2714 * 2715 * Returns: 0 on success or a negative error code 2716 */ 2717 int 2718 drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv, 2719 u64 req_addr, u64 req_range) 2720 { 2721 const struct drm_gpuvm_ops *ops = gpuvm->ops; 2722 2723 if (unlikely(!(ops && ops->sm_step_remap && 2724 ops->sm_step_unmap))) 2725 return -EINVAL; 2726 2727 return __drm_gpuvm_sm_unmap(gpuvm, ops, priv, 2728 req_addr, req_range); 2729 } 2730 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap); 2731 2732 static int 2733 drm_gpuva_sm_step_lock(struct drm_gpuva_op *op, void *priv) 2734 { 2735 struct drm_exec *exec = priv; 2736 2737 switch (op->op) { 2738 case DRM_GPUVA_OP_REMAP: 2739 if (op->remap.unmap->va->gem.obj) 2740 return drm_exec_lock_obj(exec, op->remap.unmap->va->gem.obj); 2741 return 0; 2742 case DRM_GPUVA_OP_UNMAP: 2743 if (op->unmap.va->gem.obj) 2744 return drm_exec_lock_obj(exec, op->unmap.va->gem.obj); 2745 return 0; 2746 default: 2747 return 0; 2748 } 2749 } 2750 2751 static const struct drm_gpuvm_ops lock_ops = { 2752 .sm_step_map = drm_gpuva_sm_step_lock, 2753 .sm_step_remap = drm_gpuva_sm_step_lock, 2754 .sm_step_unmap = drm_gpuva_sm_step_lock, 2755 }; 2756 2757 /** 2758 * drm_gpuvm_sm_map_exec_lock() - locks the objects touched by a drm_gpuvm_sm_map() 2759 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2760 * @exec: the &drm_exec locking context 2761 * @num_fences: for newly mapped objects, the # of fences to reserve 2762 * @req: ptr to drm_gpuvm_map_req struct 2763 * 2764 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/ 2765 * remapped, and locks+prepares (drm_exec_prepare_object()) objects that 2766 * will be newly mapped. 2767 * 2768 * The expected usage is:: 2769 * 2770 * vm_bind { 2771 * struct drm_exec exec; 2772 * 2773 * // IGNORE_DUPLICATES is required, INTERRUPTIBLE_WAIT is recommended: 2774 * drm_exec_init(&exec, IGNORE_DUPLICATES | INTERRUPTIBLE_WAIT, 0); 2775 * 2776 * drm_exec_until_all_locked (&exec) { 2777 * for_each_vm_bind_operation { 2778 * switch (op->op) { 2779 * case DRIVER_OP_UNMAP: 2780 * ret = drm_gpuvm_sm_unmap_exec_lock(gpuvm, &exec, op->addr, op->range); 2781 * break; 2782 * case DRIVER_OP_MAP: 2783 * ret = drm_gpuvm_sm_map_exec_lock(gpuvm, &exec, num_fences, &req); 2784 * break; 2785 * } 2786 * 2787 * drm_exec_retry_on_contention(&exec); 2788 * if (ret) 2789 * return ret; 2790 * } 2791 * } 2792 * } 2793 * 2794 * This enables all locking to be performed before the driver begins modifying 2795 * the VM. This is safe to do in the case of overlapping DRIVER_VM_BIND_OPs, 2796 * where an earlier op can alter the sequence of steps generated for a later 2797 * op, because the later altered step will involve the same GEM object(s) 2798 * already seen in the earlier locking step. For example: 2799 * 2800 * 1) An earlier driver DRIVER_OP_UNMAP op removes the need for a 2801 * DRM_GPUVA_OP_REMAP/UNMAP step. This is safe because we've already 2802 * locked the GEM object in the earlier DRIVER_OP_UNMAP op. 2803 * 2804 * 2) An earlier DRIVER_OP_MAP op overlaps with a later DRIVER_OP_MAP/UNMAP 2805 * op, introducing a DRM_GPUVA_OP_REMAP/UNMAP that wouldn't have been 2806 * required without the earlier DRIVER_OP_MAP. This is safe because we've 2807 * already locked the GEM object in the earlier DRIVER_OP_MAP step. 2808 * 2809 * Returns: 0 on success or a negative error code 2810 */ 2811 int 2812 drm_gpuvm_sm_map_exec_lock(struct drm_gpuvm *gpuvm, 2813 struct drm_exec *exec, unsigned int num_fences, 2814 struct drm_gpuvm_map_req *req) 2815 { 2816 struct drm_gem_object *req_obj = req->map.gem.obj; 2817 2818 if (req_obj) { 2819 int ret = drm_exec_prepare_obj(exec, req_obj, num_fences); 2820 if (ret) 2821 return ret; 2822 } 2823 2824 return __drm_gpuvm_sm_map(gpuvm, &lock_ops, exec, req, false); 2825 2826 } 2827 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_exec_lock); 2828 2829 /** 2830 * drm_gpuvm_sm_unmap_exec_lock() - locks the objects touched by drm_gpuvm_sm_unmap() 2831 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2832 * @exec: the &drm_exec locking context 2833 * @req_addr: the start address of the range to unmap 2834 * @req_range: the range of the mappings to unmap 2835 * 2836 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/ 2837 * remapped by drm_gpuvm_sm_unmap(). 2838 * 2839 * See drm_gpuvm_sm_map_exec_lock() for expected usage. 2840 * 2841 * Returns: 0 on success or a negative error code 2842 */ 2843 int 2844 drm_gpuvm_sm_unmap_exec_lock(struct drm_gpuvm *gpuvm, struct drm_exec *exec, 2845 u64 req_addr, u64 req_range) 2846 { 2847 return __drm_gpuvm_sm_unmap(gpuvm, &lock_ops, exec, 2848 req_addr, req_range); 2849 } 2850 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_exec_lock); 2851 2852 static struct drm_gpuva_op * 2853 gpuva_op_alloc(struct drm_gpuvm *gpuvm) 2854 { 2855 const struct drm_gpuvm_ops *fn = gpuvm->ops; 2856 struct drm_gpuva_op *op; 2857 2858 if (fn && fn->op_alloc) 2859 op = fn->op_alloc(); 2860 else 2861 op = kzalloc_obj(*op); 2862 2863 if (unlikely(!op)) 2864 return NULL; 2865 2866 return op; 2867 } 2868 2869 static void 2870 gpuva_op_free(struct drm_gpuvm *gpuvm, 2871 struct drm_gpuva_op *op) 2872 { 2873 const struct drm_gpuvm_ops *fn = gpuvm->ops; 2874 2875 if (fn && fn->op_free) 2876 fn->op_free(op); 2877 else 2878 kfree(op); 2879 } 2880 2881 static int 2882 drm_gpuva_sm_step(struct drm_gpuva_op *__op, 2883 void *priv) 2884 { 2885 struct { 2886 struct drm_gpuvm *vm; 2887 struct drm_gpuva_ops *ops; 2888 } *args = priv; 2889 struct drm_gpuvm *gpuvm = args->vm; 2890 struct drm_gpuva_ops *ops = args->ops; 2891 struct drm_gpuva_op *op; 2892 2893 op = gpuva_op_alloc(gpuvm); 2894 if (unlikely(!op)) 2895 goto err; 2896 2897 memcpy(op, __op, sizeof(*op)); 2898 2899 if (op->op == DRM_GPUVA_OP_REMAP) { 2900 struct drm_gpuva_op_remap *__r = &__op->remap; 2901 struct drm_gpuva_op_remap *r = &op->remap; 2902 2903 r->unmap = kmemdup(__r->unmap, sizeof(*r->unmap), 2904 GFP_KERNEL); 2905 if (unlikely(!r->unmap)) 2906 goto err_free_op; 2907 2908 if (__r->prev) { 2909 r->prev = kmemdup(__r->prev, sizeof(*r->prev), 2910 GFP_KERNEL); 2911 if (unlikely(!r->prev)) 2912 goto err_free_unmap; 2913 } 2914 2915 if (__r->next) { 2916 r->next = kmemdup(__r->next, sizeof(*r->next), 2917 GFP_KERNEL); 2918 if (unlikely(!r->next)) 2919 goto err_free_prev; 2920 } 2921 } 2922 2923 list_add_tail(&op->entry, &ops->list); 2924 2925 return 0; 2926 2927 err_free_unmap: 2928 kfree(op->remap.unmap); 2929 err_free_prev: 2930 kfree(op->remap.prev); 2931 err_free_op: 2932 gpuva_op_free(gpuvm, op); 2933 err: 2934 return -ENOMEM; 2935 } 2936 2937 static const struct drm_gpuvm_ops gpuvm_list_ops = { 2938 .sm_step_map = drm_gpuva_sm_step, 2939 .sm_step_remap = drm_gpuva_sm_step, 2940 .sm_step_unmap = drm_gpuva_sm_step, 2941 }; 2942 2943 static struct drm_gpuva_ops * 2944 __drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, 2945 const struct drm_gpuvm_map_req *req, 2946 bool madvise) 2947 { 2948 struct drm_gpuva_ops *ops; 2949 struct { 2950 struct drm_gpuvm *vm; 2951 struct drm_gpuva_ops *ops; 2952 } args; 2953 int ret; 2954 2955 ops = kzalloc_obj(*ops); 2956 if (unlikely(!ops)) 2957 return ERR_PTR(-ENOMEM); 2958 2959 INIT_LIST_HEAD(&ops->list); 2960 2961 args.vm = gpuvm; 2962 args.ops = ops; 2963 2964 ret = __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args, req, madvise); 2965 if (ret) 2966 goto err_free_ops; 2967 2968 return ops; 2969 2970 err_free_ops: 2971 drm_gpuva_ops_free(gpuvm, ops); 2972 return ERR_PTR(ret); 2973 } 2974 2975 /** 2976 * drm_gpuvm_sm_map_ops_create() - creates the &drm_gpuva_ops to split and merge 2977 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2978 * @req: map request arguments 2979 * 2980 * This function creates a list of operations to perform splitting and merging 2981 * of existing mapping(s) with the newly requested one. 2982 * 2983 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 2984 * in the given order. It can contain map, unmap and remap operations, but it 2985 * also can be empty if no operation is required, e.g. if the requested mapping 2986 * already exists in the exact same way. 2987 * 2988 * There can be an arbitrary amount of unmap operations, a maximum of two remap 2989 * operations and a single map operation. The latter one represents the original 2990 * map operation requested by the caller. 2991 * 2992 * Note that before calling this function again with another mapping request it 2993 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 2994 * previously obtained operations must be either processed or abandoned. To 2995 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 2996 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 2997 * used. 2998 * 2999 * After the caller finished processing the returned &drm_gpuva_ops, they must 3000 * be freed with &drm_gpuva_ops_free. 3001 * 3002 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3003 */ 3004 struct drm_gpuva_ops * 3005 drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, 3006 const struct drm_gpuvm_map_req *req) 3007 { 3008 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, false); 3009 } 3010 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create); 3011 3012 /** 3013 * drm_gpuvm_madvise_ops_create() - creates the &drm_gpuva_ops to split 3014 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3015 * @req: map request arguments 3016 * 3017 * This function creates a list of operations to perform splitting 3018 * of existent mapping(s) at start or end, based on the request map. 3019 * 3020 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3021 * in the given order. It can contain map and remap operations, but it 3022 * also can be empty if no operation is required, e.g. if the requested mapping 3023 * already exists is the exact same way. 3024 * 3025 * There will be no unmap operations, a maximum of two remap operations and two 3026 * map operations. The two map operations correspond to: one from start to the 3027 * end of drm_gpuvaX, and another from the start of drm_gpuvaY to end. 3028 * 3029 * Note that before calling this function again with another mapping request it 3030 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 3031 * previously obtained operations must be either processed or abandoned. To 3032 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 3033 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 3034 * used. 3035 * 3036 * After the caller finished processing the returned &drm_gpuva_ops, they must 3037 * be freed with &drm_gpuva_ops_free. 3038 * 3039 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3040 */ 3041 struct drm_gpuva_ops * 3042 drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm, 3043 const struct drm_gpuvm_map_req *req) 3044 { 3045 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, true); 3046 } 3047 EXPORT_SYMBOL_GPL(drm_gpuvm_madvise_ops_create); 3048 3049 /** 3050 * drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on 3051 * unmap 3052 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3053 * @req_addr: the start address of the range to unmap 3054 * @req_range: the range of the mappings to unmap 3055 * 3056 * This function creates a list of operations to perform unmapping and, if 3057 * required, splitting of the mappings overlapping the unmap range. 3058 * 3059 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3060 * in the given order. It can contain unmap and remap operations, depending on 3061 * whether there are actual overlapping mappings to split. 3062 * 3063 * There can be an arbitrary amount of unmap operations and a maximum of two 3064 * remap operations. 3065 * 3066 * Note that before calling this function again with another range to unmap it 3067 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 3068 * previously obtained operations must be processed or abandoned. To update the 3069 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 3070 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 3071 * used. 3072 * 3073 * After the caller finished processing the returned &drm_gpuva_ops, they must 3074 * be freed with &drm_gpuva_ops_free. 3075 * 3076 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3077 */ 3078 struct drm_gpuva_ops * 3079 drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm, 3080 u64 req_addr, u64 req_range) 3081 { 3082 struct drm_gpuva_ops *ops; 3083 struct { 3084 struct drm_gpuvm *vm; 3085 struct drm_gpuva_ops *ops; 3086 } args; 3087 int ret; 3088 3089 ops = kzalloc_obj(*ops); 3090 if (unlikely(!ops)) 3091 return ERR_PTR(-ENOMEM); 3092 3093 INIT_LIST_HEAD(&ops->list); 3094 3095 args.vm = gpuvm; 3096 args.ops = ops; 3097 3098 ret = __drm_gpuvm_sm_unmap(gpuvm, &gpuvm_list_ops, &args, 3099 req_addr, req_range); 3100 if (ret) 3101 goto err_free_ops; 3102 3103 return ops; 3104 3105 err_free_ops: 3106 drm_gpuva_ops_free(gpuvm, ops); 3107 return ERR_PTR(ret); 3108 } 3109 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_ops_create); 3110 3111 /** 3112 * drm_gpuvm_prefetch_ops_create() - creates the &drm_gpuva_ops to prefetch 3113 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3114 * @addr: the start address of the range to prefetch 3115 * @range: the range of the mappings to prefetch 3116 * 3117 * This function creates a list of operations to perform prefetching. 3118 * 3119 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3120 * in the given order. It can contain prefetch operations. 3121 * 3122 * There can be an arbitrary amount of prefetch operations. 3123 * 3124 * After the caller finished processing the returned &drm_gpuva_ops, they must 3125 * be freed with &drm_gpuva_ops_free. 3126 * 3127 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3128 */ 3129 struct drm_gpuva_ops * 3130 drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm, 3131 u64 addr, u64 range) 3132 { 3133 struct drm_gpuva_ops *ops; 3134 struct drm_gpuva_op *op; 3135 struct drm_gpuva *va; 3136 u64 end = addr + range; 3137 int ret; 3138 3139 ops = kzalloc_obj(*ops); 3140 if (!ops) 3141 return ERR_PTR(-ENOMEM); 3142 3143 INIT_LIST_HEAD(&ops->list); 3144 3145 drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) { 3146 op = gpuva_op_alloc(gpuvm); 3147 if (!op) { 3148 ret = -ENOMEM; 3149 goto err_free_ops; 3150 } 3151 3152 op->op = DRM_GPUVA_OP_PREFETCH; 3153 op->prefetch.va = va; 3154 list_add_tail(&op->entry, &ops->list); 3155 } 3156 3157 return ops; 3158 3159 err_free_ops: 3160 drm_gpuva_ops_free(gpuvm, ops); 3161 return ERR_PTR(ret); 3162 } 3163 EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create); 3164 3165 /** 3166 * drm_gpuvm_bo_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM 3167 * @vm_bo: the &drm_gpuvm_bo abstraction 3168 * 3169 * This function creates a list of operations to perform unmapping for every 3170 * GPUVA attached to a GEM. 3171 * 3172 * The list can be iterated with &drm_gpuva_for_each_op and consists out of an 3173 * arbitrary amount of unmap operations. 3174 * 3175 * After the caller finished processing the returned &drm_gpuva_ops, they must 3176 * be freed with &drm_gpuva_ops_free. 3177 * 3178 * This function expects the caller to protect the GEM's GPUVA list against 3179 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex. 3180 * 3181 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3182 */ 3183 struct drm_gpuva_ops * 3184 drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo) 3185 { 3186 struct drm_gpuva_ops *ops; 3187 struct drm_gpuva_op *op; 3188 struct drm_gpuva *va; 3189 int ret; 3190 3191 drm_gem_gpuva_assert_lock_held(vm_bo->vm, vm_bo->obj); 3192 3193 ops = kzalloc_obj(*ops); 3194 if (!ops) 3195 return ERR_PTR(-ENOMEM); 3196 3197 INIT_LIST_HEAD(&ops->list); 3198 3199 drm_gpuvm_bo_for_each_va(va, vm_bo) { 3200 op = gpuva_op_alloc(vm_bo->vm); 3201 if (!op) { 3202 ret = -ENOMEM; 3203 goto err_free_ops; 3204 } 3205 3206 op->op = DRM_GPUVA_OP_UNMAP; 3207 op->unmap.va = va; 3208 list_add_tail(&op->entry, &ops->list); 3209 } 3210 3211 return ops; 3212 3213 err_free_ops: 3214 drm_gpuva_ops_free(vm_bo->vm, ops); 3215 return ERR_PTR(ret); 3216 } 3217 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_unmap_ops_create); 3218 3219 /** 3220 * drm_gpuva_ops_free() - free the given &drm_gpuva_ops 3221 * @gpuvm: the &drm_gpuvm the ops were created for 3222 * @ops: the &drm_gpuva_ops to free 3223 * 3224 * Frees the given &drm_gpuva_ops structure including all the ops associated 3225 * with it. 3226 */ 3227 void 3228 drm_gpuva_ops_free(struct drm_gpuvm *gpuvm, 3229 struct drm_gpuva_ops *ops) 3230 { 3231 struct drm_gpuva_op *op, *next; 3232 3233 drm_gpuva_for_each_op_safe(op, next, ops) { 3234 list_del(&op->entry); 3235 3236 if (op->op == DRM_GPUVA_OP_REMAP) { 3237 kfree(op->remap.prev); 3238 kfree(op->remap.next); 3239 kfree(op->remap.unmap); 3240 } 3241 3242 gpuva_op_free(gpuvm, op); 3243 } 3244 3245 kfree(ops); 3246 } 3247 EXPORT_SYMBOL_GPL(drm_gpuva_ops_free); 3248 3249 MODULE_DESCRIPTION("DRM GPUVM"); 3250 MODULE_LICENSE("GPL"); 3251