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 unsigned long index; 1561 1562 drm_exec_for_each_locked_object(exec, index, obj) { 1563 dma_resv_assert_held(obj->resv); 1564 dma_resv_add_fence(obj->resv, fence, 1565 drm_gpuvm_is_extobj(gpuvm, obj) ? 1566 extobj_usage : private_usage); 1567 } 1568 } 1569 EXPORT_SYMBOL_GPL(drm_gpuvm_resv_add_fence); 1570 1571 /** 1572 * drm_gpuvm_bo_create() - create a new instance of struct drm_gpuvm_bo 1573 * @gpuvm: The &drm_gpuvm the @obj is mapped in. 1574 * @obj: The &drm_gem_object being mapped in the @gpuvm. 1575 * 1576 * If provided by the driver, this function uses the &drm_gpuvm_ops 1577 * vm_bo_alloc() callback to allocate. 1578 * 1579 * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure 1580 */ 1581 struct drm_gpuvm_bo * 1582 drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm, 1583 struct drm_gem_object *obj) 1584 { 1585 const struct drm_gpuvm_ops *ops = gpuvm->ops; 1586 struct drm_gpuvm_bo *vm_bo; 1587 1588 if (ops && ops->vm_bo_alloc) 1589 vm_bo = ops->vm_bo_alloc(); 1590 else 1591 vm_bo = kzalloc_obj(*vm_bo); 1592 1593 if (unlikely(!vm_bo)) 1594 return NULL; 1595 1596 vm_bo->vm = drm_gpuvm_get(gpuvm); 1597 vm_bo->obj = obj; 1598 drm_gem_object_get(obj); 1599 1600 kref_init(&vm_bo->kref); 1601 INIT_LIST_HEAD(&vm_bo->list.gpuva); 1602 INIT_LIST_HEAD(&vm_bo->list.entry.gem); 1603 1604 INIT_LIST_HEAD(&vm_bo->list.entry.extobj); 1605 INIT_LIST_HEAD(&vm_bo->list.entry.evict); 1606 init_llist_node(&vm_bo->list.entry.bo_defer); 1607 1608 return vm_bo; 1609 } 1610 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create); 1611 1612 /* 1613 * drm_gpuvm_bo_destroy_not_in_lists() - final part of drm_gpuvm_bo cleanup 1614 * @vm_bo: the &drm_gpuvm_bo to destroy 1615 * 1616 * It is illegal to call this method if the @vm_bo is present in the GEMs gpuva 1617 * list, the extobj list, or the evicted list. 1618 * 1619 * Note that this puts a refcount on the GEM object, which may destroy the GEM 1620 * object if the refcount reaches zero. It's illegal for this to happen if the 1621 * caller holds the GEMs gpuva mutex because it would free the mutex. 1622 */ 1623 static void 1624 drm_gpuvm_bo_destroy_not_in_lists(struct drm_gpuvm_bo *vm_bo) 1625 { 1626 struct drm_gpuvm *gpuvm = vm_bo->vm; 1627 const struct drm_gpuvm_ops *ops = gpuvm->ops; 1628 struct drm_gem_object *obj = vm_bo->obj; 1629 1630 if (ops && ops->vm_bo_free) 1631 ops->vm_bo_free(vm_bo); 1632 else 1633 kfree(vm_bo); 1634 1635 drm_gpuvm_put(gpuvm); 1636 drm_gem_object_put(obj); 1637 } 1638 1639 static void 1640 drm_gpuvm_bo_destroy_not_in_lists_kref(struct kref *kref) 1641 { 1642 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1643 kref); 1644 1645 drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1646 } 1647 1648 static void 1649 drm_gpuvm_bo_destroy(struct kref *kref) 1650 { 1651 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1652 kref); 1653 struct drm_gpuvm *gpuvm = vm_bo->vm; 1654 bool lock = !drm_gpuvm_resv_protected(gpuvm); 1655 1656 if (!lock) 1657 drm_gpuvm_resv_assert_held(gpuvm); 1658 1659 drm_gpuvm_bo_list_del(vm_bo, extobj, lock); 1660 drm_gpuvm_bo_list_del(vm_bo, evict, lock); 1661 1662 drm_gem_gpuva_assert_lock_held(gpuvm, vm_bo->obj); 1663 list_del(&vm_bo->list.entry.gem); 1664 1665 drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1666 } 1667 1668 /** 1669 * drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference 1670 * @vm_bo: the &drm_gpuvm_bo to release the reference of 1671 * 1672 * This releases a reference to @vm_bo. 1673 * 1674 * If the reference count drops to zero, the &gpuvm_bo is destroyed, which 1675 * includes removing it from the GEMs gpuva list. Hence, if a call to this 1676 * function can potentially let the reference count drop to zero the caller must 1677 * hold the lock that the GEM uses for its gpuva list (either the GEM's 1678 * dma-resv or gpuva.lock mutex). 1679 * 1680 * This function may only be called from non-atomic context. 1681 * 1682 * Returns: true if vm_bo was destroyed, false otherwise. 1683 */ 1684 bool 1685 drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo) 1686 { 1687 might_sleep(); 1688 1689 if (vm_bo) 1690 return !!kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy); 1691 1692 return false; 1693 } 1694 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put); 1695 1696 /* 1697 * drm_gpuvm_bo_into_zombie() - called when the vm_bo becomes a zombie due to 1698 * deferred cleanup 1699 * 1700 * If deferred cleanup is used, then this must be called right after the vm_bo 1701 * refcount drops to zero. Must be called with GEM mutex held. After releasing 1702 * the GEM mutex, drm_gpuvm_bo_defer_zombie_cleanup() must be called. 1703 */ 1704 static void 1705 drm_gpuvm_bo_into_zombie(struct kref *kref) 1706 { 1707 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1708 kref); 1709 1710 if (!drm_gpuvm_resv_protected(vm_bo->vm)) { 1711 drm_gpuvm_bo_list_del(vm_bo, extobj, true); 1712 drm_gpuvm_bo_list_del(vm_bo, evict, true); 1713 } 1714 1715 list_del(&vm_bo->list.entry.gem); 1716 } 1717 1718 /* 1719 * drm_gpuvm_bo_defer_zombie_cleanup() - adds a new zombie vm_bo to the 1720 * bo_defer list 1721 * 1722 * Called after drm_gpuvm_bo_into_zombie(). GEM mutex must not be held. 1723 * 1724 * It's important that the GEM stays alive for the duration in which we hold 1725 * the mutex, but the instant we add the vm_bo to bo_defer, another thread 1726 * might call drm_gpuvm_bo_deferred_cleanup() and put the GEM. Therefore, to 1727 * avoid kfreeing a mutex we are holding, the GEM mutex must be released 1728 * *before* calling this function. 1729 */ 1730 static void 1731 drm_gpuvm_bo_defer_zombie_cleanup(struct drm_gpuvm_bo *vm_bo) 1732 { 1733 llist_add(&vm_bo->list.entry.bo_defer, &vm_bo->vm->bo_defer); 1734 } 1735 1736 static void 1737 drm_gpuvm_bo_defer_free(struct kref *kref) 1738 { 1739 struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo, 1740 kref); 1741 1742 drm_gpuvm_bo_into_zombie(kref); 1743 mutex_unlock(&vm_bo->obj->gpuva.lock); 1744 drm_gpuvm_bo_defer_zombie_cleanup(vm_bo); 1745 } 1746 1747 /** 1748 * drm_gpuvm_bo_put_deferred() - drop a struct drm_gpuvm_bo reference with 1749 * deferred cleanup 1750 * @vm_bo: the &drm_gpuvm_bo to release the reference of 1751 * 1752 * This releases a reference to @vm_bo. 1753 * 1754 * This might take and release the GEMs GPUVA lock. You should call 1755 * drm_gpuvm_bo_deferred_cleanup() later to complete the cleanup process. 1756 * 1757 * Returns: true if vm_bo is being destroyed, false otherwise. 1758 */ 1759 bool 1760 drm_gpuvm_bo_put_deferred(struct drm_gpuvm_bo *vm_bo) 1761 { 1762 if (!vm_bo) 1763 return false; 1764 1765 drm_WARN_ON(vm_bo->vm->drm, !drm_gpuvm_immediate_mode(vm_bo->vm)); 1766 1767 return !!kref_put_mutex(&vm_bo->kref, 1768 drm_gpuvm_bo_defer_free, 1769 &vm_bo->obj->gpuva.lock); 1770 } 1771 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put_deferred); 1772 1773 /** 1774 * drm_gpuvm_bo_deferred_cleanup() - clean up BOs in the deferred list 1775 * deferred cleanup 1776 * @gpuvm: the VM to clean up 1777 * 1778 * Cleans up &drm_gpuvm_bo instances in the deferred cleanup list. 1779 */ 1780 void 1781 drm_gpuvm_bo_deferred_cleanup(struct drm_gpuvm *gpuvm) 1782 { 1783 struct drm_gpuvm_bo *vm_bo; 1784 struct llist_node *bo_defer; 1785 1786 bo_defer = llist_del_all(&gpuvm->bo_defer); 1787 if (!bo_defer) 1788 return; 1789 1790 if (drm_gpuvm_resv_protected(gpuvm)) { 1791 dma_resv_lock(drm_gpuvm_resv(gpuvm), NULL); 1792 llist_for_each_entry(vm_bo, bo_defer, list.entry.bo_defer) { 1793 drm_gpuvm_bo_list_del(vm_bo, extobj, false); 1794 drm_gpuvm_bo_list_del(vm_bo, evict, false); 1795 } 1796 dma_resv_unlock(drm_gpuvm_resv(gpuvm)); 1797 } 1798 1799 while (bo_defer) { 1800 vm_bo = llist_entry(bo_defer, struct drm_gpuvm_bo, list.entry.bo_defer); 1801 bo_defer = bo_defer->next; 1802 drm_gpuvm_bo_destroy_not_in_lists(vm_bo); 1803 } 1804 } 1805 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_deferred_cleanup); 1806 1807 static struct drm_gpuvm_bo * 1808 __drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm, 1809 struct drm_gem_object *obj) 1810 { 1811 struct drm_gpuvm_bo *vm_bo; 1812 1813 drm_gem_gpuva_assert_lock_held(gpuvm, obj); 1814 drm_gem_for_each_gpuvm_bo(vm_bo, obj) 1815 if (vm_bo->vm == gpuvm) 1816 return vm_bo; 1817 1818 return NULL; 1819 } 1820 1821 /** 1822 * drm_gpuvm_bo_find() - find the &drm_gpuvm_bo for the given 1823 * &drm_gpuvm and &drm_gem_object 1824 * @gpuvm: The &drm_gpuvm the @obj is mapped in. 1825 * @obj: The &drm_gem_object being mapped in the @gpuvm. 1826 * 1827 * Find the &drm_gpuvm_bo representing the combination of the given 1828 * &drm_gpuvm and &drm_gem_object. If found, increases the reference 1829 * count of the &drm_gpuvm_bo accordingly. 1830 * 1831 * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure 1832 */ 1833 struct drm_gpuvm_bo * 1834 drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm, 1835 struct drm_gem_object *obj) 1836 { 1837 struct drm_gpuvm_bo *vm_bo = __drm_gpuvm_bo_find(gpuvm, obj); 1838 1839 return vm_bo ? drm_gpuvm_bo_get(vm_bo) : NULL; 1840 } 1841 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find); 1842 1843 /** 1844 * drm_gpuvm_bo_obtain_locked() - obtains an instance of the &drm_gpuvm_bo for 1845 * the given &drm_gpuvm and &drm_gem_object 1846 * @gpuvm: The &drm_gpuvm the @obj is mapped in. 1847 * @obj: The &drm_gem_object being mapped in the @gpuvm. 1848 * 1849 * Find the &drm_gpuvm_bo representing the combination of the given 1850 * &drm_gpuvm and &drm_gem_object. If found, increases the reference 1851 * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new 1852 * &drm_gpuvm_bo. 1853 * 1854 * Requires the lock for the GEMs gpuva list. 1855 * 1856 * A new &drm_gpuvm_bo is added to the GEMs gpuva list. 1857 * 1858 * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure 1859 */ 1860 struct drm_gpuvm_bo * 1861 drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm, 1862 struct drm_gem_object *obj) 1863 { 1864 struct drm_gpuvm_bo *vm_bo; 1865 1866 /* 1867 * In immediate mode this would require the caller to hold the GEMs 1868 * gpuva mutex, but it's not okay to allocate while holding that lock, 1869 * and this method allocates. Immediate mode drivers should use 1870 * drm_gpuvm_bo_obtain_prealloc() instead. 1871 */ 1872 drm_WARN_ON(gpuvm->drm, drm_gpuvm_immediate_mode(gpuvm)); 1873 1874 vm_bo = drm_gpuvm_bo_find(gpuvm, obj); 1875 if (vm_bo) 1876 return vm_bo; 1877 1878 vm_bo = drm_gpuvm_bo_create(gpuvm, obj); 1879 if (!vm_bo) 1880 return ERR_PTR(-ENOMEM); 1881 1882 drm_gem_gpuva_assert_lock_held(gpuvm, obj); 1883 list_add_tail(&vm_bo->list.entry.gem, &obj->gpuva.list); 1884 1885 return vm_bo; 1886 } 1887 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_locked); 1888 1889 /** 1890 * drm_gpuvm_bo_obtain_prealloc() - obtains an instance of the &drm_gpuvm_bo 1891 * for the given &drm_gpuvm and &drm_gem_object 1892 * @__vm_bo: A pre-allocated struct drm_gpuvm_bo. 1893 * 1894 * Find the &drm_gpuvm_bo representing the combination of the given 1895 * &drm_gpuvm and &drm_gem_object. If found, increases the reference 1896 * count of the found &drm_gpuvm_bo accordingly, while the @__vm_bo reference 1897 * count is decreased. If not found @__vm_bo is returned without further 1898 * increase of the reference count. 1899 * 1900 * The provided @__vm_bo must not already be in the gpuva, evict, or extobj 1901 * lists prior to calling this method. 1902 * 1903 * A new &drm_gpuvm_bo is added to the GEMs gpuva list. 1904 * 1905 * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing 1906 * &drm_gpuvm_bo was found 1907 */ 1908 struct drm_gpuvm_bo * 1909 drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo) 1910 { 1911 struct drm_gpuvm *gpuvm = __vm_bo->vm; 1912 struct drm_gem_object *obj = __vm_bo->obj; 1913 struct drm_gpuvm_bo *vm_bo; 1914 1915 drm_WARN_ON(gpuvm->drm, !drm_gpuvm_immediate_mode(gpuvm)); 1916 1917 mutex_lock(&obj->gpuva.lock); 1918 vm_bo = drm_gpuvm_bo_find(gpuvm, obj); 1919 if (vm_bo) { 1920 mutex_unlock(&obj->gpuva.lock); 1921 kref_put(&__vm_bo->kref, drm_gpuvm_bo_destroy_not_in_lists_kref); 1922 return vm_bo; 1923 } 1924 1925 drm_gem_gpuva_assert_lock_held(gpuvm, obj); 1926 list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list); 1927 mutex_unlock(&obj->gpuva.lock); 1928 1929 return __vm_bo; 1930 } 1931 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_prealloc); 1932 1933 /** 1934 * drm_gpuvm_bo_extobj_add() - adds the &drm_gpuvm_bo to its &drm_gpuvm's 1935 * extobj list 1936 * @vm_bo: The &drm_gpuvm_bo to add to its &drm_gpuvm's the extobj list. 1937 * 1938 * Adds the given @vm_bo to its &drm_gpuvm's extobj list if not on the list 1939 * already and if the corresponding &drm_gem_object is an external object, 1940 * actually. 1941 */ 1942 void 1943 drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo) 1944 { 1945 struct drm_gpuvm *gpuvm = vm_bo->vm; 1946 bool lock = !drm_gpuvm_resv_protected(gpuvm); 1947 1948 if (!lock) 1949 drm_gpuvm_resv_assert_held(gpuvm); 1950 1951 if (drm_gpuvm_is_extobj(gpuvm, vm_bo->obj)) 1952 drm_gpuvm_bo_list_add(vm_bo, extobj, lock); 1953 } 1954 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_extobj_add); 1955 1956 /** 1957 * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to / from the &drm_gpuvms 1958 * evicted list 1959 * @vm_bo: the &drm_gpuvm_bo to add or remove 1960 * @evict: indicates whether the object is evicted 1961 * 1962 * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvm's evicted list. 1963 */ 1964 void 1965 drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict) 1966 { 1967 struct drm_gpuvm *gpuvm = vm_bo->vm; 1968 struct drm_gem_object *obj = vm_bo->obj; 1969 bool lock = !drm_gpuvm_resv_protected(gpuvm); 1970 1971 dma_resv_assert_held(obj->resv); 1972 vm_bo->evicted = evict; 1973 1974 /* Can't add external objects to the evicted list directly if not using 1975 * internal spinlocks, since in this case the evicted list is protected 1976 * with the VM's common dma-resv lock. 1977 */ 1978 if (drm_gpuvm_is_extobj(gpuvm, obj) && !lock) 1979 return; 1980 1981 if (evict) 1982 drm_gpuvm_bo_list_add(vm_bo, evict, lock); 1983 else 1984 drm_gpuvm_bo_list_del_init(vm_bo, evict, lock); 1985 } 1986 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict); 1987 1988 static int 1989 __drm_gpuva_insert(struct drm_gpuvm *gpuvm, 1990 struct drm_gpuva *va) 1991 { 1992 struct rb_node *node; 1993 struct list_head *head; 1994 1995 if (drm_gpuva_it_iter_first(&gpuvm->rb.tree, 1996 GPUVA_START(va), 1997 GPUVA_LAST(va))) 1998 return -EEXIST; 1999 2000 va->vm = gpuvm; 2001 2002 drm_gpuva_it_insert(va, &gpuvm->rb.tree); 2003 2004 node = rb_prev(&va->rb.node); 2005 if (node) 2006 head = &(to_drm_gpuva(node))->rb.entry; 2007 else 2008 head = &gpuvm->rb.list; 2009 2010 list_add(&va->rb.entry, head); 2011 2012 return 0; 2013 } 2014 2015 /** 2016 * drm_gpuva_insert() - insert a &drm_gpuva 2017 * @gpuvm: the &drm_gpuvm to insert the &drm_gpuva in 2018 * @va: the &drm_gpuva to insert 2019 * 2020 * Insert a &drm_gpuva with a given address and range into a 2021 * &drm_gpuvm. 2022 * 2023 * It is safe to use this function using the safe versions of iterating the GPU 2024 * VA space, such as drm_gpuvm_for_each_va_safe() and 2025 * drm_gpuvm_for_each_va_range_safe(). 2026 * 2027 * Returns: 0 on success, negative error code on failure. 2028 */ 2029 int 2030 drm_gpuva_insert(struct drm_gpuvm *gpuvm, 2031 struct drm_gpuva *va) 2032 { 2033 u64 addr = va->va.addr; 2034 u64 range = va->va.range; 2035 int ret; 2036 2037 if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range))) 2038 return -EINVAL; 2039 2040 ret = __drm_gpuva_insert(gpuvm, va); 2041 if (likely(!ret)) 2042 /* Take a reference of the GPUVM for the successfully inserted 2043 * drm_gpuva. We can't take the reference in 2044 * __drm_gpuva_insert() itself, since we don't want to increse 2045 * the reference count for the GPUVM's kernel_alloc_node. 2046 */ 2047 drm_gpuvm_get(gpuvm); 2048 2049 return ret; 2050 } 2051 EXPORT_SYMBOL_GPL(drm_gpuva_insert); 2052 2053 static void 2054 __drm_gpuva_remove(struct drm_gpuva *va) 2055 { 2056 drm_gpuva_it_remove(va, &va->vm->rb.tree); 2057 list_del_init(&va->rb.entry); 2058 } 2059 2060 /** 2061 * drm_gpuva_remove() - remove a &drm_gpuva 2062 * @va: the &drm_gpuva to remove 2063 * 2064 * This removes the given &va from the underlying tree. 2065 * 2066 * It is safe to use this function using the safe versions of iterating the GPU 2067 * VA space, such as drm_gpuvm_for_each_va_safe() and 2068 * drm_gpuvm_for_each_va_range_safe(). 2069 */ 2070 void 2071 drm_gpuva_remove(struct drm_gpuva *va) 2072 { 2073 struct drm_gpuvm *gpuvm = va->vm; 2074 2075 if (unlikely(va == &gpuvm->kernel_alloc_node)) { 2076 drm_WARN(gpuvm->drm, 1, 2077 "Can't destroy kernel reserved node.\n"); 2078 return; 2079 } 2080 2081 __drm_gpuva_remove(va); 2082 drm_gpuvm_put(va->vm); 2083 } 2084 EXPORT_SYMBOL_GPL(drm_gpuva_remove); 2085 2086 /** 2087 * drm_gpuva_link() - link a &drm_gpuva 2088 * @va: the &drm_gpuva to link 2089 * @vm_bo: the &drm_gpuvm_bo to add the &drm_gpuva to 2090 * 2091 * This adds the given &va to the GPU VA list of the &drm_gpuvm_bo and the 2092 * &drm_gpuvm_bo to the &drm_gem_object it is associated with. 2093 * 2094 * For every &drm_gpuva entry added to the &drm_gpuvm_bo an additional 2095 * reference of the latter is taken. 2096 * 2097 * This function expects the caller to protect the GEM's GPUVA list against 2098 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex. 2099 */ 2100 void 2101 drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo) 2102 { 2103 struct drm_gem_object *obj = va->gem.obj; 2104 struct drm_gpuvm *gpuvm = va->vm; 2105 2106 if (unlikely(!obj)) 2107 return; 2108 2109 drm_WARN_ON(gpuvm->drm, obj != vm_bo->obj); 2110 2111 va->vm_bo = drm_gpuvm_bo_get(vm_bo); 2112 2113 drm_gem_gpuva_assert_lock_held(gpuvm, obj); 2114 list_add_tail(&va->gem.entry, &vm_bo->list.gpuva); 2115 } 2116 EXPORT_SYMBOL_GPL(drm_gpuva_link); 2117 2118 /** 2119 * drm_gpuva_unlink() - unlink a &drm_gpuva 2120 * @va: the &drm_gpuva to unlink 2121 * 2122 * This removes the given &va from the GPU VA list of the &drm_gem_object it is 2123 * associated with. 2124 * 2125 * This removes the given &va from the GPU VA list of the &drm_gpuvm_bo and 2126 * the &drm_gpuvm_bo from the &drm_gem_object it is associated with in case 2127 * this call unlinks the last &drm_gpuva from the &drm_gpuvm_bo. 2128 * 2129 * For every &drm_gpuva entry removed from the &drm_gpuvm_bo a reference of 2130 * the latter is dropped. 2131 * 2132 * This function expects the caller to protect the GEM's GPUVA list against 2133 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex. 2134 */ 2135 void 2136 drm_gpuva_unlink(struct drm_gpuva *va) 2137 { 2138 struct drm_gem_object *obj = va->gem.obj; 2139 struct drm_gpuvm_bo *vm_bo = va->vm_bo; 2140 2141 if (unlikely(!obj)) 2142 return; 2143 2144 drm_gem_gpuva_assert_lock_held(va->vm, obj); 2145 list_del_init(&va->gem.entry); 2146 2147 va->vm_bo = NULL; 2148 drm_gpuvm_bo_put(vm_bo); 2149 } 2150 EXPORT_SYMBOL_GPL(drm_gpuva_unlink); 2151 2152 /** 2153 * drm_gpuva_unlink_defer() - unlink a &drm_gpuva with deferred vm_bo cleanup 2154 * @va: the &drm_gpuva to unlink 2155 * 2156 * Similar to drm_gpuva_unlink(), but uses drm_gpuvm_bo_put_deferred() and takes 2157 * the lock for the caller. 2158 */ 2159 void 2160 drm_gpuva_unlink_defer(struct drm_gpuva *va) 2161 { 2162 struct drm_gem_object *obj = va->gem.obj; 2163 struct drm_gpuvm_bo *vm_bo = va->vm_bo; 2164 bool should_defer_bo; 2165 2166 if (unlikely(!obj)) 2167 return; 2168 2169 drm_WARN_ON(vm_bo->vm->drm, !drm_gpuvm_immediate_mode(vm_bo->vm)); 2170 2171 mutex_lock(&obj->gpuva.lock); 2172 list_del_init(&va->gem.entry); 2173 2174 /* 2175 * This is drm_gpuvm_bo_put_deferred() except we already hold the mutex. 2176 */ 2177 should_defer_bo = kref_put(&vm_bo->kref, drm_gpuvm_bo_into_zombie); 2178 mutex_unlock(&obj->gpuva.lock); 2179 if (should_defer_bo) 2180 drm_gpuvm_bo_defer_zombie_cleanup(vm_bo); 2181 2182 va->vm_bo = NULL; 2183 } 2184 EXPORT_SYMBOL_GPL(drm_gpuva_unlink_defer); 2185 2186 /** 2187 * drm_gpuva_find_first() - find the first &drm_gpuva in the given range 2188 * @gpuvm: the &drm_gpuvm to search in 2189 * @addr: the &drm_gpuvas address 2190 * @range: the &drm_gpuvas range 2191 * 2192 * Returns: the first &drm_gpuva within the given range 2193 */ 2194 struct drm_gpuva * 2195 drm_gpuva_find_first(struct drm_gpuvm *gpuvm, 2196 u64 addr, u64 range) 2197 { 2198 u64 last = addr + range - 1; 2199 2200 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, addr, last); 2201 } 2202 EXPORT_SYMBOL_GPL(drm_gpuva_find_first); 2203 2204 /** 2205 * drm_gpuva_find() - find a &drm_gpuva 2206 * @gpuvm: the &drm_gpuvm to search in 2207 * @addr: the &drm_gpuvas address 2208 * @range: the &drm_gpuvas range 2209 * 2210 * Returns: the &drm_gpuva at a given &addr and with a given &range 2211 */ 2212 struct drm_gpuva * 2213 drm_gpuva_find(struct drm_gpuvm *gpuvm, 2214 u64 addr, u64 range) 2215 { 2216 struct drm_gpuva *va; 2217 2218 va = drm_gpuva_find_first(gpuvm, addr, range); 2219 if (!va) 2220 goto out; 2221 2222 if (va->va.addr != addr || 2223 va->va.range != range) 2224 goto out; 2225 2226 return va; 2227 2228 out: 2229 return NULL; 2230 } 2231 EXPORT_SYMBOL_GPL(drm_gpuva_find); 2232 2233 /** 2234 * drm_gpuva_find_prev() - find the &drm_gpuva before the given address 2235 * @gpuvm: the &drm_gpuvm to search in 2236 * @start: the given GPU VA's start address 2237 * 2238 * Find the adjacent &drm_gpuva before the GPU VA with given &start address. 2239 * 2240 * Note that if there is any free space between the GPU VA mappings no mapping 2241 * is returned. 2242 * 2243 * Returns: a pointer to the found &drm_gpuva or NULL if none was found 2244 */ 2245 struct drm_gpuva * 2246 drm_gpuva_find_prev(struct drm_gpuvm *gpuvm, u64 start) 2247 { 2248 if (!drm_gpuvm_range_valid(gpuvm, start - 1, 1)) 2249 return NULL; 2250 2251 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, start - 1, start); 2252 } 2253 EXPORT_SYMBOL_GPL(drm_gpuva_find_prev); 2254 2255 /** 2256 * drm_gpuva_find_next() - find the &drm_gpuva after the given address 2257 * @gpuvm: the &drm_gpuvm to search in 2258 * @end: the given GPU VA's end address 2259 * 2260 * Find the adjacent &drm_gpuva after the GPU VA with given &end address. 2261 * 2262 * Note that if there is any free space between the GPU VA mappings no mapping 2263 * is returned. 2264 * 2265 * Returns: a pointer to the found &drm_gpuva or NULL if none was found 2266 */ 2267 struct drm_gpuva * 2268 drm_gpuva_find_next(struct drm_gpuvm *gpuvm, u64 end) 2269 { 2270 if (!drm_gpuvm_range_valid(gpuvm, end, 1)) 2271 return NULL; 2272 2273 return drm_gpuva_it_iter_first(&gpuvm->rb.tree, end, end + 1); 2274 } 2275 EXPORT_SYMBOL_GPL(drm_gpuva_find_next); 2276 2277 /** 2278 * drm_gpuvm_interval_empty() - indicate whether a given interval of the VA space 2279 * is empty 2280 * @gpuvm: the &drm_gpuvm to check the range for 2281 * @addr: the start address of the range 2282 * @range: the range of the interval 2283 * 2284 * Returns: true if the interval is empty, false otherwise 2285 */ 2286 bool 2287 drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range) 2288 { 2289 return !drm_gpuva_find_first(gpuvm, addr, range); 2290 } 2291 EXPORT_SYMBOL_GPL(drm_gpuvm_interval_empty); 2292 2293 /** 2294 * drm_gpuva_map() - helper to insert a &drm_gpuva according to a 2295 * &drm_gpuva_op_map 2296 * @gpuvm: the &drm_gpuvm 2297 * @va: the &drm_gpuva to insert 2298 * @op: the &drm_gpuva_op_map to initialize @va with 2299 * 2300 * Initializes the @va from the @op and inserts it into the given @gpuvm. 2301 */ 2302 void 2303 drm_gpuva_map(struct drm_gpuvm *gpuvm, 2304 struct drm_gpuva *va, 2305 const struct drm_gpuva_op_map *op) 2306 { 2307 drm_gpuva_init_from_op(va, op); 2308 drm_gpuva_insert(gpuvm, va); 2309 } 2310 EXPORT_SYMBOL_GPL(drm_gpuva_map); 2311 2312 /** 2313 * drm_gpuva_remap() - helper to remap a &drm_gpuva according to a 2314 * &drm_gpuva_op_remap 2315 * @prev: the &drm_gpuva to remap when keeping the start of a mapping 2316 * @next: the &drm_gpuva to remap when keeping the end of a mapping 2317 * @op: the &drm_gpuva_op_remap to initialize @prev and @next with 2318 * 2319 * Removes the currently mapped &drm_gpuva and remaps it using @prev and/or 2320 * @next. 2321 */ 2322 void 2323 drm_gpuva_remap(struct drm_gpuva *prev, 2324 struct drm_gpuva *next, 2325 const struct drm_gpuva_op_remap *op) 2326 { 2327 struct drm_gpuva *va = op->unmap->va; 2328 struct drm_gpuvm *gpuvm = va->vm; 2329 2330 drm_gpuva_remove(va); 2331 2332 if (op->prev) { 2333 drm_gpuva_init_from_op(prev, op->prev); 2334 drm_gpuva_insert(gpuvm, prev); 2335 } 2336 2337 if (op->next) { 2338 drm_gpuva_init_from_op(next, op->next); 2339 drm_gpuva_insert(gpuvm, next); 2340 } 2341 } 2342 EXPORT_SYMBOL_GPL(drm_gpuva_remap); 2343 2344 /** 2345 * drm_gpuva_unmap() - helper to remove a &drm_gpuva according to a 2346 * &drm_gpuva_op_unmap 2347 * @op: the &drm_gpuva_op_unmap specifying the &drm_gpuva to remove 2348 * 2349 * Removes the &drm_gpuva associated with the &drm_gpuva_op_unmap. 2350 */ 2351 void 2352 drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op) 2353 { 2354 drm_gpuva_remove(op->va); 2355 } 2356 EXPORT_SYMBOL_GPL(drm_gpuva_unmap); 2357 2358 static int 2359 op_map_cb(const struct drm_gpuvm_ops *fn, void *priv, 2360 const struct drm_gpuvm_map_req *req) 2361 { 2362 struct drm_gpuva_op op = {}; 2363 2364 if (!req) 2365 return 0; 2366 2367 op.op = DRM_GPUVA_OP_MAP; 2368 op.map.va.addr = req->map.va.addr; 2369 op.map.va.range = req->map.va.range; 2370 op.map.gem.obj = req->map.gem.obj; 2371 op.map.gem.offset = req->map.gem.offset; 2372 2373 return fn->sm_step_map(&op, priv); 2374 } 2375 2376 static int 2377 op_remap_cb(const struct drm_gpuvm_ops *fn, void *priv, 2378 struct drm_gpuva_op_map *prev, 2379 struct drm_gpuva_op_map *next, 2380 struct drm_gpuva_op_unmap *unmap) 2381 { 2382 struct drm_gpuva_op op = {}; 2383 struct drm_gpuva_op_remap *r; 2384 2385 op.op = DRM_GPUVA_OP_REMAP; 2386 r = &op.remap; 2387 r->prev = prev; 2388 r->next = next; 2389 r->unmap = unmap; 2390 2391 return fn->sm_step_remap(&op, priv); 2392 } 2393 2394 static int 2395 op_unmap_cb(const struct drm_gpuvm_ops *fn, void *priv, 2396 struct drm_gpuva *va, bool merge, bool madvise) 2397 { 2398 struct drm_gpuva_op op = {}; 2399 2400 if (madvise) 2401 return 0; 2402 2403 op.op = DRM_GPUVA_OP_UNMAP; 2404 op.unmap.va = va; 2405 op.unmap.keep = merge; 2406 2407 return fn->sm_step_unmap(&op, priv); 2408 } 2409 2410 static int 2411 __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, 2412 const struct drm_gpuvm_ops *ops, void *priv, 2413 const struct drm_gpuvm_map_req *req, 2414 bool madvise) 2415 { 2416 struct drm_gem_object *req_obj = req->map.gem.obj; 2417 const struct drm_gpuvm_map_req *op_map = madvise ? NULL : req; 2418 struct drm_gpuva *va, *next; 2419 u64 req_offset = req->map.gem.offset; 2420 u64 req_range = req->map.va.range; 2421 u64 req_addr = req->map.va.addr; 2422 u64 req_end = req_addr + req_range; 2423 int ret; 2424 2425 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range))) 2426 return -EINVAL; 2427 2428 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) { 2429 struct drm_gem_object *obj = va->gem.obj; 2430 u64 offset = va->gem.offset; 2431 u64 addr = va->va.addr; 2432 u64 range = va->va.range; 2433 u64 end = addr + range; 2434 bool merge = !!va->gem.obj; 2435 2436 if (madvise && obj) 2437 continue; 2438 2439 if (addr == req_addr) { 2440 merge &= obj == req_obj && 2441 offset == req_offset; 2442 2443 if (end == req_end) { 2444 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2445 if (ret) 2446 return ret; 2447 break; 2448 } 2449 2450 if (end < req_end) { 2451 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2452 if (ret) 2453 return ret; 2454 continue; 2455 } 2456 2457 if (end > req_end) { 2458 struct drm_gpuva_op_map n = { 2459 .va.addr = req_end, 2460 .va.range = range - req_range, 2461 .gem.obj = obj, 2462 .gem.offset = offset + req_range, 2463 }; 2464 struct drm_gpuva_op_unmap u = { 2465 .va = va, 2466 .keep = merge, 2467 }; 2468 2469 ret = op_remap_cb(ops, priv, NULL, &n, &u); 2470 if (ret) 2471 return ret; 2472 2473 if (madvise) 2474 op_map = req; 2475 break; 2476 } 2477 } else if (addr < req_addr) { 2478 u64 ls_range = req_addr - addr; 2479 struct drm_gpuva_op_map p = { 2480 .va.addr = addr, 2481 .va.range = ls_range, 2482 .gem.obj = obj, 2483 .gem.offset = offset, 2484 }; 2485 struct drm_gpuva_op_unmap u = { .va = va }; 2486 2487 merge &= obj == req_obj && 2488 offset + ls_range == req_offset; 2489 u.keep = merge; 2490 2491 if (end == req_end) { 2492 ret = op_remap_cb(ops, priv, &p, NULL, &u); 2493 if (ret) 2494 return ret; 2495 2496 if (madvise) 2497 op_map = req; 2498 break; 2499 } 2500 2501 if (end < req_end) { 2502 ret = op_remap_cb(ops, priv, &p, NULL, &u); 2503 if (ret) 2504 return ret; 2505 2506 if (madvise) { 2507 struct drm_gpuvm_map_req map_req = { 2508 .map.va.addr = req_addr, 2509 .map.va.range = end - req_addr, 2510 }; 2511 2512 ret = op_map_cb(ops, priv, &map_req); 2513 if (ret) 2514 return ret; 2515 } 2516 2517 continue; 2518 } 2519 2520 if (end > req_end) { 2521 struct drm_gpuva_op_map n = { 2522 .va.addr = req_end, 2523 .va.range = end - req_end, 2524 .gem.obj = obj, 2525 .gem.offset = offset + ls_range + 2526 req_range, 2527 }; 2528 2529 ret = op_remap_cb(ops, priv, &p, &n, &u); 2530 if (ret) 2531 return ret; 2532 2533 if (madvise) 2534 op_map = req; 2535 break; 2536 } 2537 } else if (addr > req_addr) { 2538 merge &= obj == req_obj && 2539 offset == req_offset + 2540 (addr - req_addr); 2541 2542 if (end == req_end) { 2543 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2544 if (ret) 2545 return ret; 2546 2547 break; 2548 } 2549 2550 if (end < req_end) { 2551 ret = op_unmap_cb(ops, priv, va, merge, madvise); 2552 if (ret) 2553 return ret; 2554 2555 continue; 2556 } 2557 2558 if (end > req_end) { 2559 struct drm_gpuva_op_map n = { 2560 .va.addr = req_end, 2561 .va.range = end - req_end, 2562 .gem.obj = obj, 2563 .gem.offset = offset + req_end - addr, 2564 }; 2565 struct drm_gpuva_op_unmap u = { 2566 .va = va, 2567 .keep = merge, 2568 }; 2569 2570 ret = op_remap_cb(ops, priv, NULL, &n, &u); 2571 if (ret) 2572 return ret; 2573 2574 if (madvise) { 2575 struct drm_gpuvm_map_req map_req = { 2576 .map.va.addr = addr, 2577 .map.va.range = req_end - addr, 2578 }; 2579 2580 return op_map_cb(ops, priv, &map_req); 2581 } 2582 break; 2583 } 2584 } 2585 } 2586 return op_map_cb(ops, priv, op_map); 2587 } 2588 2589 static int 2590 __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, 2591 const struct drm_gpuvm_ops *ops, void *priv, 2592 u64 req_addr, u64 req_range) 2593 { 2594 struct drm_gpuva *va, *next; 2595 u64 req_end = req_addr + req_range; 2596 int ret; 2597 2598 if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range))) 2599 return -EINVAL; 2600 2601 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) { 2602 struct drm_gpuva_op_map prev = {}, next = {}; 2603 bool prev_split = false, next_split = false; 2604 struct drm_gem_object *obj = va->gem.obj; 2605 u64 offset = va->gem.offset; 2606 u64 addr = va->va.addr; 2607 u64 range = va->va.range; 2608 u64 end = addr + range; 2609 2610 if (addr < req_addr) { 2611 prev.va.addr = addr; 2612 prev.va.range = req_addr - addr; 2613 prev.gem.obj = obj; 2614 prev.gem.offset = offset; 2615 2616 prev_split = true; 2617 } 2618 2619 if (end > req_end) { 2620 next.va.addr = req_end; 2621 next.va.range = end - req_end; 2622 next.gem.obj = obj; 2623 next.gem.offset = offset + (req_end - addr); 2624 2625 next_split = true; 2626 } 2627 2628 if (prev_split || next_split) { 2629 struct drm_gpuva_op_unmap unmap = { .va = va }; 2630 2631 ret = op_remap_cb(ops, priv, 2632 prev_split ? &prev : NULL, 2633 next_split ? &next : NULL, 2634 &unmap); 2635 if (ret) 2636 return ret; 2637 } else { 2638 ret = op_unmap_cb(ops, priv, va, false, false); 2639 if (ret) 2640 return ret; 2641 } 2642 } 2643 2644 return 0; 2645 } 2646 2647 /** 2648 * drm_gpuvm_sm_map() - calls the &drm_gpuva_op split/merge steps 2649 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2650 * @priv: pointer to a driver private data structure 2651 * @req: ptr to struct drm_gpuvm_map_req 2652 * 2653 * This function iterates the given range of the GPU VA space. It utilizes the 2654 * &drm_gpuvm_ops to call back into the driver providing the split and merge 2655 * steps. 2656 * 2657 * Drivers may use these callbacks to update the GPU VA space right away within 2658 * the callback. In case the driver decides to copy and store the operations for 2659 * later processing neither this function nor &drm_gpuvm_sm_unmap is allowed to 2660 * be called before the &drm_gpuvm's view of the GPU VA space was 2661 * updated with the previous set of operations. To update the 2662 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 2663 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 2664 * used. 2665 * 2666 * A sequence of callbacks can contain map, unmap and remap operations, but 2667 * the sequence of callbacks might also be empty if no operation is required, 2668 * e.g. if the requested mapping already exists in the exact same way. 2669 * 2670 * There can be an arbitrary amount of unmap operations, a maximum of two remap 2671 * operations and a single map operation. The latter one represents the original 2672 * map operation requested by the caller. 2673 * 2674 * Returns: 0 on success or a negative error code 2675 */ 2676 int 2677 drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv, 2678 const struct drm_gpuvm_map_req *req) 2679 { 2680 const struct drm_gpuvm_ops *ops = gpuvm->ops; 2681 2682 if (unlikely(!(ops && ops->sm_step_map && 2683 ops->sm_step_remap && 2684 ops->sm_step_unmap))) 2685 return -EINVAL; 2686 2687 return __drm_gpuvm_sm_map(gpuvm, ops, priv, req, false); 2688 } 2689 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map); 2690 2691 /** 2692 * drm_gpuvm_sm_unmap() - calls the &drm_gpuva_ops to split on unmap 2693 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2694 * @priv: pointer to a driver private data structure 2695 * @req_addr: the start address of the range to unmap 2696 * @req_range: the range of the mappings to unmap 2697 * 2698 * This function iterates the given range of the GPU VA space. It utilizes the 2699 * &drm_gpuvm_ops to call back into the driver providing the operations to 2700 * unmap and, if required, split existing mappings. 2701 * 2702 * Drivers may use these callbacks to update the GPU VA space right away within 2703 * the callback. In case the driver decides to copy and store the operations for 2704 * later processing neither this function nor &drm_gpuvm_sm_map is allowed to be 2705 * called before the &drm_gpuvm's view of the GPU VA space was updated 2706 * with the previous set of operations. To update the &drm_gpuvm's view 2707 * of the GPU VA space drm_gpuva_insert(), drm_gpuva_destroy_locked() and/or 2708 * drm_gpuva_destroy_unlocked() should be used. 2709 * 2710 * A sequence of callbacks can contain unmap and remap operations, depending on 2711 * whether there are actual overlapping mappings to split. 2712 * 2713 * There can be an arbitrary amount of unmap operations and a maximum of two 2714 * remap operations. 2715 * 2716 * Returns: 0 on success or a negative error code 2717 */ 2718 int 2719 drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv, 2720 u64 req_addr, u64 req_range) 2721 { 2722 const struct drm_gpuvm_ops *ops = gpuvm->ops; 2723 2724 if (unlikely(!(ops && ops->sm_step_remap && 2725 ops->sm_step_unmap))) 2726 return -EINVAL; 2727 2728 return __drm_gpuvm_sm_unmap(gpuvm, ops, priv, 2729 req_addr, req_range); 2730 } 2731 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap); 2732 2733 static int 2734 drm_gpuva_sm_step_lock(struct drm_gpuva_op *op, void *priv) 2735 { 2736 struct drm_exec *exec = priv; 2737 2738 switch (op->op) { 2739 case DRM_GPUVA_OP_REMAP: 2740 if (op->remap.unmap->va->gem.obj) 2741 return drm_exec_lock_obj(exec, op->remap.unmap->va->gem.obj); 2742 return 0; 2743 case DRM_GPUVA_OP_UNMAP: 2744 if (op->unmap.va->gem.obj) 2745 return drm_exec_lock_obj(exec, op->unmap.va->gem.obj); 2746 return 0; 2747 default: 2748 return 0; 2749 } 2750 } 2751 2752 static const struct drm_gpuvm_ops lock_ops = { 2753 .sm_step_map = drm_gpuva_sm_step_lock, 2754 .sm_step_remap = drm_gpuva_sm_step_lock, 2755 .sm_step_unmap = drm_gpuva_sm_step_lock, 2756 }; 2757 2758 /** 2759 * drm_gpuvm_sm_map_exec_lock() - locks the objects touched by a drm_gpuvm_sm_map() 2760 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2761 * @exec: the &drm_exec locking context 2762 * @num_fences: for newly mapped objects, the # of fences to reserve 2763 * @req: ptr to drm_gpuvm_map_req struct 2764 * 2765 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/ 2766 * remapped, and locks+prepares (drm_exec_prepare_object()) objects that 2767 * will be newly mapped. 2768 * 2769 * The expected usage is:: 2770 * 2771 * vm_bind { 2772 * struct drm_exec exec; 2773 * 2774 * // IGNORE_DUPLICATES is required, INTERRUPTIBLE_WAIT is recommended: 2775 * drm_exec_init(&exec, IGNORE_DUPLICATES | INTERRUPTIBLE_WAIT, 0); 2776 * 2777 * drm_exec_until_all_locked (&exec) { 2778 * for_each_vm_bind_operation { 2779 * switch (op->op) { 2780 * case DRIVER_OP_UNMAP: 2781 * ret = drm_gpuvm_sm_unmap_exec_lock(gpuvm, &exec, op->addr, op->range); 2782 * break; 2783 * case DRIVER_OP_MAP: 2784 * ret = drm_gpuvm_sm_map_exec_lock(gpuvm, &exec, num_fences, &req); 2785 * break; 2786 * } 2787 * 2788 * drm_exec_retry_on_contention(&exec); 2789 * if (ret) 2790 * return ret; 2791 * } 2792 * } 2793 * } 2794 * 2795 * This enables all locking to be performed before the driver begins modifying 2796 * the VM. This is safe to do in the case of overlapping DRIVER_VM_BIND_OPs, 2797 * where an earlier op can alter the sequence of steps generated for a later 2798 * op, because the later altered step will involve the same GEM object(s) 2799 * already seen in the earlier locking step. For example: 2800 * 2801 * 1) An earlier driver DRIVER_OP_UNMAP op removes the need for a 2802 * DRM_GPUVA_OP_REMAP/UNMAP step. This is safe because we've already 2803 * locked the GEM object in the earlier DRIVER_OP_UNMAP op. 2804 * 2805 * 2) An earlier DRIVER_OP_MAP op overlaps with a later DRIVER_OP_MAP/UNMAP 2806 * op, introducing a DRM_GPUVA_OP_REMAP/UNMAP that wouldn't have been 2807 * required without the earlier DRIVER_OP_MAP. This is safe because we've 2808 * already locked the GEM object in the earlier DRIVER_OP_MAP step. 2809 * 2810 * Returns: 0 on success or a negative error code 2811 */ 2812 int 2813 drm_gpuvm_sm_map_exec_lock(struct drm_gpuvm *gpuvm, 2814 struct drm_exec *exec, unsigned int num_fences, 2815 struct drm_gpuvm_map_req *req) 2816 { 2817 struct drm_gem_object *req_obj = req->map.gem.obj; 2818 2819 if (req_obj) { 2820 int ret = drm_exec_prepare_obj(exec, req_obj, num_fences); 2821 if (ret) 2822 return ret; 2823 } 2824 2825 return __drm_gpuvm_sm_map(gpuvm, &lock_ops, exec, req, false); 2826 2827 } 2828 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_exec_lock); 2829 2830 /** 2831 * drm_gpuvm_sm_unmap_exec_lock() - locks the objects touched by drm_gpuvm_sm_unmap() 2832 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2833 * @exec: the &drm_exec locking context 2834 * @req_addr: the start address of the range to unmap 2835 * @req_range: the range of the mappings to unmap 2836 * 2837 * This function locks (drm_exec_lock_obj()) objects that will be unmapped/ 2838 * remapped by drm_gpuvm_sm_unmap(). 2839 * 2840 * See drm_gpuvm_sm_map_exec_lock() for expected usage. 2841 * 2842 * Returns: 0 on success or a negative error code 2843 */ 2844 int 2845 drm_gpuvm_sm_unmap_exec_lock(struct drm_gpuvm *gpuvm, struct drm_exec *exec, 2846 u64 req_addr, u64 req_range) 2847 { 2848 return __drm_gpuvm_sm_unmap(gpuvm, &lock_ops, exec, 2849 req_addr, req_range); 2850 } 2851 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_exec_lock); 2852 2853 static struct drm_gpuva_op * 2854 gpuva_op_alloc(struct drm_gpuvm *gpuvm) 2855 { 2856 const struct drm_gpuvm_ops *fn = gpuvm->ops; 2857 struct drm_gpuva_op *op; 2858 2859 if (fn && fn->op_alloc) 2860 op = fn->op_alloc(); 2861 else 2862 op = kzalloc_obj(*op); 2863 2864 if (unlikely(!op)) 2865 return NULL; 2866 2867 return op; 2868 } 2869 2870 static void 2871 gpuva_op_free(struct drm_gpuvm *gpuvm, 2872 struct drm_gpuva_op *op) 2873 { 2874 const struct drm_gpuvm_ops *fn = gpuvm->ops; 2875 2876 if (fn && fn->op_free) 2877 fn->op_free(op); 2878 else 2879 kfree(op); 2880 } 2881 2882 static int 2883 drm_gpuva_sm_step(struct drm_gpuva_op *__op, 2884 void *priv) 2885 { 2886 struct { 2887 struct drm_gpuvm *vm; 2888 struct drm_gpuva_ops *ops; 2889 } *args = priv; 2890 struct drm_gpuvm *gpuvm = args->vm; 2891 struct drm_gpuva_ops *ops = args->ops; 2892 struct drm_gpuva_op *op; 2893 2894 op = gpuva_op_alloc(gpuvm); 2895 if (unlikely(!op)) 2896 goto err; 2897 2898 memcpy(op, __op, sizeof(*op)); 2899 2900 if (op->op == DRM_GPUVA_OP_REMAP) { 2901 struct drm_gpuva_op_remap *__r = &__op->remap; 2902 struct drm_gpuva_op_remap *r = &op->remap; 2903 2904 r->unmap = kmemdup(__r->unmap, sizeof(*r->unmap), 2905 GFP_KERNEL); 2906 if (unlikely(!r->unmap)) 2907 goto err_free_op; 2908 2909 if (__r->prev) { 2910 r->prev = kmemdup(__r->prev, sizeof(*r->prev), 2911 GFP_KERNEL); 2912 if (unlikely(!r->prev)) 2913 goto err_free_unmap; 2914 } 2915 2916 if (__r->next) { 2917 r->next = kmemdup(__r->next, sizeof(*r->next), 2918 GFP_KERNEL); 2919 if (unlikely(!r->next)) 2920 goto err_free_prev; 2921 } 2922 } 2923 2924 list_add_tail(&op->entry, &ops->list); 2925 2926 return 0; 2927 2928 err_free_unmap: 2929 kfree(op->remap.unmap); 2930 err_free_prev: 2931 kfree(op->remap.prev); 2932 err_free_op: 2933 gpuva_op_free(gpuvm, op); 2934 err: 2935 return -ENOMEM; 2936 } 2937 2938 static const struct drm_gpuvm_ops gpuvm_list_ops = { 2939 .sm_step_map = drm_gpuva_sm_step, 2940 .sm_step_remap = drm_gpuva_sm_step, 2941 .sm_step_unmap = drm_gpuva_sm_step, 2942 }; 2943 2944 static struct drm_gpuva_ops * 2945 __drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, 2946 const struct drm_gpuvm_map_req *req, 2947 bool madvise) 2948 { 2949 struct drm_gpuva_ops *ops; 2950 struct { 2951 struct drm_gpuvm *vm; 2952 struct drm_gpuva_ops *ops; 2953 } args; 2954 int ret; 2955 2956 ops = kzalloc_obj(*ops); 2957 if (unlikely(!ops)) 2958 return ERR_PTR(-ENOMEM); 2959 2960 INIT_LIST_HEAD(&ops->list); 2961 2962 args.vm = gpuvm; 2963 args.ops = ops; 2964 2965 ret = __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args, req, madvise); 2966 if (ret) 2967 goto err_free_ops; 2968 2969 return ops; 2970 2971 err_free_ops: 2972 drm_gpuva_ops_free(gpuvm, ops); 2973 return ERR_PTR(ret); 2974 } 2975 2976 /** 2977 * drm_gpuvm_sm_map_ops_create() - creates the &drm_gpuva_ops to split and merge 2978 * @gpuvm: the &drm_gpuvm representing the GPU VA space 2979 * @req: map request arguments 2980 * 2981 * This function creates a list of operations to perform splitting and merging 2982 * of existing mapping(s) with the newly requested one. 2983 * 2984 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 2985 * in the given order. It can contain map, unmap and remap operations, but it 2986 * also can be empty if no operation is required, e.g. if the requested mapping 2987 * already exists in the exact same way. 2988 * 2989 * There can be an arbitrary amount of unmap operations, a maximum of two remap 2990 * operations and a single map operation. The latter one represents the original 2991 * map operation requested by the caller. 2992 * 2993 * Note that before calling this function again with another mapping request it 2994 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 2995 * previously obtained operations must be either processed or abandoned. To 2996 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 2997 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 2998 * used. 2999 * 3000 * After the caller finished processing the returned &drm_gpuva_ops, they must 3001 * be freed with &drm_gpuva_ops_free. 3002 * 3003 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3004 */ 3005 struct drm_gpuva_ops * 3006 drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, 3007 const struct drm_gpuvm_map_req *req) 3008 { 3009 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, false); 3010 } 3011 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create); 3012 3013 /** 3014 * drm_gpuvm_madvise_ops_create() - creates the &drm_gpuva_ops to split 3015 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3016 * @req: map request arguments 3017 * 3018 * This function creates a list of operations to perform splitting 3019 * of existent mapping(s) at start or end, based on the request map. 3020 * 3021 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3022 * in the given order. It can contain map and remap operations, but it 3023 * also can be empty if no operation is required, e.g. if the requested mapping 3024 * already exists is the exact same way. 3025 * 3026 * There will be no unmap operations, a maximum of two remap operations and two 3027 * map operations. The two map operations correspond to: one from start to the 3028 * end of drm_gpuvaX, and another from the start of drm_gpuvaY to end. 3029 * 3030 * Note that before calling this function again with another mapping request it 3031 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 3032 * previously obtained operations must be either processed or abandoned. To 3033 * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 3034 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 3035 * used. 3036 * 3037 * After the caller finished processing the returned &drm_gpuva_ops, they must 3038 * be freed with &drm_gpuva_ops_free. 3039 * 3040 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3041 */ 3042 struct drm_gpuva_ops * 3043 drm_gpuvm_madvise_ops_create(struct drm_gpuvm *gpuvm, 3044 const struct drm_gpuvm_map_req *req) 3045 { 3046 return __drm_gpuvm_sm_map_ops_create(gpuvm, req, true); 3047 } 3048 EXPORT_SYMBOL_GPL(drm_gpuvm_madvise_ops_create); 3049 3050 /** 3051 * drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on 3052 * unmap 3053 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3054 * @req_addr: the start address of the range to unmap 3055 * @req_range: the range of the mappings to unmap 3056 * 3057 * This function creates a list of operations to perform unmapping and, if 3058 * required, splitting of the mappings overlapping the unmap range. 3059 * 3060 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3061 * in the given order. It can contain unmap and remap operations, depending on 3062 * whether there are actual overlapping mappings to split. 3063 * 3064 * There can be an arbitrary amount of unmap operations and a maximum of two 3065 * remap operations. 3066 * 3067 * Note that before calling this function again with another range to unmap it 3068 * is necessary to update the &drm_gpuvm's view of the GPU VA space. The 3069 * previously obtained operations must be processed or abandoned. To update the 3070 * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(), 3071 * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be 3072 * used. 3073 * 3074 * After the caller finished processing the returned &drm_gpuva_ops, they must 3075 * be freed with &drm_gpuva_ops_free. 3076 * 3077 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3078 */ 3079 struct drm_gpuva_ops * 3080 drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm, 3081 u64 req_addr, u64 req_range) 3082 { 3083 struct drm_gpuva_ops *ops; 3084 struct { 3085 struct drm_gpuvm *vm; 3086 struct drm_gpuva_ops *ops; 3087 } args; 3088 int ret; 3089 3090 ops = kzalloc_obj(*ops); 3091 if (unlikely(!ops)) 3092 return ERR_PTR(-ENOMEM); 3093 3094 INIT_LIST_HEAD(&ops->list); 3095 3096 args.vm = gpuvm; 3097 args.ops = ops; 3098 3099 ret = __drm_gpuvm_sm_unmap(gpuvm, &gpuvm_list_ops, &args, 3100 req_addr, req_range); 3101 if (ret) 3102 goto err_free_ops; 3103 3104 return ops; 3105 3106 err_free_ops: 3107 drm_gpuva_ops_free(gpuvm, ops); 3108 return ERR_PTR(ret); 3109 } 3110 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_ops_create); 3111 3112 /** 3113 * drm_gpuvm_prefetch_ops_create() - creates the &drm_gpuva_ops to prefetch 3114 * @gpuvm: the &drm_gpuvm representing the GPU VA space 3115 * @addr: the start address of the range to prefetch 3116 * @range: the range of the mappings to prefetch 3117 * 3118 * This function creates a list of operations to perform prefetching. 3119 * 3120 * The list can be iterated with &drm_gpuva_for_each_op and must be processed 3121 * in the given order. It can contain prefetch operations. 3122 * 3123 * There can be an arbitrary amount of prefetch operations. 3124 * 3125 * After the caller finished processing the returned &drm_gpuva_ops, they must 3126 * be freed with &drm_gpuva_ops_free. 3127 * 3128 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3129 */ 3130 struct drm_gpuva_ops * 3131 drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm, 3132 u64 addr, u64 range) 3133 { 3134 struct drm_gpuva_ops *ops; 3135 struct drm_gpuva_op *op; 3136 struct drm_gpuva *va; 3137 u64 end = addr + range; 3138 int ret; 3139 3140 ops = kzalloc_obj(*ops); 3141 if (!ops) 3142 return ERR_PTR(-ENOMEM); 3143 3144 INIT_LIST_HEAD(&ops->list); 3145 3146 drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) { 3147 op = gpuva_op_alloc(gpuvm); 3148 if (!op) { 3149 ret = -ENOMEM; 3150 goto err_free_ops; 3151 } 3152 3153 op->op = DRM_GPUVA_OP_PREFETCH; 3154 op->prefetch.va = va; 3155 list_add_tail(&op->entry, &ops->list); 3156 } 3157 3158 return ops; 3159 3160 err_free_ops: 3161 drm_gpuva_ops_free(gpuvm, ops); 3162 return ERR_PTR(ret); 3163 } 3164 EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create); 3165 3166 /** 3167 * drm_gpuvm_bo_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM 3168 * @vm_bo: the &drm_gpuvm_bo abstraction 3169 * 3170 * This function creates a list of operations to perform unmapping for every 3171 * GPUVA attached to a GEM. 3172 * 3173 * The list can be iterated with &drm_gpuva_for_each_op and consists out of an 3174 * arbitrary amount of unmap operations. 3175 * 3176 * After the caller finished processing the returned &drm_gpuva_ops, they must 3177 * be freed with &drm_gpuva_ops_free. 3178 * 3179 * This function expects the caller to protect the GEM's GPUVA list against 3180 * concurrent access using either the GEM's dma-resv or gpuva.lock mutex. 3181 * 3182 * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure 3183 */ 3184 struct drm_gpuva_ops * 3185 drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo) 3186 { 3187 struct drm_gpuva_ops *ops; 3188 struct drm_gpuva_op *op; 3189 struct drm_gpuva *va; 3190 int ret; 3191 3192 drm_gem_gpuva_assert_lock_held(vm_bo->vm, vm_bo->obj); 3193 3194 ops = kzalloc_obj(*ops); 3195 if (!ops) 3196 return ERR_PTR(-ENOMEM); 3197 3198 INIT_LIST_HEAD(&ops->list); 3199 3200 drm_gpuvm_bo_for_each_va(va, vm_bo) { 3201 op = gpuva_op_alloc(vm_bo->vm); 3202 if (!op) { 3203 ret = -ENOMEM; 3204 goto err_free_ops; 3205 } 3206 3207 op->op = DRM_GPUVA_OP_UNMAP; 3208 op->unmap.va = va; 3209 list_add_tail(&op->entry, &ops->list); 3210 } 3211 3212 return ops; 3213 3214 err_free_ops: 3215 drm_gpuva_ops_free(vm_bo->vm, ops); 3216 return ERR_PTR(ret); 3217 } 3218 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_unmap_ops_create); 3219 3220 /** 3221 * drm_gpuva_ops_free() - free the given &drm_gpuva_ops 3222 * @gpuvm: the &drm_gpuvm the ops were created for 3223 * @ops: the &drm_gpuva_ops to free 3224 * 3225 * Frees the given &drm_gpuva_ops structure including all the ops associated 3226 * with it. 3227 */ 3228 void 3229 drm_gpuva_ops_free(struct drm_gpuvm *gpuvm, 3230 struct drm_gpuva_ops *ops) 3231 { 3232 struct drm_gpuva_op *op, *next; 3233 3234 drm_gpuva_for_each_op_safe(op, next, ops) { 3235 list_del(&op->entry); 3236 3237 if (op->op == DRM_GPUVA_OP_REMAP) { 3238 kfree(op->remap.prev); 3239 kfree(op->remap.next); 3240 kfree(op->remap.unmap); 3241 } 3242 3243 gpuva_op_free(gpuvm, op); 3244 } 3245 3246 kfree(ops); 3247 } 3248 EXPORT_SYMBOL_GPL(drm_gpuva_ops_free); 3249 3250 MODULE_DESCRIPTION("DRM GPUVM"); 3251 MODULE_LICENSE("GPL"); 3252