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