1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* 3 * Copyright © 2024 Intel Corporation 4 * 5 * Authors: 6 * Matthew Brost <matthew.brost@intel.com> 7 */ 8 9 #include <linux/dma-mapping.h> 10 #include <linux/export.h> 11 #include <linux/hmm.h> 12 #include <linux/hugetlb_inline.h> 13 #include <linux/memremap.h> 14 #include <linux/mm_types.h> 15 #include <linux/slab.h> 16 17 #include <drm/drm_device.h> 18 #include <drm/drm_gpusvm.h> 19 #include <drm/drm_pagemap.h> 20 #include <drm/drm_print.h> 21 22 /** 23 * DOC: Overview 24 * 25 * GPU Shared Virtual Memory (GPU SVM) layer for the Direct Rendering Manager (DRM) 26 * is a component of the DRM framework designed to manage shared virtual memory 27 * between the CPU and GPU. It enables efficient data exchange and processing 28 * for GPU-accelerated applications by allowing memory sharing and 29 * synchronization between the CPU's and GPU's virtual address spaces. 30 * 31 * Key GPU SVM Components: 32 * 33 * - Notifiers: 34 * Used for tracking memory intervals and notifying the GPU of changes, 35 * notifiers are sized based on a GPU SVM initialization parameter, with a 36 * recommendation of 512M or larger. They maintain a Red-BlacK tree and a 37 * list of ranges that fall within the notifier interval. Notifiers are 38 * tracked within a GPU SVM Red-BlacK tree and list and are dynamically 39 * inserted or removed as ranges within the interval are created or 40 * destroyed. 41 * - Ranges: 42 * Represent memory ranges mapped in a DRM device and managed by GPU SVM. 43 * They are sized based on an array of chunk sizes, which is a GPU SVM 44 * initialization parameter, and the CPU address space. Upon GPU fault, 45 * the largest aligned chunk that fits within the faulting CPU address 46 * space is chosen for the range size. Ranges are expected to be 47 * dynamically allocated on GPU fault and removed on an MMU notifier UNMAP 48 * event. As mentioned above, ranges are tracked in a notifier's Red-Black 49 * tree. 50 * 51 * - Pages: 52 * struct drm_gpusvm_pages holds the DMA mapping state for a range of 53 * CPU virtual addresses: the DMA mapped device addresses, 54 * the device private pagemap, the IOVA state, the per mapping 55 * notifier sequence number, and the drm_device that owns the DMA 56 * mappings. 57 * A driver embeds one or more struct drm_gpusvm_pages alongside its 58 * struct drm_gpusvm_range, choosing one of two layouts: 59 * 60 * 1:1 - one drm_gpusvm_pages per range (one drm_device). Simplest 61 * layout; to mirror a VA range on several devices a driver uses a 62 * separate range (and notifier) per device, so the HMM fault is taken 63 * once per device. 64 * 65 * N:1 - one drm_gpusvm_pages per drm_device, all sharing one range and 66 * notifier; only the per-device DMA mapping differs. The instances must 67 * sit in contiguous memory so a single drm_gpusvm_range_set_unmapped() 68 * can mark them all. A driver can keep one instance inline for the single 69 * device case and switch to a heap array only when more devices join, 70 * e.g.: 71 * 72 * .. code-block:: c 73 * 74 * struct driver_range { 75 * struct drm_gpusvm_range base; 76 * unsigned int num_pages; // 1: inline_pages, >1: pages[] 77 * union { 78 * struct drm_gpusvm_pages inline_pages; 79 * struct drm_gpusvm_pages *pages; 80 * }; 81 * }; 82 * 83 * In the N:1 case the driver allocates the pages array with a zeroing 84 * allocator (e.g. kcalloc(num_pages, ...)), initialises each entry with 85 * drm_gpusvm_init_pages(), and frees each entry with 86 * drm_gpusvm_free_pages() plus the array itself, from its range free 87 * callback. Each drm_gpusvm_pages is mapped independently by their own 88 * drm_device. 89 * Each drm_gpusvm_pages must be zero-initialised and initialised with 90 * drm_gpusvm_init_pages(), called once per entry. 91 * 92 * - Operations: 93 * Define the interface for driver-specific GPU SVM operations such as 94 * range allocation, notifier allocation, and invalidations. 95 * 96 * - Device Memory Allocations: 97 * Embedded structure containing enough information for GPU SVM to migrate 98 * to / from device memory. 99 * 100 * - Device Memory Operations: 101 * Define the interface for driver-specific device memory operations 102 * release memory, populate pfns, and copy to / from device memory. 103 * 104 * This layer provides interfaces for allocating, mapping, migrating, and 105 * releasing memory ranges between the CPU and GPU. It handles all core memory 106 * management interactions (DMA mapping, HMM, and migration) and provides 107 * driver-specific virtual functions (vfuncs). This infrastructure is sufficient 108 * to build the expected driver components for an SVM implementation as detailed 109 * below. 110 * 111 * Expected Driver Components: 112 * 113 * - GPU page fault handler: 114 * Used to create ranges and notifiers based on the fault address, 115 * optionally migrate the range to device memory, and create GPU bindings. 116 * 117 * - Garbage collector: 118 * Used to unmap and destroy GPU bindings for ranges. Ranges are expected 119 * to be added to the garbage collector upon a MMU_NOTIFY_UNMAP event in 120 * notifier callback. 121 * 122 * - Notifier callback: 123 * Used to invalidate and DMA unmap GPU bindings for ranges. 124 */ 125 126 /** 127 * DOC: Locking 128 * 129 * GPU SVM handles locking for core MM interactions, i.e., it locks/unlocks the 130 * mmap lock as needed. 131 * 132 * GPU SVM introduces a global notifier lock, which safeguards the notifier's 133 * range RB tree and list, as well as the range's DMA mappings and sequence 134 * number. GPU SVM manages all necessary locking and unlocking operations, 135 * except for the recheck range's pages being valid 136 * (drm_gpusvm_pages_valid) when the driver is committing GPU bindings. 137 * This lock corresponds to the ``driver->update`` lock mentioned in 138 * Documentation/mm/hmm.rst. Future revisions may transition from a GPU SVM 139 * global lock to a per-notifier lock if finer-grained locking is deemed 140 * necessary. 141 * 142 * In addition to the locking mentioned above, the driver should implement a 143 * lock to safeguard core GPU SVM function calls that modify state, such as 144 * drm_gpusvm_range_find_or_insert and drm_gpusvm_range_remove. This lock is 145 * denoted as 'driver_svm_lock' in code examples. Finer grained driver side 146 * locking should also be possible for concurrent GPU fault processing within a 147 * single GPU SVM. The 'driver_svm_lock' can be via drm_gpusvm_driver_set_lock 148 * to add annotations to GPU SVM. 149 */ 150 151 /** 152 * DOC: Partial Unmapping of Ranges 153 * 154 * Partial unmapping of ranges (e.g., 1M out of 2M is unmapped by CPU resulting 155 * in MMU_NOTIFY_UNMAP event) presents several challenges, with the main one 156 * being that a subset of the range still has CPU and GPU mappings. If the 157 * backing store for the range is in device memory, a subset of the backing 158 * store has references. One option would be to split the range and device 159 * memory backing store, but the implementation for this would be quite 160 * complicated. Given that partial unmappings are rare and driver-defined range 161 * sizes are relatively small, GPU SVM does not support splitting of ranges. 162 * 163 * With no support for range splitting, upon partial unmapping of a range, the 164 * driver is expected to invalidate and destroy the entire range. If the range 165 * has device memory as its backing, the driver is also expected to migrate any 166 * remaining pages back to RAM. 167 */ 168 169 /** 170 * DOC: Examples 171 * 172 * This section provides three examples of how to build the expected driver 173 * components: the GPU page fault handler, the garbage collector, and the 174 * notifier callback. 175 * 176 * The generic code provided does not include logic for complex migration 177 * policies, optimized invalidations, fined grained driver locking, or other 178 * potentially required driver locking (e.g., DMA-resv locks). 179 * 180 * 1) GPU page fault handler 181 * 182 * .. code-block:: c 183 * 184 * struct driver_range { 185 * struct drm_gpusvm_range base; 186 * struct drm_gpusvm_pages pages; 187 * }; 188 * 189 * int driver_bind_range(struct drm_gpusvm *gpusvm, struct driver_range *drange) 190 * { 191 * int err = 0; 192 * 193 * driver_alloc_and_setup_memory_for_bind(gpusvm, drange); 194 * 195 * drm_gpusvm_notifier_lock(gpusvm); 196 * if (drm_gpusvm_pages_valid(gpusvm, &drange->pages)) 197 * driver_commit_bind(gpusvm, drange); 198 * else 199 * err = -EAGAIN; 200 * drm_gpusvm_notifier_unlock(gpusvm); 201 * 202 * return err; 203 * } 204 * 205 * int driver_gpu_fault(struct drm_gpusvm *gpusvm, unsigned long fault_addr, 206 * unsigned long gpuva_start, unsigned long gpuva_end) 207 * { 208 * struct drm_gpusvm_ctx ctx = {}; 209 * struct driver_range *drange; 210 * struct drm_gpusvm_range *range; 211 * int err; 212 * 213 * driver_svm_lock(); 214 * retry: 215 * // Always process UNMAPs first so view of GPU SVM ranges is current 216 * driver_garbage_collector(gpusvm); 217 * 218 * range = drm_gpusvm_range_find_or_insert(gpusvm, fault_addr, 219 * gpuva_start, gpuva_end, 220 * &ctx); 221 * if (IS_ERR(range)) { 222 * err = PTR_ERR(range); 223 * goto unlock; 224 * } 225 * drange = container_of(range, struct driver_range, base); 226 * 227 * if (driver_migration_policy(range)) { 228 * err = drm_pagemap_populate_mm(driver_choose_drm_pagemap(), 229 * gpuva_start, gpuva_end, gpusvm->mm, 230 * ctx->timeslice_ms); 231 * if (err) // CPU mappings may have changed 232 * goto retry; 233 * } 234 * 235 * err = drm_gpusvm_get_pages(gpusvm, &drange->pages, 236 * gpusvm->mm, &range->notifier->notifier, 237 * drm_gpusvm_range_start(range), 238 * drm_gpusvm_range_end(range), &ctx); 239 * if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) { // CPU mappings changed 240 * if (err == -EOPNOTSUPP) 241 * drm_gpusvm_range_evict(gpusvm, range); 242 * goto retry; 243 * } else if (err) { 244 * goto unlock; 245 * } 246 * 247 * err = driver_bind_range(gpusvm, drange); 248 * if (err == -EAGAIN) // CPU mappings changed 249 * goto retry 250 * 251 * unlock: 252 * driver_svm_unlock(); 253 * return err; 254 * } 255 * 256 * 2) Garbage Collector 257 * 258 * .. code-block:: c 259 * 260 * // The driver owns the drm_gpusvm_pages lifecycle. ops->range_free is 261 * // the final fallback: drm_gpusvm_free_pages() unmaps any 262 * // lingering DMA mapping and a no-op if already unmapped and frees the 263 * // dma_addr array. The normal flow is to DMA unmap before 264 * // drm_gpusvm_range_remove() (before the range leaves the tree). 265 * void driver_range_free(struct drm_gpusvm_range *range) 266 * { 267 * struct driver_range *drange = 268 * container_of(range, struct driver_range, base); 269 * 270 * drm_gpusvm_free_pages(range->gpusvm, &drange->pages, 271 * drm_gpusvm_range_size(range) >> PAGE_SHIFT); 272 * kfree(drange); 273 * } 274 * 275 * void __driver_garbage_collector(struct drm_gpusvm *gpusvm, 276 * struct drm_gpusvm_range *range) 277 * { 278 * assert_driver_svm_locked(gpusvm); 279 * 280 * // Partial unmap, migrate any remaining device memory pages back to RAM 281 * if (range->flags.partial_unmap) 282 * drm_gpusvm_range_evict(gpusvm, range); 283 * 284 * driver_unbind_range(range); 285 * // The pages must be DMA unmapped before drm_gpusvm_range_remove() 286 * // , so a range is never off the MMU interval tree while still DMA 287 * // mapped as the original drmsvm design flow. Otherwise a concurrent CPU 288 * // munmap's notifier could miss this range and free pages still mapped 289 * // for device DMA. This is the normal unmap point. 290 * drm_gpusvm_unmap_pages(gpusvm, &drange->pages, 291 * drm_gpusvm_range_size(range) >> PAGE_SHIFT, 292 * &(struct drm_gpusvm_ctx){ .in_notifier = false }); 293 * drm_gpusvm_range_remove(gpusvm, range); 294 * } 295 * 296 * void driver_garbage_collector(struct drm_gpusvm *gpusvm) 297 * { 298 * assert_driver_svm_locked(gpusvm); 299 * 300 * for_each_range_in_garbage_collector(gpusvm, range) 301 * __driver_garbage_collector(gpusvm, range); 302 * } 303 * 304 * 3) Notifier callback 305 * 306 * .. code-block:: c 307 * 308 * void driver_invalidation(struct drm_gpusvm *gpusvm, 309 * struct drm_gpusvm_notifier *notifier, 310 * const struct mmu_notifier_range *mmu_range) 311 * { 312 * struct drm_gpusvm_ctx ctx = { .in_notifier = true, }; 313 * struct drm_gpusvm_range *range = NULL; 314 * struct driver_range *drange; 315 * 316 * driver_invalidate_device_pages(gpusvm, mmu_range->start, mmu_range->end); 317 * 318 * drm_gpusvm_for_each_range(range, notifier, mmu_range->start, 319 * mmu_range->end) { 320 * drange = container_of(range, struct driver_range, base); 321 * 322 * drm_gpusvm_unmap_pages(gpusvm, &drange->pages, 323 * drm_gpusvm_range_size(range) >> PAGE_SHIFT, 324 * &ctx); 325 * 326 * if (mmu_range->event != MMU_NOTIFY_UNMAP) 327 * continue; 328 * 329 * drm_gpusvm_range_set_unmapped(range, &drange->pages, 1, mmu_range); 330 * driver_garbage_collector_add(gpusvm, range); 331 * } 332 * } 333 */ 334 335 /** 336 * npages_in_range() - Calculate the number of pages in a given range 337 * @start: The start address of the range 338 * @end: The end address of the range 339 * 340 * This macro calculates the number of pages in a given memory range, 341 * specified by the start and end addresses. It divides the difference 342 * between the end and start addresses by the page size (PAGE_SIZE) to 343 * determine the number of pages in the range. 344 * 345 * Return: The number of pages in the specified range. 346 */ 347 static unsigned long 348 npages_in_range(unsigned long start, unsigned long end) 349 { 350 return (end - start) >> PAGE_SHIFT; 351 } 352 353 /** 354 * drm_gpusvm_notifier_find() - Find GPU SVM notifier from GPU SVM 355 * @gpusvm: Pointer to the GPU SVM structure. 356 * @start: Start address of the notifier 357 * @end: End address of the notifier 358 * 359 * Return: A pointer to the drm_gpusvm_notifier if found or NULL 360 */ 361 struct drm_gpusvm_notifier * 362 drm_gpusvm_notifier_find(struct drm_gpusvm *gpusvm, unsigned long start, 363 unsigned long end) 364 { 365 struct interval_tree_node *itree; 366 367 itree = interval_tree_iter_first(&gpusvm->root, start, end - 1); 368 369 if (itree) 370 return container_of(itree, struct drm_gpusvm_notifier, itree); 371 else 372 return NULL; 373 } 374 EXPORT_SYMBOL_GPL(drm_gpusvm_notifier_find); 375 376 /** 377 * drm_gpusvm_range_find() - Find GPU SVM range from GPU SVM notifier 378 * @notifier: Pointer to the GPU SVM notifier structure. 379 * @start: Start address of the range 380 * @end: End address of the range 381 * 382 * Return: A pointer to the drm_gpusvm_range if found or NULL 383 */ 384 struct drm_gpusvm_range * 385 drm_gpusvm_range_find(struct drm_gpusvm_notifier *notifier, unsigned long start, 386 unsigned long end) 387 { 388 struct interval_tree_node *itree; 389 390 itree = interval_tree_iter_first(¬ifier->root, start, end - 1); 391 392 if (itree) 393 return container_of(itree, struct drm_gpusvm_range, itree); 394 else 395 return NULL; 396 } 397 EXPORT_SYMBOL_GPL(drm_gpusvm_range_find); 398 399 /** 400 * drm_gpusvm_notifier_invalidate() - Invalidate a GPU SVM notifier. 401 * @mni: Pointer to the mmu_interval_notifier structure. 402 * @mmu_range: Pointer to the mmu_notifier_range structure. 403 * @cur_seq: Current sequence number. 404 * 405 * This function serves as a generic MMU notifier for GPU SVM. It sets the MMU 406 * notifier sequence number and calls the driver invalidate vfunc under 407 * gpusvm->notifier_lock. 408 * 409 * Return: true if the operation succeeds, false otherwise. 410 */ 411 static bool 412 drm_gpusvm_notifier_invalidate(struct mmu_interval_notifier *mni, 413 const struct mmu_notifier_range *mmu_range, 414 unsigned long cur_seq) 415 { 416 struct drm_gpusvm_notifier *notifier = 417 container_of(mni, typeof(*notifier), notifier); 418 struct drm_gpusvm *gpusvm = notifier->gpusvm; 419 420 if (!mmu_notifier_range_blockable(mmu_range)) 421 return false; 422 423 down_write(&gpusvm->notifier_lock); 424 mmu_interval_set_seq(mni, cur_seq); 425 gpusvm->ops->invalidate(gpusvm, notifier, mmu_range); 426 up_write(&gpusvm->notifier_lock); 427 428 return true; 429 } 430 431 /* 432 * drm_gpusvm_notifier_ops - MMU interval notifier operations for GPU SVM 433 */ 434 static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = { 435 .invalidate = drm_gpusvm_notifier_invalidate, 436 }; 437 438 /** 439 * drm_gpusvm_init() - Initialize the GPU SVM. 440 * @gpusvm: Pointer to the GPU SVM structure. 441 * @name: Name of the GPU SVM. 442 * @mm: Pointer to the mm_struct for the address space. 443 * @mm_start: Start address of GPU SVM. 444 * @mm_range: Range of the GPU SVM. 445 * @notifier_size: Size of individual notifiers. 446 * @ops: Pointer to the operations structure for GPU SVM. 447 * @chunk_sizes: Pointer to the array of chunk sizes used in range allocation. 448 * Entries should be powers of 2 in descending order with last 449 * entry being SZ_4K. 450 * @num_chunks: Number of chunks. 451 * 452 * This function initializes the GPU SVM. 453 * 454 * Note: If only using the simple drm_gpusvm_pages API (get/unmap/free), 455 * then only @gpusvm and @name are expected. The @drm drm_device for dma 456 * mappings is bound per-pages via drm_gpusvm_init_pages() before the first 457 * drm_gpusvm_get_pages() call. However, the same base 458 * @gpusvm can also be used with both modes together in which case the full 459 * setup is needed, where the core drm_gpusvm_pages API will simply never use 460 * the other fields. 461 * 462 * Return: 0 on success, a negative error code on failure. 463 */ 464 int drm_gpusvm_init(struct drm_gpusvm *gpusvm, 465 const char *name, 466 struct mm_struct *mm, 467 unsigned long mm_start, unsigned long mm_range, 468 unsigned long notifier_size, 469 const struct drm_gpusvm_ops *ops, 470 const unsigned long *chunk_sizes, int num_chunks) 471 { 472 if (mm) { 473 if (!ops->invalidate || !num_chunks) 474 return -EINVAL; 475 mmgrab(mm); 476 } else { 477 /* No full SVM mode, only core drm_gpusvm_pages API. */ 478 if (ops || num_chunks || mm_range || notifier_size) 479 return -EINVAL; 480 } 481 482 gpusvm->name = name; 483 gpusvm->mm = mm; 484 gpusvm->mm_start = mm_start; 485 gpusvm->mm_range = mm_range; 486 gpusvm->notifier_size = notifier_size; 487 gpusvm->ops = ops; 488 gpusvm->chunk_sizes = chunk_sizes; 489 gpusvm->num_chunks = num_chunks; 490 491 gpusvm->root = RB_ROOT_CACHED; 492 INIT_LIST_HEAD(&gpusvm->notifier_list); 493 494 init_rwsem(&gpusvm->notifier_lock); 495 496 fs_reclaim_acquire(GFP_KERNEL); 497 might_lock(&gpusvm->notifier_lock); 498 fs_reclaim_release(GFP_KERNEL); 499 500 #ifdef CONFIG_LOCKDEP 501 gpusvm->lock_dep_map = NULL; 502 #endif 503 504 return 0; 505 } 506 EXPORT_SYMBOL_GPL(drm_gpusvm_init); 507 508 /** 509 * to_drm_gpusvm_notifier() - retrieve the container struct for a given rbtree node 510 * @node: a pointer to the rbtree node embedded within a drm_gpusvm_notifier struct 511 * 512 * Return: A pointer to the containing drm_gpusvm_notifier structure. 513 */ 514 static struct drm_gpusvm_notifier *to_drm_gpusvm_notifier(struct rb_node *node) 515 { 516 return container_of(node, struct drm_gpusvm_notifier, itree.rb); 517 } 518 519 /** 520 * drm_gpusvm_notifier_insert() - Insert GPU SVM notifier 521 * @gpusvm: Pointer to the GPU SVM structure 522 * @notifier: Pointer to the GPU SVM notifier structure 523 * 524 * This function inserts the GPU SVM notifier into the GPU SVM RB tree and list. 525 */ 526 static void drm_gpusvm_notifier_insert(struct drm_gpusvm *gpusvm, 527 struct drm_gpusvm_notifier *notifier) 528 { 529 struct rb_node *node; 530 struct list_head *head; 531 532 interval_tree_insert(¬ifier->itree, &gpusvm->root); 533 534 node = rb_prev(¬ifier->itree.rb); 535 if (node) 536 head = &(to_drm_gpusvm_notifier(node))->entry; 537 else 538 head = &gpusvm->notifier_list; 539 540 list_add(¬ifier->entry, head); 541 } 542 543 /** 544 * drm_gpusvm_notifier_remove() - Remove GPU SVM notifier 545 * @gpusvm: Pointer to the GPU SVM tructure 546 * @notifier: Pointer to the GPU SVM notifier structure 547 * 548 * This function removes the GPU SVM notifier from the GPU SVM RB tree and list. 549 */ 550 static void drm_gpusvm_notifier_remove(struct drm_gpusvm *gpusvm, 551 struct drm_gpusvm_notifier *notifier) 552 { 553 interval_tree_remove(¬ifier->itree, &gpusvm->root); 554 list_del(¬ifier->entry); 555 } 556 557 /** 558 * drm_gpusvm_fini() - Finalize the GPU SVM. 559 * @gpusvm: Pointer to the GPU SVM structure. 560 * 561 * This function finalizes the GPU SVM by cleaning up any remaining ranges and 562 * notifiers, and dropping a reference to struct MM. 563 */ 564 void drm_gpusvm_fini(struct drm_gpusvm *gpusvm) 565 { 566 struct drm_gpusvm_notifier *notifier, *next; 567 568 drm_gpusvm_for_each_notifier_safe(notifier, next, gpusvm, 0, LONG_MAX) { 569 struct drm_gpusvm_range *range, *__next; 570 571 /* 572 * Remove notifier first to avoid racing with any invalidation 573 */ 574 mmu_interval_notifier_remove(¬ifier->notifier); 575 notifier->flags.removed = true; 576 577 drm_gpusvm_for_each_range_safe(range, __next, notifier, 0, 578 LONG_MAX) 579 drm_gpusvm_range_remove(gpusvm, range); 580 } 581 582 if (gpusvm->mm) 583 mmdrop(gpusvm->mm); 584 WARN_ON(!RB_EMPTY_ROOT(&gpusvm->root.rb_root)); 585 } 586 EXPORT_SYMBOL_GPL(drm_gpusvm_fini); 587 588 /** 589 * drm_gpusvm_notifier_alloc() - Allocate GPU SVM notifier 590 * @gpusvm: Pointer to the GPU SVM structure 591 * @fault_addr: Fault address 592 * 593 * This function allocates and initializes the GPU SVM notifier structure. 594 * 595 * Return: Pointer to the allocated GPU SVM notifier on success, ERR_PTR() on failure. 596 */ 597 static struct drm_gpusvm_notifier * 598 drm_gpusvm_notifier_alloc(struct drm_gpusvm *gpusvm, unsigned long fault_addr) 599 { 600 struct drm_gpusvm_notifier *notifier; 601 602 if (gpusvm->ops->notifier_alloc) 603 notifier = gpusvm->ops->notifier_alloc(); 604 else 605 notifier = kzalloc_obj(*notifier); 606 607 if (!notifier) 608 return ERR_PTR(-ENOMEM); 609 610 notifier->gpusvm = gpusvm; 611 notifier->itree.start = ALIGN_DOWN(fault_addr, gpusvm->notifier_size); 612 notifier->itree.last = ALIGN(fault_addr + 1, gpusvm->notifier_size) - 1; 613 INIT_LIST_HEAD(¬ifier->entry); 614 notifier->root = RB_ROOT_CACHED; 615 INIT_LIST_HEAD(¬ifier->range_list); 616 617 return notifier; 618 } 619 620 /** 621 * drm_gpusvm_notifier_free() - Free GPU SVM notifier 622 * @gpusvm: Pointer to the GPU SVM structure 623 * @notifier: Pointer to the GPU SVM notifier structure 624 * 625 * This function frees the GPU SVM notifier structure. 626 */ 627 static void drm_gpusvm_notifier_free(struct drm_gpusvm *gpusvm, 628 struct drm_gpusvm_notifier *notifier) 629 { 630 WARN_ON(!RB_EMPTY_ROOT(¬ifier->root.rb_root)); 631 632 if (gpusvm->ops->notifier_free) 633 gpusvm->ops->notifier_free(notifier); 634 else 635 kfree(notifier); 636 } 637 638 /** 639 * to_drm_gpusvm_range() - retrieve the container struct for a given rbtree node 640 * @node: a pointer to the rbtree node embedded within a drm_gpusvm_range struct 641 * 642 * Return: A pointer to the containing drm_gpusvm_range structure. 643 */ 644 static struct drm_gpusvm_range *to_drm_gpusvm_range(struct rb_node *node) 645 { 646 return container_of(node, struct drm_gpusvm_range, itree.rb); 647 } 648 649 /** 650 * drm_gpusvm_range_insert() - Insert GPU SVM range 651 * @notifier: Pointer to the GPU SVM notifier structure 652 * @range: Pointer to the GPU SVM range structure 653 * 654 * This function inserts the GPU SVM range into the notifier RB tree and list. 655 */ 656 static void drm_gpusvm_range_insert(struct drm_gpusvm_notifier *notifier, 657 struct drm_gpusvm_range *range) 658 { 659 struct rb_node *node; 660 struct list_head *head; 661 662 drm_gpusvm_notifier_lock(notifier->gpusvm); 663 interval_tree_insert(&range->itree, ¬ifier->root); 664 665 node = rb_prev(&range->itree.rb); 666 if (node) 667 head = &(to_drm_gpusvm_range(node))->entry; 668 else 669 head = ¬ifier->range_list; 670 671 list_add(&range->entry, head); 672 drm_gpusvm_notifier_unlock(notifier->gpusvm); 673 } 674 675 /** 676 * __drm_gpusvm_range_remove() - Remove GPU SVM range 677 * @notifier: Pointer to the GPU SVM notifier structure 678 * @range: Pointer to the GPU SVM range structure 679 * 680 * This macro removes the GPU SVM range from the notifier RB tree and list. 681 */ 682 static void __drm_gpusvm_range_remove(struct drm_gpusvm_notifier *notifier, 683 struct drm_gpusvm_range *range) 684 { 685 interval_tree_remove(&range->itree, ¬ifier->root); 686 list_del(&range->entry); 687 } 688 689 /** 690 * drm_gpusvm_range_alloc() - Allocate GPU SVM range 691 * @gpusvm: Pointer to the GPU SVM structure 692 * @notifier: Pointer to the GPU SVM notifier structure 693 * @fault_addr: Fault address 694 * @chunk_size: Chunk size 695 * @migrate_devmem: Flag indicating whether to migrate device memory 696 * 697 * This function allocates and initializes the GPU SVM range structure. 698 * 699 * Return: Pointer to the allocated GPU SVM range on success, ERR_PTR() on failure. 700 */ 701 static struct drm_gpusvm_range * 702 drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm, 703 struct drm_gpusvm_notifier *notifier, 704 unsigned long fault_addr, unsigned long chunk_size, 705 bool migrate_devmem) 706 { 707 struct drm_gpusvm_range *range; 708 709 if (gpusvm->ops->range_alloc) 710 range = gpusvm->ops->range_alloc(gpusvm); 711 else 712 range = kzalloc_obj(*range); 713 714 if (!range) 715 return ERR_PTR(-ENOMEM); 716 717 kref_init(&range->refcount); 718 range->gpusvm = gpusvm; 719 range->notifier = notifier; 720 range->itree.start = ALIGN_DOWN(fault_addr, chunk_size); 721 range->itree.last = ALIGN(fault_addr + 1, chunk_size) - 1; 722 INIT_LIST_HEAD(&range->entry); 723 range->flags.migrate_devmem = migrate_devmem ? 1 : 0; 724 725 return range; 726 } 727 728 /** 729 * drm_gpusvm_hmm_pfn_to_order() - Get the largest CPU mapping order. 730 * @hmm_pfn: The current hmm_pfn. 731 * @hmm_pfn_index: Index of the @hmm_pfn within the pfn array. 732 * @npages: Number of pages within the pfn array i.e the hmm range size. 733 * 734 * To allow skipping PFNs with the same flags (like when they belong to 735 * the same huge PTE) when looping over the pfn array, take a given a hmm_pfn, 736 * and return the largest order that will fit inside the CPU PTE, but also 737 * crucially accounting for the original hmm range boundaries. 738 * 739 * Return: The largest order that will safely fit within the size of the hmm_pfn 740 * CPU PTE. 741 */ 742 static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn, 743 unsigned long hmm_pfn_index, 744 unsigned long npages) 745 { 746 unsigned long size; 747 748 size = 1UL << hmm_pfn_to_map_order(hmm_pfn); 749 size -= (hmm_pfn & ~HMM_PFN_FLAGS) & (size - 1); 750 hmm_pfn_index += size; 751 if (hmm_pfn_index > npages) 752 size -= (hmm_pfn_index - npages); 753 754 return ilog2(size); 755 } 756 757 /** 758 * drm_gpusvm_check_pages() - Check pages 759 * @gpusvm: Pointer to the GPU SVM structure 760 * @notifier: Pointer to the GPU SVM notifier structure 761 * @start: Start address 762 * @end: End address 763 * @dev_private_owner: The device private page owner 764 * 765 * Check if pages between start and end have been faulted in on the CPU. Use to 766 * prevent migration of pages without CPU backing store. 767 * 768 * Return: True if pages have been faulted into CPU, False otherwise 769 */ 770 static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm, 771 struct drm_gpusvm_notifier *notifier, 772 unsigned long start, unsigned long end, 773 void *dev_private_owner) 774 { 775 struct hmm_range hmm_range = { 776 .default_flags = 0, 777 .notifier = ¬ifier->notifier, 778 .start = start, 779 .end = end, 780 .dev_private_owner = dev_private_owner, 781 }; 782 unsigned long timeout = 783 jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 784 unsigned long *pfns; 785 unsigned long npages = npages_in_range(start, end); 786 int err, i; 787 788 mmap_assert_locked(gpusvm->mm); 789 790 pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL); 791 if (!pfns) 792 return false; 793 794 hmm_range.notifier_seq = mmu_interval_read_begin(¬ifier->notifier); 795 hmm_range.hmm_pfns = pfns; 796 797 while (true) { 798 err = hmm_range_fault(&hmm_range); 799 if (err == -EBUSY) { 800 if (time_after(jiffies, timeout)) 801 break; 802 803 hmm_range.notifier_seq = 804 mmu_interval_read_begin(¬ifier->notifier); 805 continue; 806 } 807 break; 808 } 809 if (err) 810 goto err_free; 811 812 for (i = 0; i < npages;) { 813 if (!(pfns[i] & HMM_PFN_VALID)) { 814 err = -EFAULT; 815 goto err_free; 816 } 817 i += 0x1 << drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages); 818 } 819 820 err_free: 821 kvfree(pfns); 822 return err ? false : true; 823 } 824 825 /** 826 * drm_gpusvm_scan_mm() - Check the migration state of a drm_gpusvm_range 827 * @range: Pointer to the struct drm_gpusvm_range to check. 828 * @dev_private_owner: The struct dev_private_owner to use to determine 829 * compatible device-private pages. 830 * @pagemap: The struct dev_pagemap pointer to use for pagemap-specific 831 * checks. 832 * 833 * Scan the CPU address space corresponding to @range and return the 834 * current migration state. Note that the result may be invalid as 835 * soon as the function returns. It's an advisory check. 836 * 837 * TODO: Bail early and call hmm_range_fault() for subranges. 838 * 839 * Return: See &enum drm_gpusvm_scan_result. 840 */ 841 enum drm_gpusvm_scan_result drm_gpusvm_scan_mm(struct drm_gpusvm_range *range, 842 void *dev_private_owner, 843 const struct dev_pagemap *pagemap) 844 { 845 struct mmu_interval_notifier *notifier = &range->notifier->notifier; 846 unsigned long start = drm_gpusvm_range_start(range); 847 unsigned long end = drm_gpusvm_range_end(range); 848 struct hmm_range hmm_range = { 849 .default_flags = 0, 850 .notifier = notifier, 851 .start = start, 852 .end = end, 853 .dev_private_owner = dev_private_owner, 854 }; 855 unsigned long timeout = 856 jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 857 enum drm_gpusvm_scan_result state = DRM_GPUSVM_SCAN_UNPOPULATED, new_state; 858 unsigned long *pfns; 859 unsigned long npages = npages_in_range(start, end); 860 const struct dev_pagemap *other = NULL; 861 int err, i; 862 863 pfns = kvcalloc(npages, sizeof(*pfns), GFP_KERNEL); 864 if (!pfns) 865 return DRM_GPUSVM_SCAN_UNPOPULATED; 866 867 hmm_range.hmm_pfns = pfns; 868 869 retry: 870 hmm_range.notifier_seq = mmu_interval_read_begin(notifier); 871 mmap_read_lock(range->gpusvm->mm); 872 873 while (true) { 874 err = hmm_range_fault(&hmm_range); 875 if (err == -EBUSY) { 876 if (time_after(jiffies, timeout)) 877 break; 878 879 hmm_range.notifier_seq = 880 mmu_interval_read_begin(notifier); 881 continue; 882 } 883 break; 884 } 885 mmap_read_unlock(range->gpusvm->mm); 886 if (err) 887 goto err_free; 888 889 drm_gpusvm_notifier_lock(range->gpusvm); 890 if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) { 891 drm_gpusvm_notifier_unlock(range->gpusvm); 892 goto retry; 893 } 894 895 for (i = 0; i < npages;) { 896 struct page *page; 897 const struct dev_pagemap *cur = NULL; 898 899 if (!(pfns[i] & HMM_PFN_VALID)) { 900 state = DRM_GPUSVM_SCAN_UNPOPULATED; 901 break; 902 } 903 904 page = hmm_pfn_to_page(pfns[i]); 905 if (is_device_private_page(page) || 906 is_device_coherent_page(page)) 907 cur = page_pgmap(page); 908 909 if (cur == pagemap) { 910 new_state = DRM_GPUSVM_SCAN_EQUAL; 911 } else if (cur && (cur == other || !other)) { 912 new_state = DRM_GPUSVM_SCAN_OTHER; 913 other = cur; 914 } else if (cur) { 915 new_state = DRM_GPUSVM_SCAN_MIXED_DEVICE; 916 } else { 917 new_state = DRM_GPUSVM_SCAN_SYSTEM; 918 } 919 920 /* 921 * TODO: Could use an array for state 922 * transitions, and caller might want it 923 * to bail early for some results. 924 */ 925 if (state == DRM_GPUSVM_SCAN_UNPOPULATED) { 926 state = new_state; 927 } else if (state != new_state) { 928 if (new_state == DRM_GPUSVM_SCAN_SYSTEM || 929 state == DRM_GPUSVM_SCAN_SYSTEM) 930 state = DRM_GPUSVM_SCAN_MIXED; 931 else if (state != DRM_GPUSVM_SCAN_MIXED) 932 state = DRM_GPUSVM_SCAN_MIXED_DEVICE; 933 } 934 935 i += 1ul << drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages); 936 } 937 938 drm_gpusvm_notifier_unlock(range->gpusvm); 939 940 err_free: 941 kvfree(pfns); 942 return state; 943 } 944 EXPORT_SYMBOL(drm_gpusvm_scan_mm); 945 946 /** 947 * drm_gpusvm_range_chunk_size() - Determine chunk size for GPU SVM range 948 * @gpusvm: Pointer to the GPU SVM structure 949 * @notifier: Pointer to the GPU SVM notifier structure 950 * @vas: Pointer to the virtual memory area structure 951 * @fault_addr: Fault address 952 * @gpuva_start: Start address of GPUVA which mirrors CPU 953 * @gpuva_end: End address of GPUVA which mirrors CPU 954 * @check_pages_threshold: Check CPU pages for present threshold 955 * @dev_private_owner: The device private page owner 956 * 957 * This function determines the chunk size for the GPU SVM range based on the 958 * fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual 959 * memory area boundaries. 960 * 961 * Return: Chunk size on success, LONG_MAX on failure. 962 */ 963 static unsigned long 964 drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm, 965 struct drm_gpusvm_notifier *notifier, 966 struct vm_area_struct *vas, 967 unsigned long fault_addr, 968 unsigned long gpuva_start, 969 unsigned long gpuva_end, 970 unsigned long check_pages_threshold, 971 void *dev_private_owner) 972 { 973 unsigned long start, end; 974 int i = 0; 975 976 retry: 977 for (; i < gpusvm->num_chunks; ++i) { 978 start = ALIGN_DOWN(fault_addr, gpusvm->chunk_sizes[i]); 979 end = ALIGN(fault_addr + 1, gpusvm->chunk_sizes[i]); 980 981 if (start >= vas->vm_start && end <= vas->vm_end && 982 start >= drm_gpusvm_notifier_start(notifier) && 983 end <= drm_gpusvm_notifier_end(notifier) && 984 start >= gpuva_start && end <= gpuva_end) 985 break; 986 } 987 988 if (i == gpusvm->num_chunks) 989 return LONG_MAX; 990 991 /* 992 * If allocation more than page, ensure not to overlap with existing 993 * ranges. 994 */ 995 if (end - start != SZ_4K) { 996 struct drm_gpusvm_range *range; 997 998 range = drm_gpusvm_range_find(notifier, start, end); 999 if (range) { 1000 ++i; 1001 goto retry; 1002 } 1003 1004 /* 1005 * XXX: Only create range on pages CPU has faulted in. Without 1006 * this check, or prefault, on BMG 'xe_exec_system_allocator --r 1007 * process-many-malloc' fails. In the failure case, each process 1008 * mallocs 16k but the CPU VMA is ~128k which results in 64k SVM 1009 * ranges. When migrating the SVM ranges, some processes fail in 1010 * drm_pagemap_migrate_to_devmem with 'migrate.cpages != npages' 1011 * and then upon drm_gpusvm_get_pages device pages from 1012 * other processes are collected + faulted in which creates all 1013 * sorts of problems. Unsure exactly how this happening, also 1014 * problem goes away if 'xe_exec_system_allocator --r 1015 * process-many-malloc' mallocs at least 64k at a time. 1016 */ 1017 if (end - start <= check_pages_threshold && 1018 !drm_gpusvm_check_pages(gpusvm, notifier, start, end, dev_private_owner)) { 1019 ++i; 1020 goto retry; 1021 } 1022 } 1023 1024 return end - start; 1025 } 1026 1027 #ifdef CONFIG_LOCKDEP 1028 /** 1029 * drm_gpusvm_driver_lock_held() - Assert GPU SVM driver lock is held 1030 * @gpusvm: Pointer to the GPU SVM structure. 1031 * 1032 * Ensure driver lock is held. 1033 */ 1034 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm) 1035 { 1036 if ((gpusvm)->lock_dep_map) 1037 lockdep_assert(lock_is_held_type((gpusvm)->lock_dep_map, 0)); 1038 } 1039 #else 1040 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm) 1041 { 1042 } 1043 #endif 1044 1045 /** 1046 * drm_gpusvm_find_vma_start() - Find start address for first VMA in range 1047 * @gpusvm: Pointer to the GPU SVM structure 1048 * @start: The inclusive start user address. 1049 * @end: The exclusive end user address. 1050 * 1051 * Returns: The start address of first VMA within the provided range, 1052 * ULONG_MAX otherwise. Assumes start_addr < end_addr. 1053 */ 1054 unsigned long 1055 drm_gpusvm_find_vma_start(struct drm_gpusvm *gpusvm, 1056 unsigned long start, 1057 unsigned long end) 1058 { 1059 struct mm_struct *mm = gpusvm->mm; 1060 struct vm_area_struct *vma; 1061 unsigned long addr = ULONG_MAX; 1062 1063 if (!mmget_not_zero(mm)) 1064 return addr; 1065 1066 mmap_read_lock(mm); 1067 1068 vma = find_vma_intersection(mm, start, end); 1069 if (vma) 1070 addr = vma->vm_start; 1071 1072 mmap_read_unlock(mm); 1073 mmput(mm); 1074 1075 return addr; 1076 } 1077 EXPORT_SYMBOL_GPL(drm_gpusvm_find_vma_start); 1078 1079 /** 1080 * drm_gpusvm_range_find_or_insert() - Find or insert GPU SVM range 1081 * @gpusvm: Pointer to the GPU SVM structure 1082 * @fault_addr: Fault address 1083 * @gpuva_start: Start address of GPUVA which mirrors CPU 1084 * @gpuva_end: End address of GPUVA which mirrors CPU 1085 * @ctx: GPU SVM context 1086 * 1087 * This function finds or inserts a newly allocated a GPU SVM range based on the 1088 * fault address. Caller must hold a lock to protect range lookup and insertion. 1089 * 1090 * Return: Pointer to the GPU SVM range on success, ERR_PTR() on failure. 1091 */ 1092 struct drm_gpusvm_range * 1093 drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm, 1094 unsigned long fault_addr, 1095 unsigned long gpuva_start, 1096 unsigned long gpuva_end, 1097 const struct drm_gpusvm_ctx *ctx) 1098 { 1099 struct drm_gpusvm_notifier *notifier; 1100 struct drm_gpusvm_range *range; 1101 struct mm_struct *mm = gpusvm->mm; 1102 struct vm_area_struct *vas; 1103 bool notifier_alloc = false; 1104 unsigned long chunk_size; 1105 int err; 1106 bool migrate_devmem; 1107 1108 drm_gpusvm_driver_lock_held(gpusvm); 1109 1110 if (fault_addr < gpusvm->mm_start || 1111 fault_addr > gpusvm->mm_start + gpusvm->mm_range) 1112 return ERR_PTR(-EINVAL); 1113 1114 if (!mmget_not_zero(mm)) 1115 return ERR_PTR(-EFAULT); 1116 1117 notifier = drm_gpusvm_notifier_find(gpusvm, fault_addr, fault_addr + 1); 1118 if (!notifier) { 1119 notifier = drm_gpusvm_notifier_alloc(gpusvm, fault_addr); 1120 if (IS_ERR(notifier)) { 1121 err = PTR_ERR(notifier); 1122 goto err_mmunlock; 1123 } 1124 notifier_alloc = true; 1125 err = mmu_interval_notifier_insert(¬ifier->notifier, 1126 mm, 1127 drm_gpusvm_notifier_start(notifier), 1128 drm_gpusvm_notifier_size(notifier), 1129 &drm_gpusvm_notifier_ops); 1130 if (err) 1131 goto err_notifier; 1132 } 1133 1134 mmap_read_lock(mm); 1135 1136 vas = vma_lookup(mm, fault_addr); 1137 if (!vas) { 1138 err = -ENOENT; 1139 goto err_notifier_remove; 1140 } 1141 1142 if (!ctx->read_only && !(vas->vm_flags & VM_WRITE)) { 1143 err = -EPERM; 1144 goto err_notifier_remove; 1145 } 1146 1147 if (vas->vm_flags & (VM_IO | VM_PFNMAP)) { 1148 err = -EIO; 1149 goto err_notifier_remove; 1150 } 1151 1152 range = drm_gpusvm_range_find(notifier, fault_addr, fault_addr + 1); 1153 if (range) 1154 goto out_mmunlock; 1155 /* 1156 * XXX: Short-circuiting migration based on migrate_vma_* current 1157 * limitations. If/when migrate_vma_* add more support, this logic will 1158 * have to change. 1159 */ 1160 migrate_devmem = ctx->devmem_possible && 1161 vma_is_anonymous(vas) && !is_vm_hugetlb_page(vas); 1162 1163 chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas, 1164 fault_addr, gpuva_start, 1165 gpuva_end, 1166 ctx->check_pages_threshold, 1167 ctx->device_private_page_owner); 1168 if (chunk_size == LONG_MAX) { 1169 err = -EINVAL; 1170 goto err_notifier_remove; 1171 } 1172 1173 range = drm_gpusvm_range_alloc(gpusvm, notifier, fault_addr, chunk_size, 1174 migrate_devmem); 1175 if (IS_ERR(range)) { 1176 err = PTR_ERR(range); 1177 goto err_notifier_remove; 1178 } 1179 1180 drm_gpusvm_range_insert(notifier, range); 1181 if (notifier_alloc) 1182 drm_gpusvm_notifier_insert(gpusvm, notifier); 1183 1184 out_mmunlock: 1185 mmap_read_unlock(mm); 1186 mmput(mm); 1187 1188 return range; 1189 1190 err_notifier_remove: 1191 mmap_read_unlock(mm); 1192 if (notifier_alloc) 1193 mmu_interval_notifier_remove(¬ifier->notifier); 1194 err_notifier: 1195 if (notifier_alloc) 1196 drm_gpusvm_notifier_free(gpusvm, notifier); 1197 err_mmunlock: 1198 mmput(mm); 1199 return ERR_PTR(err); 1200 } 1201 EXPORT_SYMBOL_GPL(drm_gpusvm_range_find_or_insert); 1202 1203 /** 1204 * __drm_gpusvm_unmap_pages() - Unmap pages associated with GPU SVM pages (internal) 1205 * @gpusvm: Pointer to the GPU SVM structure 1206 * @svm_pages: Pointer to the GPU SVM pages structure 1207 * @npages: Number of pages to unmap 1208 * 1209 * This function unmap pages associated with a GPU SVM pages struct. Assumes and 1210 * asserts correct locking is in place when called. 1211 */ 1212 static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, 1213 struct drm_gpusvm_pages *svm_pages, 1214 unsigned long npages) 1215 { 1216 struct drm_pagemap *dpagemap = svm_pages->dpagemap; 1217 struct device *dev; 1218 unsigned long i, j; 1219 1220 lockdep_assert_held(&gpusvm->notifier_lock); 1221 1222 if (!svm_pages->drm) 1223 return; 1224 1225 dev = svm_pages->drm->dev; 1226 1227 if (svm_pages->flags.has_dma_mapping) { 1228 struct drm_gpusvm_pages_flags flags = { 1229 .__flags = svm_pages->flags.__flags, 1230 }; 1231 bool use_iova = dma_use_iova(&svm_pages->state); 1232 1233 /* 1234 * IOVA is reserved for the whole range but only the linked 1235 * system pages (state_offset bytes) need unlinking; free the 1236 * entire reservation to avoid leaking the device-page part. 1237 * On the error path state_offset is 0, so just free it. 1238 */ 1239 if (use_iova) { 1240 if (svm_pages->state_offset) 1241 dma_iova_unlink(dev, &svm_pages->state, 0, 1242 svm_pages->state_offset, 1243 svm_pages->dma_addr[0].dir, 0); 1244 dma_iova_free(dev, &svm_pages->state); 1245 } 1246 1247 for (i = 0, j = 0; i < npages; j++) { 1248 struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j]; 1249 1250 if (addr->proto == DRM_INTERCONNECT_SYSTEM) { 1251 /* 1252 * Linked IOVA pages were already torn down by 1253 * the dma_iova_unlink()/dma_iova_free() above; 1254 * only the non-IOVA mappings need unmap here. 1255 */ 1256 if (!use_iova) 1257 dma_unmap_page(dev, 1258 addr->addr, 1259 PAGE_SIZE << addr->order, 1260 addr->dir); 1261 } else if (dpagemap && dpagemap->ops->device_unmap) 1262 dpagemap->ops->device_unmap(dpagemap, 1263 dev, addr); 1264 i += 1 << addr->order; 1265 } 1266 1267 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1268 flags.has_devmem_pages = false; 1269 flags.has_dma_mapping = false; 1270 WRITE_ONCE(svm_pages->flags.__flags, flags.__flags); 1271 1272 drm_pagemap_put(svm_pages->dpagemap); 1273 svm_pages->dpagemap = NULL; 1274 } 1275 } 1276 1277 /** 1278 * __drm_gpusvm_free_pages() - Free dma array associated with GPU SVM pages 1279 * @gpusvm: Pointer to the GPU SVM structure 1280 * @svm_pages: Pointer to the GPU SVM pages structure 1281 * 1282 * This function frees the dma address array associated with a GPU SVM range. 1283 */ 1284 static void __drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm, 1285 struct drm_gpusvm_pages *svm_pages) 1286 { 1287 lockdep_assert_held(&gpusvm->notifier_lock); 1288 1289 if (svm_pages->dma_addr) { 1290 kvfree(svm_pages->dma_addr); 1291 svm_pages->dma_addr = NULL; 1292 } 1293 } 1294 1295 /** 1296 * drm_gpusvm_free_pages() - Free dma-mapping associated with GPU SVM pages 1297 * struct 1298 * @gpusvm: Pointer to the GPU SVM structure 1299 * @svm_pages: Pointer to the GPU SVM pages structure 1300 * @npages: Number of mapped pages 1301 * 1302 * This function unmaps and frees the dma address array associated with a GPU 1303 * SVM pages struct. 1304 */ 1305 void drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm, 1306 struct drm_gpusvm_pages *svm_pages, 1307 unsigned long npages) 1308 { 1309 drm_gpusvm_notifier_lock(gpusvm); 1310 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages); 1311 __drm_gpusvm_free_pages(gpusvm, svm_pages); 1312 drm_gpusvm_notifier_unlock(gpusvm); 1313 } 1314 EXPORT_SYMBOL_GPL(drm_gpusvm_free_pages); 1315 1316 /** 1317 * drm_gpusvm_range_remove() - Remove GPU SVM range 1318 * @gpusvm: Pointer to the GPU SVM structure 1319 * @range: Pointer to the GPU SVM range to be removed 1320 * 1321 * This function removes the specified GPU SVM range and also removes the parent 1322 * GPU SVM notifier if no more ranges remain in the notifier. The caller must 1323 * hold a lock to protect range and notifier removal. 1324 * 1325 * This function does not unmap or free the drm_gpusvm_pages, the driver owns 1326 * that lifecycle. The caller must DMA unmap the range's pages before calling 1327 * this function, so a range is never removed from the MMU interval tree while 1328 * still DMA mapped. Typically the driver calls drm_gpusvm_unmap_pages() first. 1329 * And the range_free callback's drm_gpusvm_free_pages() is a final fallback safe 1330 * net. 1331 */ 1332 void drm_gpusvm_range_remove(struct drm_gpusvm *gpusvm, 1333 struct drm_gpusvm_range *range) 1334 { 1335 struct drm_gpusvm_notifier *notifier; 1336 1337 drm_gpusvm_driver_lock_held(gpusvm); 1338 1339 notifier = drm_gpusvm_notifier_find(gpusvm, 1340 drm_gpusvm_range_start(range), 1341 drm_gpusvm_range_start(range) + 1); 1342 if (WARN_ON_ONCE(!notifier)) 1343 return; 1344 1345 drm_gpusvm_notifier_lock(gpusvm); 1346 __drm_gpusvm_range_remove(notifier, range); 1347 drm_gpusvm_notifier_unlock(gpusvm); 1348 1349 drm_gpusvm_range_put(range); 1350 1351 if (RB_EMPTY_ROOT(¬ifier->root.rb_root)) { 1352 if (!notifier->flags.removed) 1353 mmu_interval_notifier_remove(¬ifier->notifier); 1354 drm_gpusvm_notifier_remove(gpusvm, notifier); 1355 drm_gpusvm_notifier_free(gpusvm, notifier); 1356 } 1357 } 1358 EXPORT_SYMBOL_GPL(drm_gpusvm_range_remove); 1359 1360 /** 1361 * drm_gpusvm_range_get() - Get a reference to GPU SVM range 1362 * @range: Pointer to the GPU SVM range 1363 * 1364 * This function increments the reference count of the specified GPU SVM range. 1365 * 1366 * Return: Pointer to the GPU SVM range. 1367 */ 1368 struct drm_gpusvm_range * 1369 drm_gpusvm_range_get(struct drm_gpusvm_range *range) 1370 { 1371 kref_get(&range->refcount); 1372 1373 return range; 1374 } 1375 EXPORT_SYMBOL_GPL(drm_gpusvm_range_get); 1376 1377 /** 1378 * drm_gpusvm_range_destroy() - Destroy GPU SVM range 1379 * @refcount: Pointer to the reference counter embedded in the GPU SVM range 1380 * 1381 * This function destroys the specified GPU SVM range when its reference count 1382 * reaches zero. If a custom range-free function is provided, it is invoked to 1383 * free the range; otherwise, the range is deallocated using kfree(). 1384 */ 1385 static void drm_gpusvm_range_destroy(struct kref *refcount) 1386 { 1387 struct drm_gpusvm_range *range = 1388 container_of(refcount, struct drm_gpusvm_range, refcount); 1389 struct drm_gpusvm *gpusvm = range->gpusvm; 1390 1391 if (gpusvm->ops->range_free) 1392 gpusvm->ops->range_free(range); 1393 else 1394 kfree(range); 1395 } 1396 1397 /** 1398 * drm_gpusvm_range_put() - Put a reference to GPU SVM range 1399 * @range: Pointer to the GPU SVM range 1400 * 1401 * This function decrements the reference count of the specified GPU SVM range 1402 * and frees it when the count reaches zero. 1403 */ 1404 void drm_gpusvm_range_put(struct drm_gpusvm_range *range) 1405 { 1406 kref_put(&range->refcount, drm_gpusvm_range_destroy); 1407 } 1408 EXPORT_SYMBOL_GPL(drm_gpusvm_range_put); 1409 1410 /** 1411 * drm_gpusvm_pages_valid() - GPU SVM range pages valid 1412 * @gpusvm: Pointer to the GPU SVM structure 1413 * @svm_pages: Pointer to the GPU SVM pages structure 1414 * 1415 * This function determines if a GPU SVM range pages are valid. Expected be 1416 * called holding gpusvm->notifier_lock and as the last step before committing a 1417 * GPU binding. This is akin to a notifier seqno check in the HMM documentation 1418 * but due to wider notifiers (i.e., notifiers which span multiple ranges) this 1419 * function is required for finer grained checking (i.e., per range) if pages 1420 * are valid. 1421 * 1422 * Return: True if GPU SVM range has valid pages, False otherwise 1423 */ 1424 bool drm_gpusvm_pages_valid(struct drm_gpusvm *gpusvm, 1425 struct drm_gpusvm_pages *svm_pages) 1426 { 1427 lockdep_assert_held(&gpusvm->notifier_lock); 1428 1429 return svm_pages->flags.has_devmem_pages || svm_pages->flags.has_dma_mapping; 1430 } 1431 EXPORT_SYMBOL_GPL(drm_gpusvm_pages_valid); 1432 1433 /** 1434 * drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked 1435 * @gpusvm: Pointer to the GPU SVM structure 1436 * @svm_pages: Pointer to the GPU SVM pages structure 1437 * 1438 * This function determines if a GPU SVM pages are valid. Expected be called 1439 * without holding gpusvm->notifier_lock. 1440 * 1441 * Return: True if GPU SVM pages are valid, False otherwise 1442 */ 1443 static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm, 1444 struct drm_gpusvm_pages *svm_pages) 1445 { 1446 bool pages_valid; 1447 1448 if (!svm_pages->dma_addr) 1449 return false; 1450 1451 drm_gpusvm_notifier_lock(gpusvm); 1452 pages_valid = drm_gpusvm_pages_valid(gpusvm, svm_pages); 1453 if (!pages_valid) 1454 __drm_gpusvm_free_pages(gpusvm, svm_pages); 1455 drm_gpusvm_notifier_unlock(gpusvm); 1456 1457 return pages_valid; 1458 } 1459 1460 /** 1461 * drm_gpusvm_get_pages() - Get pages and populate GPU SVM pages struct 1462 * @gpusvm: Pointer to the GPU SVM structure 1463 * @svm_pages: The SVM pages to populate. This will contain the dma-addresses 1464 * @mm: The mm corresponding to the CPU range 1465 * @notifier: The corresponding notifier for the given CPU range 1466 * @pages_start: Start CPU address for the pages 1467 * @pages_end: End CPU address for the pages (exclusive) 1468 * @ctx: GPU SVM context 1469 * 1470 * This function gets and maps pages for CPU range and ensures they are 1471 * mapped for DMA access. 1472 * 1473 * Return: 0 on success, negative error code on failure. 1474 */ 1475 int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, 1476 struct drm_gpusvm_pages *svm_pages, 1477 struct mm_struct *mm, 1478 struct mmu_interval_notifier *notifier, 1479 unsigned long pages_start, unsigned long pages_end, 1480 const struct drm_gpusvm_ctx *ctx) 1481 { 1482 struct hmm_range hmm_range = { 1483 .default_flags = HMM_PFN_REQ_FAULT | (ctx->read_only ? 0 : 1484 HMM_PFN_REQ_WRITE), 1485 .notifier = notifier, 1486 .start = pages_start, 1487 .end = pages_end, 1488 .dev_private_owner = ctx->device_private_page_owner, 1489 }; 1490 void *zdd; 1491 unsigned long timeout = 1492 jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 1493 unsigned long i, j; 1494 unsigned long npages = npages_in_range(pages_start, pages_end); 1495 unsigned long num_dma_mapped; 1496 unsigned int order = 0; 1497 unsigned long *pfns; 1498 int err = 0; 1499 struct dev_pagemap *pagemap; 1500 struct drm_pagemap *dpagemap; 1501 struct drm_gpusvm_pages_flags flags; 1502 enum dma_data_direction dma_dir = ctx->read_only ? DMA_TO_DEVICE : 1503 DMA_BIDIRECTIONAL; 1504 struct dma_iova_state *state = &svm_pages->state; 1505 1506 if (!svm_pages->drm) 1507 return -EINVAL; 1508 1509 retry: 1510 if (time_after(jiffies, timeout)) 1511 return -EBUSY; 1512 1513 hmm_range.notifier_seq = mmu_interval_read_begin(notifier); 1514 if (drm_gpusvm_pages_valid_unlocked(gpusvm, svm_pages)) 1515 goto set_seqno; 1516 1517 pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL); 1518 if (!pfns) 1519 return -ENOMEM; 1520 1521 if (!mmget_not_zero(mm)) { 1522 err = -EFAULT; 1523 goto err_free; 1524 } 1525 1526 hmm_range.hmm_pfns = pfns; 1527 while (true) { 1528 mmap_read_lock(mm); 1529 err = hmm_range_fault(&hmm_range); 1530 mmap_read_unlock(mm); 1531 1532 if (err == -EBUSY) { 1533 if (time_after(jiffies, timeout)) 1534 break; 1535 1536 hmm_range.notifier_seq = 1537 mmu_interval_read_begin(notifier); 1538 continue; 1539 } 1540 break; 1541 } 1542 mmput(mm); 1543 if (err) 1544 goto err_free; 1545 1546 *state = (struct dma_iova_state){}; 1547 svm_pages->state_offset = 0; 1548 1549 map_pages: 1550 /* 1551 * Perform all dma mappings under the notifier lock to not 1552 * access freed pages. A notifier will either block on 1553 * the notifier lock or unmap dma. 1554 */ 1555 drm_gpusvm_notifier_lock(gpusvm); 1556 1557 flags.__flags = svm_pages->flags.__flags; 1558 if (flags.unmapped) { 1559 drm_gpusvm_notifier_unlock(gpusvm); 1560 err = -EFAULT; 1561 goto err_free; 1562 } 1563 1564 if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) { 1565 drm_gpusvm_notifier_unlock(gpusvm); 1566 kvfree(pfns); 1567 goto retry; 1568 } 1569 1570 if (!svm_pages->dma_addr) { 1571 /* Unlock and restart mapping to allocate memory. */ 1572 drm_gpusvm_notifier_unlock(gpusvm); 1573 svm_pages->dma_addr = 1574 kvzalloc_objs(*svm_pages->dma_addr, npages); 1575 if (!svm_pages->dma_addr) { 1576 err = -ENOMEM; 1577 goto err_free; 1578 } 1579 goto map_pages; 1580 } 1581 1582 zdd = NULL; 1583 pagemap = NULL; 1584 num_dma_mapped = 0; 1585 for (i = 0, j = 0; i < npages; ++j) { 1586 struct page *page = hmm_pfn_to_page(pfns[i]); 1587 1588 order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages); 1589 if (is_device_private_page(page) || 1590 is_device_coherent_page(page)) { 1591 struct drm_pagemap_zdd *__zdd = 1592 drm_pagemap_page_zone_device_data(page); 1593 1594 if (!ctx->allow_mixed && 1595 zdd != __zdd && i > 0) { 1596 err = -EOPNOTSUPP; 1597 goto err_unmap; 1598 } 1599 zdd = __zdd; 1600 if (pagemap != page_pgmap(page)) { 1601 if (pagemap) { 1602 err = -EOPNOTSUPP; 1603 goto err_unmap; 1604 } 1605 1606 pagemap = page_pgmap(page); 1607 dpagemap = drm_pagemap_page_to_dpagemap(page); 1608 if (drm_WARN_ON(svm_pages->drm, !dpagemap)) { 1609 /* 1610 * Raced. This is not supposed to happen 1611 * since hmm_range_fault() should've migrated 1612 * this page to system. 1613 */ 1614 err = -EAGAIN; 1615 goto err_unmap; 1616 } 1617 1618 /* 1619 * Set the dpagemap as soon as the first 1620 * device page is mapped so the err_unmap path 1621 * can device_unmap() the device mappings that 1622 * have already been created. 1623 */ 1624 drm_pagemap_get(dpagemap); 1625 drm_pagemap_put(svm_pages->dpagemap); 1626 svm_pages->dpagemap = dpagemap; 1627 } 1628 svm_pages->dma_addr[j] = 1629 dpagemap->ops->device_map(dpagemap, 1630 svm_pages->drm->dev, 1631 page, order, 1632 dma_dir); 1633 if (dma_mapping_error(svm_pages->drm->dev, 1634 svm_pages->dma_addr[j].addr)) { 1635 err = -EFAULT; 1636 goto err_unmap; 1637 } 1638 } else { 1639 dma_addr_t addr; 1640 1641 if (is_zone_device_page(page) || 1642 (pagemap && !ctx->allow_mixed)) { 1643 err = -EOPNOTSUPP; 1644 goto err_unmap; 1645 } 1646 1647 if (ctx->devmem_only) { 1648 err = -EFAULT; 1649 goto err_unmap; 1650 } 1651 1652 if (!i) 1653 dma_iova_try_alloc(svm_pages->drm->dev, state, 1654 0, npages * PAGE_SIZE); 1655 1656 if (dma_use_iova(state)) { 1657 err = dma_iova_link(svm_pages->drm->dev, state, 1658 hmm_pfn_to_phys(pfns[i]), 1659 svm_pages->state_offset, 1660 PAGE_SIZE << order, 1661 dma_dir, 0); 1662 if (err) 1663 goto err_unmap; 1664 1665 addr = state->addr + svm_pages->state_offset; 1666 svm_pages->state_offset += PAGE_SIZE << order; 1667 } else { 1668 addr = dma_map_page(svm_pages->drm->dev, 1669 page, 0, 1670 PAGE_SIZE << order, 1671 dma_dir); 1672 if (dma_mapping_error(svm_pages->drm->dev, addr)) { 1673 err = -EFAULT; 1674 goto err_unmap; 1675 } 1676 } 1677 1678 svm_pages->dma_addr[j] = drm_pagemap_addr_encode 1679 (addr, DRM_INTERCONNECT_SYSTEM, order, 1680 dma_dir); 1681 } 1682 i += 1 << order; 1683 num_dma_mapped = i; 1684 flags.has_dma_mapping = true; 1685 } 1686 1687 if (dma_use_iova(state)) { 1688 err = dma_iova_sync(svm_pages->drm->dev, state, 0, 1689 svm_pages->state_offset); 1690 if (err) 1691 goto err_unmap; 1692 } 1693 1694 if (pagemap) 1695 flags.has_devmem_pages = true; 1696 1697 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1698 WRITE_ONCE(svm_pages->flags.__flags, flags.__flags); 1699 1700 drm_gpusvm_notifier_unlock(gpusvm); 1701 kvfree(pfns); 1702 set_seqno: 1703 svm_pages->notifier_seq = hmm_range.notifier_seq; 1704 1705 return 0; 1706 1707 err_unmap: 1708 svm_pages->flags.has_dma_mapping = true; 1709 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, num_dma_mapped); 1710 drm_gpusvm_notifier_unlock(gpusvm); 1711 err_free: 1712 kvfree(pfns); 1713 if (err == -EAGAIN) 1714 goto retry; 1715 return err; 1716 } 1717 EXPORT_SYMBOL_GPL(drm_gpusvm_get_pages); 1718 1719 /** 1720 * drm_gpusvm_unmap_pages() - Unmap GPU svm pages 1721 * @gpusvm: Pointer to the GPU SVM structure 1722 * @svm_pages: Pointer to the GPU SVM pages structure 1723 * @npages: Number of pages in @svm_pages. 1724 * @ctx: GPU SVM context 1725 * 1726 * This function unmaps pages associated with a GPU SVM pages struct. If 1727 * @in_notifier is set, it is assumed that gpusvm->notifier_lock is held in 1728 * write mode; if it is clear, it acquires gpusvm->notifier_lock in read mode. 1729 * Must be called in the invalidate() callback of the corresponding notifier for 1730 * IOMMU security model. 1731 */ 1732 void drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, 1733 struct drm_gpusvm_pages *svm_pages, 1734 unsigned long npages, 1735 const struct drm_gpusvm_ctx *ctx) 1736 { 1737 if (ctx->in_notifier) 1738 lockdep_assert_held_write(&gpusvm->notifier_lock); 1739 else 1740 drm_gpusvm_notifier_lock(gpusvm); 1741 1742 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages); 1743 1744 if (!ctx->in_notifier) 1745 drm_gpusvm_notifier_unlock(gpusvm); 1746 } 1747 EXPORT_SYMBOL_GPL(drm_gpusvm_unmap_pages); 1748 1749 /** 1750 * drm_gpusvm_range_evict() - Evict GPU SVM range 1751 * @gpusvm: Pointer to the GPU SVM structure 1752 * @range: Pointer to the GPU SVM range to be removed 1753 * 1754 * This function evicts the specified GPU SVM range. 1755 * 1756 * Return: 0 on success, a negative error code on failure. 1757 */ 1758 int drm_gpusvm_range_evict(struct drm_gpusvm *gpusvm, 1759 struct drm_gpusvm_range *range) 1760 { 1761 struct mmu_interval_notifier *notifier = &range->notifier->notifier; 1762 struct hmm_range hmm_range = { 1763 .default_flags = HMM_PFN_REQ_FAULT, 1764 .notifier = notifier, 1765 .start = drm_gpusvm_range_start(range), 1766 .end = drm_gpusvm_range_end(range), 1767 .dev_private_owner = NULL, 1768 }; 1769 unsigned long timeout = 1770 jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 1771 unsigned long *pfns; 1772 unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), 1773 drm_gpusvm_range_end(range)); 1774 int err = 0; 1775 struct mm_struct *mm = gpusvm->mm; 1776 1777 if (!mmget_not_zero(mm)) 1778 return -EFAULT; 1779 1780 pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL); 1781 if (!pfns) { 1782 mmput(mm); 1783 return -ENOMEM; 1784 } 1785 1786 hmm_range.hmm_pfns = pfns; 1787 while (!time_after(jiffies, timeout)) { 1788 hmm_range.notifier_seq = mmu_interval_read_begin(notifier); 1789 if (time_after(jiffies, timeout)) { 1790 err = -ETIME; 1791 break; 1792 } 1793 1794 mmap_read_lock(mm); 1795 err = hmm_range_fault(&hmm_range); 1796 mmap_read_unlock(mm); 1797 if (err != -EBUSY) 1798 break; 1799 } 1800 1801 kvfree(pfns); 1802 mmput(mm); 1803 1804 return err; 1805 } 1806 EXPORT_SYMBOL_GPL(drm_gpusvm_range_evict); 1807 1808 /** 1809 * drm_gpusvm_has_mapping() - Check if GPU SVM has mapping for the given address range 1810 * @gpusvm: Pointer to the GPU SVM structure. 1811 * @start: Start address 1812 * @end: End address 1813 * 1814 * Return: True if GPU SVM has mapping, False otherwise 1815 */ 1816 bool drm_gpusvm_has_mapping(struct drm_gpusvm *gpusvm, unsigned long start, 1817 unsigned long end) 1818 { 1819 struct drm_gpusvm_notifier *notifier; 1820 1821 drm_gpusvm_for_each_notifier(notifier, gpusvm, start, end) { 1822 struct drm_gpusvm_range *range = NULL; 1823 1824 drm_gpusvm_for_each_range(range, notifier, start, end) 1825 return true; 1826 } 1827 1828 return false; 1829 } 1830 EXPORT_SYMBOL_GPL(drm_gpusvm_has_mapping); 1831 1832 /** 1833 * drm_gpusvm_range_set_unmapped() - Mark a GPU SVM range as unmapped 1834 * @range: Pointer to the GPU SVM range structure. 1835 * @pages: Pointer to the GPU SVM pages structure(s). 1836 * @pages_count: Number of GPU SVM pages structure(s) passed in. 1837 * @mmu_range: Pointer to the MMU notifier range structure. 1838 * 1839 * This function marks a GPU SVM range as unmapped and sets the partial_unmap flag 1840 * if the range partially falls within the provided MMU notifier range. 1841 */ 1842 void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range, 1843 struct drm_gpusvm_pages *pages, 1844 unsigned int pages_count, 1845 const struct mmu_notifier_range *mmu_range) 1846 { 1847 struct drm_gpusvm_range_flags range_flags = { 1848 .__flags = range->flags.__flags, 1849 }; 1850 unsigned int i; 1851 1852 lockdep_assert_held_write(&range->gpusvm->notifier_lock); 1853 1854 range_flags.unmapped = true; 1855 for (i = 0; i < pages_count; ++i) { 1856 struct drm_gpusvm_pages_flags flags = { 1857 .__flags = pages[i].flags.__flags, 1858 }; 1859 1860 flags.unmapped = true; 1861 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1862 WRITE_ONCE(pages[i].flags.__flags, flags.__flags); 1863 } 1864 if (drm_gpusvm_range_start(range) < mmu_range->start || 1865 drm_gpusvm_range_end(range) > mmu_range->end) 1866 range_flags.partial_unmap = true; 1867 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1868 WRITE_ONCE(range->flags.__flags, range_flags.__flags); 1869 } 1870 EXPORT_SYMBOL_GPL(drm_gpusvm_range_set_unmapped); 1871 1872 MODULE_DESCRIPTION("DRM GPUSVM"); 1873 MODULE_LICENSE("GPL"); 1874