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 = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 777 enum drm_gpusvm_scan_result state = DRM_GPUSVM_SCAN_UNPOPULATED, new_state; 778 unsigned long *pfns; 779 unsigned long npages = npages_in_range(start, end); 780 const struct dev_pagemap *other = NULL; 781 int err, i; 782 783 pfns = kvcalloc(npages, sizeof(*pfns), GFP_KERNEL); 784 if (!pfns) 785 return DRM_GPUSVM_SCAN_UNPOPULATED; 786 787 hmm_range.hmm_pfns = pfns; 788 789 retry: 790 err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); 791 if (err) 792 goto err_free; 793 794 drm_gpusvm_notifier_lock(range->gpusvm); 795 if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) { 796 drm_gpusvm_notifier_unlock(range->gpusvm); 797 goto retry; 798 } 799 800 for (i = 0; i < npages;) { 801 struct page *page; 802 const struct dev_pagemap *cur = NULL; 803 804 if (!(pfns[i] & HMM_PFN_VALID)) { 805 state = DRM_GPUSVM_SCAN_UNPOPULATED; 806 break; 807 } 808 809 page = hmm_pfn_to_page(pfns[i]); 810 if (is_device_private_page(page) || 811 is_device_coherent_page(page)) 812 cur = page_pgmap(page); 813 814 if (cur == pagemap) { 815 new_state = DRM_GPUSVM_SCAN_EQUAL; 816 } else if (cur && (cur == other || !other)) { 817 new_state = DRM_GPUSVM_SCAN_OTHER; 818 other = cur; 819 } else if (cur) { 820 new_state = DRM_GPUSVM_SCAN_MIXED_DEVICE; 821 } else { 822 new_state = DRM_GPUSVM_SCAN_SYSTEM; 823 } 824 825 /* 826 * TODO: Could use an array for state 827 * transitions, and caller might want it 828 * to bail early for some results. 829 */ 830 if (state == DRM_GPUSVM_SCAN_UNPOPULATED) { 831 state = new_state; 832 } else if (state != new_state) { 833 if (new_state == DRM_GPUSVM_SCAN_SYSTEM || 834 state == DRM_GPUSVM_SCAN_SYSTEM) 835 state = DRM_GPUSVM_SCAN_MIXED; 836 else if (state != DRM_GPUSVM_SCAN_MIXED) 837 state = DRM_GPUSVM_SCAN_MIXED_DEVICE; 838 } 839 840 i += 1ul << drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages); 841 } 842 843 drm_gpusvm_notifier_unlock(range->gpusvm); 844 845 err_free: 846 kvfree(pfns); 847 return state; 848 } 849 EXPORT_SYMBOL(drm_gpusvm_scan_mm); 850 851 /** 852 * drm_gpusvm_range_chunk_size() - Determine chunk size for GPU SVM range 853 * @gpusvm: Pointer to the GPU SVM structure 854 * @notifier: Pointer to the GPU SVM notifier structure 855 * @vas: Pointer to the virtual memory area structure 856 * @fault_addr: Fault address 857 * @gpuva_start: Start address of GPUVA which mirrors CPU 858 * @gpuva_end: End address of GPUVA which mirrors CPU 859 * @check_pages_threshold: Check CPU pages for present threshold 860 * @dev_private_owner: The device private page owner 861 * 862 * This function determines the chunk size for the GPU SVM range based on the 863 * fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual 864 * memory area boundaries. 865 * 866 * Return: Chunk size on success, LONG_MAX on failure. 867 */ 868 static unsigned long 869 drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm, 870 struct drm_gpusvm_notifier *notifier, 871 struct vm_area_struct *vas, 872 unsigned long fault_addr, 873 unsigned long gpuva_start, 874 unsigned long gpuva_end, 875 unsigned long check_pages_threshold, 876 void *dev_private_owner) 877 { 878 unsigned long start, end; 879 int i = 0; 880 881 retry: 882 for (; i < gpusvm->num_chunks; ++i) { 883 start = ALIGN_DOWN(fault_addr, gpusvm->chunk_sizes[i]); 884 end = ALIGN(fault_addr + 1, gpusvm->chunk_sizes[i]); 885 886 if (start >= vas->vm_start && end <= vas->vm_end && 887 start >= drm_gpusvm_notifier_start(notifier) && 888 end <= drm_gpusvm_notifier_end(notifier) && 889 start >= gpuva_start && end <= gpuva_end) 890 break; 891 } 892 893 if (i == gpusvm->num_chunks) 894 return LONG_MAX; 895 896 /* 897 * If allocation more than page, ensure not to overlap with existing 898 * ranges. 899 */ 900 if (end - start != SZ_4K) { 901 struct drm_gpusvm_range *range; 902 903 range = drm_gpusvm_range_find(notifier, start, end); 904 if (range) { 905 ++i; 906 goto retry; 907 } 908 909 /* 910 * XXX: Only create range on pages CPU has faulted in. Without 911 * this check, or prefault, on BMG 'xe_exec_system_allocator --r 912 * process-many-malloc' fails. In the failure case, each process 913 * mallocs 16k but the CPU VMA is ~128k which results in 64k SVM 914 * ranges. When migrating the SVM ranges, some processes fail in 915 * drm_pagemap_migrate_to_devmem with 'migrate.cpages != npages' 916 * and then upon drm_gpusvm_range_get_pages device pages from 917 * other processes are collected + faulted in which creates all 918 * sorts of problems. Unsure exactly how this happening, also 919 * problem goes away if 'xe_exec_system_allocator --r 920 * process-many-malloc' mallocs at least 64k at a time. 921 */ 922 if (end - start <= check_pages_threshold && 923 !drm_gpusvm_check_pages(gpusvm, notifier, start, end, dev_private_owner)) { 924 ++i; 925 goto retry; 926 } 927 } 928 929 return end - start; 930 } 931 932 #ifdef CONFIG_LOCKDEP 933 /** 934 * drm_gpusvm_driver_lock_held() - Assert GPU SVM driver lock is held 935 * @gpusvm: Pointer to the GPU SVM structure. 936 * 937 * Ensure driver lock is held. 938 */ 939 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm) 940 { 941 if ((gpusvm)->lock_dep_map) 942 lockdep_assert(lock_is_held_type((gpusvm)->lock_dep_map, 0)); 943 } 944 #else 945 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm) 946 { 947 } 948 #endif 949 950 /** 951 * drm_gpusvm_find_vma_start() - Find start address for first VMA in range 952 * @gpusvm: Pointer to the GPU SVM structure 953 * @start: The inclusive start user address. 954 * @end: The exclusive end user address. 955 * 956 * Returns: The start address of first VMA within the provided range, 957 * ULONG_MAX otherwise. Assumes start_addr < end_addr. 958 */ 959 unsigned long 960 drm_gpusvm_find_vma_start(struct drm_gpusvm *gpusvm, 961 unsigned long start, 962 unsigned long end) 963 { 964 struct mm_struct *mm = gpusvm->mm; 965 struct vm_area_struct *vma; 966 unsigned long addr = ULONG_MAX; 967 968 if (!mmget_not_zero(mm)) 969 return addr; 970 971 mmap_read_lock(mm); 972 973 vma = find_vma_intersection(mm, start, end); 974 if (vma) 975 addr = vma->vm_start; 976 977 mmap_read_unlock(mm); 978 mmput(mm); 979 980 return addr; 981 } 982 EXPORT_SYMBOL_GPL(drm_gpusvm_find_vma_start); 983 984 /** 985 * drm_gpusvm_range_find_or_insert() - Find or insert GPU SVM range 986 * @gpusvm: Pointer to the GPU SVM structure 987 * @fault_addr: Fault address 988 * @gpuva_start: Start address of GPUVA which mirrors CPU 989 * @gpuva_end: End address of GPUVA which mirrors CPU 990 * @ctx: GPU SVM context 991 * 992 * This function finds or inserts a newly allocated a GPU SVM range based on the 993 * fault address. Caller must hold a lock to protect range lookup and insertion. 994 * 995 * Return: Pointer to the GPU SVM range on success, ERR_PTR() on failure. 996 */ 997 struct drm_gpusvm_range * 998 drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm, 999 unsigned long fault_addr, 1000 unsigned long gpuva_start, 1001 unsigned long gpuva_end, 1002 const struct drm_gpusvm_ctx *ctx) 1003 { 1004 struct drm_gpusvm_notifier *notifier; 1005 struct drm_gpusvm_range *range; 1006 struct mm_struct *mm = gpusvm->mm; 1007 struct vm_area_struct *vas; 1008 bool notifier_alloc = false; 1009 unsigned long chunk_size; 1010 int err; 1011 bool migrate_devmem; 1012 1013 drm_gpusvm_driver_lock_held(gpusvm); 1014 1015 if (fault_addr < gpusvm->mm_start || 1016 fault_addr > gpusvm->mm_start + gpusvm->mm_range) 1017 return ERR_PTR(-EINVAL); 1018 1019 if (!mmget_not_zero(mm)) 1020 return ERR_PTR(-EFAULT); 1021 1022 notifier = drm_gpusvm_notifier_find(gpusvm, fault_addr, fault_addr + 1); 1023 if (!notifier) { 1024 notifier = drm_gpusvm_notifier_alloc(gpusvm, fault_addr); 1025 if (IS_ERR(notifier)) { 1026 err = PTR_ERR(notifier); 1027 goto err_mmunlock; 1028 } 1029 notifier_alloc = true; 1030 err = mmu_interval_notifier_insert(¬ifier->notifier, 1031 mm, 1032 drm_gpusvm_notifier_start(notifier), 1033 drm_gpusvm_notifier_size(notifier), 1034 &drm_gpusvm_notifier_ops); 1035 if (err) 1036 goto err_notifier; 1037 } 1038 1039 mmap_read_lock(mm); 1040 1041 vas = vma_lookup(mm, fault_addr); 1042 if (!vas) { 1043 err = -ENOENT; 1044 goto err_notifier_remove; 1045 } 1046 1047 if (!ctx->read_only && !(vas->vm_flags & VM_WRITE)) { 1048 err = -EPERM; 1049 goto err_notifier_remove; 1050 } 1051 1052 if (vas->vm_flags & (VM_IO | VM_PFNMAP)) { 1053 err = -EIO; 1054 goto err_notifier_remove; 1055 } 1056 1057 range = drm_gpusvm_range_find(notifier, fault_addr, fault_addr + 1); 1058 if (range) 1059 goto out_mmunlock; 1060 /* 1061 * XXX: Short-circuiting migration based on migrate_vma_* current 1062 * limitations. If/when migrate_vma_* add more support, this logic will 1063 * have to change. 1064 */ 1065 migrate_devmem = ctx->devmem_possible && 1066 vma_is_anonymous(vas) && !is_vm_hugetlb_page(vas); 1067 1068 chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas, 1069 fault_addr, gpuva_start, 1070 gpuva_end, 1071 ctx->check_pages_threshold, 1072 ctx->device_private_page_owner); 1073 if (chunk_size == LONG_MAX) { 1074 err = -EINVAL; 1075 goto err_notifier_remove; 1076 } 1077 1078 range = drm_gpusvm_range_alloc(gpusvm, notifier, fault_addr, chunk_size, 1079 migrate_devmem); 1080 if (IS_ERR(range)) { 1081 err = PTR_ERR(range); 1082 goto err_notifier_remove; 1083 } 1084 1085 drm_gpusvm_range_insert(notifier, range); 1086 if (notifier_alloc) 1087 drm_gpusvm_notifier_insert(gpusvm, notifier); 1088 1089 out_mmunlock: 1090 mmap_read_unlock(mm); 1091 mmput(mm); 1092 1093 return range; 1094 1095 err_notifier_remove: 1096 mmap_read_unlock(mm); 1097 if (notifier_alloc) 1098 mmu_interval_notifier_remove(¬ifier->notifier); 1099 err_notifier: 1100 if (notifier_alloc) 1101 drm_gpusvm_notifier_free(gpusvm, notifier); 1102 err_mmunlock: 1103 mmput(mm); 1104 return ERR_PTR(err); 1105 } 1106 EXPORT_SYMBOL_GPL(drm_gpusvm_range_find_or_insert); 1107 1108 /** 1109 * __drm_gpusvm_unmap_pages() - Unmap pages associated with GPU SVM pages (internal) 1110 * @gpusvm: Pointer to the GPU SVM structure 1111 * @svm_pages: Pointer to the GPU SVM pages structure 1112 * @npages: Number of pages to unmap 1113 * 1114 * This function unmap pages associated with a GPU SVM pages struct. Assumes and 1115 * asserts correct locking is in place when called. 1116 */ 1117 static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, 1118 struct drm_gpusvm_pages *svm_pages, 1119 unsigned long npages) 1120 { 1121 struct drm_pagemap *dpagemap = svm_pages->dpagemap; 1122 struct device *dev = gpusvm->drm->dev; 1123 unsigned long i, j; 1124 1125 lockdep_assert_held(&gpusvm->notifier_lock); 1126 1127 if (svm_pages->flags.has_dma_mapping) { 1128 struct drm_gpusvm_pages_flags flags = { 1129 .__flags = svm_pages->flags.__flags, 1130 }; 1131 bool use_iova = dma_use_iova(&svm_pages->state); 1132 1133 /* 1134 * IOVA is reserved for the whole range but only the linked 1135 * system pages (state_offset bytes) need unlinking; free the 1136 * entire reservation to avoid leaking the device-page part. 1137 * On the error path state_offset is 0, so just free it. 1138 */ 1139 if (use_iova) { 1140 if (svm_pages->state_offset) 1141 dma_iova_unlink(dev, &svm_pages->state, 0, 1142 svm_pages->state_offset, 1143 svm_pages->dma_addr[0].dir, 0); 1144 dma_iova_free(dev, &svm_pages->state); 1145 } 1146 1147 for (i = 0, j = 0; i < npages; j++) { 1148 struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j]; 1149 1150 if (addr->proto == DRM_INTERCONNECT_SYSTEM) { 1151 /* 1152 * Linked IOVA pages were already torn down by 1153 * the dma_iova_unlink()/dma_iova_free() above; 1154 * only the non-IOVA mappings need unmap here. 1155 */ 1156 if (!use_iova) 1157 dma_unmap_page(dev, 1158 addr->addr, 1159 PAGE_SIZE << addr->order, 1160 addr->dir); 1161 } else if (dpagemap && dpagemap->ops->device_unmap) 1162 dpagemap->ops->device_unmap(dpagemap, 1163 dev, addr); 1164 i += 1 << addr->order; 1165 } 1166 1167 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1168 flags.has_devmem_pages = false; 1169 flags.has_dma_mapping = false; 1170 WRITE_ONCE(svm_pages->flags.__flags, flags.__flags); 1171 1172 drm_pagemap_put(svm_pages->dpagemap); 1173 svm_pages->dpagemap = NULL; 1174 } 1175 } 1176 1177 /** 1178 * __drm_gpusvm_free_pages() - Free dma array associated with GPU SVM pages 1179 * @gpusvm: Pointer to the GPU SVM structure 1180 * @svm_pages: Pointer to the GPU SVM pages structure 1181 * 1182 * This function frees the dma address array associated with a GPU SVM range. 1183 */ 1184 static void __drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm, 1185 struct drm_gpusvm_pages *svm_pages) 1186 { 1187 lockdep_assert_held(&gpusvm->notifier_lock); 1188 1189 if (svm_pages->dma_addr) { 1190 kvfree(svm_pages->dma_addr); 1191 svm_pages->dma_addr = NULL; 1192 } 1193 } 1194 1195 /** 1196 * drm_gpusvm_free_pages() - Free dma-mapping associated with GPU SVM pages 1197 * struct 1198 * @gpusvm: Pointer to the GPU SVM structure 1199 * @svm_pages: Pointer to the GPU SVM pages structure 1200 * @npages: Number of mapped pages 1201 * 1202 * This function unmaps and frees the dma address array associated with a GPU 1203 * SVM pages struct. 1204 */ 1205 void drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm, 1206 struct drm_gpusvm_pages *svm_pages, 1207 unsigned long npages) 1208 { 1209 drm_gpusvm_notifier_lock(gpusvm); 1210 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages); 1211 __drm_gpusvm_free_pages(gpusvm, svm_pages); 1212 drm_gpusvm_notifier_unlock(gpusvm); 1213 } 1214 EXPORT_SYMBOL_GPL(drm_gpusvm_free_pages); 1215 1216 /** 1217 * drm_gpusvm_range_remove() - Remove GPU SVM range 1218 * @gpusvm: Pointer to the GPU SVM structure 1219 * @range: Pointer to the GPU SVM range to be removed 1220 * 1221 * This function removes the specified GPU SVM range and also removes the parent 1222 * GPU SVM notifier if no more ranges remain in the notifier. The caller must 1223 * hold a lock to protect range and notifier removal. 1224 */ 1225 void drm_gpusvm_range_remove(struct drm_gpusvm *gpusvm, 1226 struct drm_gpusvm_range *range) 1227 { 1228 unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), 1229 drm_gpusvm_range_end(range)); 1230 struct drm_gpusvm_notifier *notifier; 1231 1232 drm_gpusvm_driver_lock_held(gpusvm); 1233 1234 notifier = drm_gpusvm_notifier_find(gpusvm, 1235 drm_gpusvm_range_start(range), 1236 drm_gpusvm_range_start(range) + 1); 1237 if (WARN_ON_ONCE(!notifier)) 1238 return; 1239 1240 drm_gpusvm_notifier_lock(gpusvm); 1241 __drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages); 1242 __drm_gpusvm_free_pages(gpusvm, &range->pages); 1243 __drm_gpusvm_range_remove(notifier, range); 1244 drm_gpusvm_notifier_unlock(gpusvm); 1245 1246 drm_gpusvm_range_put(range); 1247 1248 if (RB_EMPTY_ROOT(¬ifier->root.rb_root)) { 1249 if (!notifier->flags.removed) 1250 mmu_interval_notifier_remove(¬ifier->notifier); 1251 drm_gpusvm_notifier_remove(gpusvm, notifier); 1252 drm_gpusvm_notifier_free(gpusvm, notifier); 1253 } 1254 } 1255 EXPORT_SYMBOL_GPL(drm_gpusvm_range_remove); 1256 1257 /** 1258 * drm_gpusvm_range_get() - Get a reference to GPU SVM range 1259 * @range: Pointer to the GPU SVM range 1260 * 1261 * This function increments the reference count of the specified GPU SVM range. 1262 * 1263 * Return: Pointer to the GPU SVM range. 1264 */ 1265 struct drm_gpusvm_range * 1266 drm_gpusvm_range_get(struct drm_gpusvm_range *range) 1267 { 1268 kref_get(&range->refcount); 1269 1270 return range; 1271 } 1272 EXPORT_SYMBOL_GPL(drm_gpusvm_range_get); 1273 1274 /** 1275 * drm_gpusvm_range_destroy() - Destroy GPU SVM range 1276 * @refcount: Pointer to the reference counter embedded in the GPU SVM range 1277 * 1278 * This function destroys the specified GPU SVM range when its reference count 1279 * reaches zero. If a custom range-free function is provided, it is invoked to 1280 * free the range; otherwise, the range is deallocated using kfree(). 1281 */ 1282 static void drm_gpusvm_range_destroy(struct kref *refcount) 1283 { 1284 struct drm_gpusvm_range *range = 1285 container_of(refcount, struct drm_gpusvm_range, refcount); 1286 struct drm_gpusvm *gpusvm = range->gpusvm; 1287 1288 if (gpusvm->ops->range_free) 1289 gpusvm->ops->range_free(range); 1290 else 1291 kfree(range); 1292 } 1293 1294 /** 1295 * drm_gpusvm_range_put() - Put a reference to GPU SVM range 1296 * @range: Pointer to the GPU SVM range 1297 * 1298 * This function decrements the reference count of the specified GPU SVM range 1299 * and frees it when the count reaches zero. 1300 */ 1301 void drm_gpusvm_range_put(struct drm_gpusvm_range *range) 1302 { 1303 kref_put(&range->refcount, drm_gpusvm_range_destroy); 1304 } 1305 EXPORT_SYMBOL_GPL(drm_gpusvm_range_put); 1306 1307 /** 1308 * drm_gpusvm_pages_valid() - GPU SVM range pages valid 1309 * @gpusvm: Pointer to the GPU SVM structure 1310 * @svm_pages: Pointer to the GPU SVM pages structure 1311 * 1312 * This function determines if a GPU SVM range pages are valid. Expected be 1313 * called holding gpusvm->notifier_lock and as the last step before committing a 1314 * GPU binding. This is akin to a notifier seqno check in the HMM documentation 1315 * but due to wider notifiers (i.e., notifiers which span multiple ranges) this 1316 * function is required for finer grained checking (i.e., per range) if pages 1317 * are valid. 1318 * 1319 * Return: True if GPU SVM range has valid pages, False otherwise 1320 */ 1321 static bool drm_gpusvm_pages_valid(struct drm_gpusvm *gpusvm, 1322 struct drm_gpusvm_pages *svm_pages) 1323 { 1324 lockdep_assert_held(&gpusvm->notifier_lock); 1325 1326 return svm_pages->flags.has_devmem_pages || svm_pages->flags.has_dma_mapping; 1327 } 1328 1329 /** 1330 * drm_gpusvm_range_pages_valid() - GPU SVM range pages valid 1331 * @gpusvm: Pointer to the GPU SVM structure 1332 * @range: Pointer to the GPU SVM range structure 1333 * 1334 * This function determines if a GPU SVM range pages are valid. Expected be 1335 * called holding gpusvm->notifier_lock and as the last step before committing a 1336 * GPU binding. This is akin to a notifier seqno check in the HMM documentation 1337 * but due to wider notifiers (i.e., notifiers which span multiple ranges) this 1338 * function is required for finer grained checking (i.e., per range) if pages 1339 * are valid. 1340 * 1341 * Return: True if GPU SVM range has valid pages, False otherwise 1342 */ 1343 bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm, 1344 struct drm_gpusvm_range *range) 1345 { 1346 return drm_gpusvm_pages_valid(gpusvm, &range->pages); 1347 } 1348 EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid); 1349 1350 /** 1351 * drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked 1352 * @gpusvm: Pointer to the GPU SVM structure 1353 * @svm_pages: Pointer to the GPU SVM pages structure 1354 * 1355 * This function determines if a GPU SVM pages are valid. Expected be called 1356 * without holding gpusvm->notifier_lock. 1357 * 1358 * Return: True if GPU SVM pages are valid, False otherwise 1359 */ 1360 static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm, 1361 struct drm_gpusvm_pages *svm_pages) 1362 { 1363 bool pages_valid; 1364 1365 if (!svm_pages->dma_addr) 1366 return false; 1367 1368 drm_gpusvm_notifier_lock(gpusvm); 1369 pages_valid = drm_gpusvm_pages_valid(gpusvm, svm_pages); 1370 if (!pages_valid) 1371 __drm_gpusvm_free_pages(gpusvm, svm_pages); 1372 drm_gpusvm_notifier_unlock(gpusvm); 1373 1374 return pages_valid; 1375 } 1376 1377 /** 1378 * drm_gpusvm_get_pages() - Get pages and populate GPU SVM pages struct 1379 * @gpusvm: Pointer to the GPU SVM structure 1380 * @svm_pages: The SVM pages to populate. This will contain the dma-addresses 1381 * @mm: The mm corresponding to the CPU range 1382 * @notifier: The corresponding notifier for the given CPU range 1383 * @pages_start: Start CPU address for the pages 1384 * @pages_end: End CPU address for the pages (exclusive) 1385 * @ctx: GPU SVM context 1386 * 1387 * This function gets and maps pages for CPU range and ensures they are 1388 * mapped for DMA access. 1389 * 1390 * Return: 0 on success, negative error code on failure. 1391 */ 1392 int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, 1393 struct drm_gpusvm_pages *svm_pages, 1394 struct mm_struct *mm, 1395 struct mmu_interval_notifier *notifier, 1396 unsigned long pages_start, unsigned long pages_end, 1397 const struct drm_gpusvm_ctx *ctx) 1398 { 1399 struct hmm_range hmm_range = { 1400 .default_flags = HMM_PFN_REQ_FAULT | (ctx->read_only ? 0 : 1401 HMM_PFN_REQ_WRITE), 1402 .notifier = notifier, 1403 .start = pages_start, 1404 .end = pages_end, 1405 .dev_private_owner = ctx->device_private_page_owner, 1406 }; 1407 void *zdd; 1408 unsigned long timeout = 1409 jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 1410 unsigned long remaining; 1411 unsigned long i, j; 1412 unsigned long npages = npages_in_range(pages_start, pages_end); 1413 unsigned long num_dma_mapped; 1414 unsigned int order = 0; 1415 unsigned long *pfns; 1416 int err = 0; 1417 struct dev_pagemap *pagemap; 1418 struct drm_pagemap *dpagemap; 1419 struct drm_gpusvm_pages_flags flags; 1420 enum dma_data_direction dma_dir = ctx->read_only ? DMA_TO_DEVICE : 1421 DMA_BIDIRECTIONAL; 1422 struct dma_iova_state *state = &svm_pages->state; 1423 1424 retry: 1425 remaining = timeout - jiffies; 1426 1427 if (time_after_eq(jiffies, timeout)) 1428 return -EBUSY; 1429 1430 hmm_range.notifier_seq = mmu_interval_read_begin(notifier); 1431 if (drm_gpusvm_pages_valid_unlocked(gpusvm, svm_pages)) 1432 goto set_seqno; 1433 1434 pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL); 1435 if (!pfns) 1436 return -ENOMEM; 1437 1438 if (!mmget_not_zero(mm)) { 1439 err = -EFAULT; 1440 goto err_free; 1441 } 1442 1443 hmm_range.hmm_pfns = pfns; 1444 err = hmm_range_fault_unlocked_timeout(&hmm_range, remaining); 1445 mmput(mm); 1446 if (err) 1447 goto err_free; 1448 1449 *state = (struct dma_iova_state){}; 1450 svm_pages->state_offset = 0; 1451 1452 map_pages: 1453 /* 1454 * Perform all dma mappings under the notifier lock to not 1455 * access freed pages. A notifier will either block on 1456 * the notifier lock or unmap dma. 1457 */ 1458 drm_gpusvm_notifier_lock(gpusvm); 1459 1460 flags.__flags = svm_pages->flags.__flags; 1461 if (flags.unmapped) { 1462 drm_gpusvm_notifier_unlock(gpusvm); 1463 err = -EFAULT; 1464 goto err_free; 1465 } 1466 1467 if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) { 1468 drm_gpusvm_notifier_unlock(gpusvm); 1469 kvfree(pfns); 1470 goto retry; 1471 } 1472 1473 if (!svm_pages->dma_addr) { 1474 /* Unlock and restart mapping to allocate memory. */ 1475 drm_gpusvm_notifier_unlock(gpusvm); 1476 svm_pages->dma_addr = 1477 kvzalloc_objs(*svm_pages->dma_addr, npages); 1478 if (!svm_pages->dma_addr) { 1479 err = -ENOMEM; 1480 goto err_free; 1481 } 1482 goto map_pages; 1483 } 1484 1485 zdd = NULL; 1486 pagemap = NULL; 1487 num_dma_mapped = 0; 1488 for (i = 0, j = 0; i < npages; ++j) { 1489 struct page *page = hmm_pfn_to_page(pfns[i]); 1490 1491 order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages); 1492 if (is_device_private_page(page) || 1493 is_device_coherent_page(page)) { 1494 struct drm_pagemap_zdd *__zdd = 1495 drm_pagemap_page_zone_device_data(page); 1496 1497 if (!ctx->allow_mixed && 1498 zdd != __zdd && i > 0) { 1499 err = -EOPNOTSUPP; 1500 goto err_unmap; 1501 } 1502 zdd = __zdd; 1503 if (pagemap != page_pgmap(page)) { 1504 if (pagemap) { 1505 err = -EOPNOTSUPP; 1506 goto err_unmap; 1507 } 1508 1509 pagemap = page_pgmap(page); 1510 dpagemap = drm_pagemap_page_to_dpagemap(page); 1511 if (drm_WARN_ON(gpusvm->drm, !dpagemap)) { 1512 /* 1513 * Raced. This is not supposed to happen 1514 * since hmm_range_fault() should've migrated 1515 * this page to system. 1516 */ 1517 err = -EAGAIN; 1518 goto err_unmap; 1519 } 1520 1521 /* 1522 * Set the dpagemap as soon as the first 1523 * device page is mapped so the err_unmap path 1524 * can device_unmap() the device mappings that 1525 * have already been created. 1526 */ 1527 drm_pagemap_get(dpagemap); 1528 drm_pagemap_put(svm_pages->dpagemap); 1529 svm_pages->dpagemap = dpagemap; 1530 } 1531 svm_pages->dma_addr[j] = 1532 dpagemap->ops->device_map(dpagemap, 1533 gpusvm->drm->dev, 1534 page, order, 1535 dma_dir); 1536 if (dma_mapping_error(gpusvm->drm->dev, 1537 svm_pages->dma_addr[j].addr)) { 1538 err = -EFAULT; 1539 goto err_unmap; 1540 } 1541 } else { 1542 dma_addr_t addr; 1543 1544 if (is_zone_device_page(page) || 1545 (pagemap && !ctx->allow_mixed)) { 1546 err = -EOPNOTSUPP; 1547 goto err_unmap; 1548 } 1549 1550 if (ctx->devmem_only) { 1551 err = -EFAULT; 1552 goto err_unmap; 1553 } 1554 1555 if (!i) 1556 dma_iova_try_alloc(gpusvm->drm->dev, state, 1557 0, npages * PAGE_SIZE); 1558 1559 if (dma_use_iova(state)) { 1560 err = dma_iova_link(gpusvm->drm->dev, state, 1561 hmm_pfn_to_phys(pfns[i]), 1562 svm_pages->state_offset, 1563 PAGE_SIZE << order, 1564 dma_dir, 0); 1565 if (err) 1566 goto err_unmap; 1567 1568 addr = state->addr + svm_pages->state_offset; 1569 svm_pages->state_offset += PAGE_SIZE << order; 1570 } else { 1571 addr = dma_map_page(gpusvm->drm->dev, 1572 page, 0, 1573 PAGE_SIZE << order, 1574 dma_dir); 1575 if (dma_mapping_error(gpusvm->drm->dev, addr)) { 1576 err = -EFAULT; 1577 goto err_unmap; 1578 } 1579 } 1580 1581 svm_pages->dma_addr[j] = drm_pagemap_addr_encode 1582 (addr, DRM_INTERCONNECT_SYSTEM, order, 1583 dma_dir); 1584 } 1585 i += 1 << order; 1586 num_dma_mapped = i; 1587 flags.has_dma_mapping = true; 1588 } 1589 1590 if (dma_use_iova(state)) { 1591 err = dma_iova_sync(gpusvm->drm->dev, state, 0, 1592 svm_pages->state_offset); 1593 if (err) 1594 goto err_unmap; 1595 } 1596 1597 if (pagemap) 1598 flags.has_devmem_pages = true; 1599 1600 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */ 1601 WRITE_ONCE(svm_pages->flags.__flags, flags.__flags); 1602 1603 drm_gpusvm_notifier_unlock(gpusvm); 1604 kvfree(pfns); 1605 set_seqno: 1606 svm_pages->notifier_seq = hmm_range.notifier_seq; 1607 1608 return 0; 1609 1610 err_unmap: 1611 svm_pages->flags.has_dma_mapping = true; 1612 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, num_dma_mapped); 1613 drm_gpusvm_notifier_unlock(gpusvm); 1614 err_free: 1615 kvfree(pfns); 1616 if (err == -EAGAIN) 1617 goto retry; 1618 return err; 1619 } 1620 EXPORT_SYMBOL_GPL(drm_gpusvm_get_pages); 1621 1622 /** 1623 * drm_gpusvm_range_get_pages() - Get pages for a GPU SVM range 1624 * @gpusvm: Pointer to the GPU SVM structure 1625 * @range: Pointer to the GPU SVM range structure 1626 * @ctx: GPU SVM context 1627 * 1628 * This function gets pages for a GPU SVM range and ensures they are mapped for 1629 * DMA access. 1630 * 1631 * Return: 0 on success, negative error code on failure. 1632 */ 1633 int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm, 1634 struct drm_gpusvm_range *range, 1635 const struct drm_gpusvm_ctx *ctx) 1636 { 1637 return drm_gpusvm_get_pages(gpusvm, &range->pages, gpusvm->mm, 1638 &range->notifier->notifier, 1639 drm_gpusvm_range_start(range), 1640 drm_gpusvm_range_end(range), ctx); 1641 } 1642 EXPORT_SYMBOL_GPL(drm_gpusvm_range_get_pages); 1643 1644 /** 1645 * drm_gpusvm_unmap_pages() - Unmap GPU svm pages 1646 * @gpusvm: Pointer to the GPU SVM structure 1647 * @svm_pages: Pointer to the GPU SVM pages structure 1648 * @npages: Number of pages in @svm_pages. 1649 * @ctx: GPU SVM context 1650 * 1651 * This function unmaps pages associated with a GPU SVM pages struct. If 1652 * @in_notifier is set, it is assumed that gpusvm->notifier_lock is held in 1653 * write mode; if it is clear, it acquires gpusvm->notifier_lock in read mode. 1654 * Must be called in the invalidate() callback of the corresponding notifier for 1655 * IOMMU security model. 1656 */ 1657 void drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, 1658 struct drm_gpusvm_pages *svm_pages, 1659 unsigned long npages, 1660 const struct drm_gpusvm_ctx *ctx) 1661 { 1662 if (ctx->in_notifier) 1663 lockdep_assert_held_write(&gpusvm->notifier_lock); 1664 else 1665 drm_gpusvm_notifier_lock(gpusvm); 1666 1667 __drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages); 1668 1669 if (!ctx->in_notifier) 1670 drm_gpusvm_notifier_unlock(gpusvm); 1671 } 1672 EXPORT_SYMBOL_GPL(drm_gpusvm_unmap_pages); 1673 1674 /** 1675 * drm_gpusvm_range_unmap_pages() - Unmap pages associated with a GPU SVM range 1676 * @gpusvm: Pointer to the GPU SVM structure 1677 * @range: Pointer to the GPU SVM range structure 1678 * @ctx: GPU SVM context 1679 * 1680 * This function unmaps pages associated with a GPU SVM range. If @in_notifier 1681 * is set, it is assumed that gpusvm->notifier_lock is held in write mode; if it 1682 * is clear, it acquires gpusvm->notifier_lock in read mode. Must be called on 1683 * each GPU SVM range attached to notifier in gpusvm->ops->invalidate for IOMMU 1684 * security model. 1685 */ 1686 void drm_gpusvm_range_unmap_pages(struct drm_gpusvm *gpusvm, 1687 struct drm_gpusvm_range *range, 1688 const struct drm_gpusvm_ctx *ctx) 1689 { 1690 unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), 1691 drm_gpusvm_range_end(range)); 1692 1693 return drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages, ctx); 1694 } 1695 EXPORT_SYMBOL_GPL(drm_gpusvm_range_unmap_pages); 1696 1697 /** 1698 * drm_gpusvm_range_evict() - Evict GPU SVM range 1699 * @gpusvm: Pointer to the GPU SVM structure 1700 * @range: Pointer to the GPU SVM range to be removed 1701 * 1702 * This function evicts the specified GPU SVM range. 1703 * 1704 * Return: 0 on success, a negative error code on failure. 1705 */ 1706 int drm_gpusvm_range_evict(struct drm_gpusvm *gpusvm, 1707 struct drm_gpusvm_range *range) 1708 { 1709 struct mmu_interval_notifier *notifier = &range->notifier->notifier; 1710 struct hmm_range hmm_range = { 1711 .default_flags = HMM_PFN_REQ_FAULT, 1712 .notifier = notifier, 1713 .start = drm_gpusvm_range_start(range), 1714 .end = drm_gpusvm_range_end(range), 1715 .dev_private_owner = NULL, 1716 }; 1717 unsigned long timeout = msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT); 1718 unsigned long *pfns; 1719 unsigned long npages = npages_in_range(drm_gpusvm_range_start(range), 1720 drm_gpusvm_range_end(range)); 1721 int err = 0; 1722 struct mm_struct *mm = gpusvm->mm; 1723 1724 if (!mmget_not_zero(mm)) 1725 return -EFAULT; 1726 1727 pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL); 1728 if (!pfns) { 1729 mmput(mm); 1730 return -ENOMEM; 1731 } 1732 1733 hmm_range.hmm_pfns = pfns; 1734 err = hmm_range_fault_unlocked_timeout(&hmm_range, timeout); 1735 1736 kvfree(pfns); 1737 mmput(mm); 1738 1739 return err == -EBUSY ? -ETIME : err; 1740 } 1741 EXPORT_SYMBOL_GPL(drm_gpusvm_range_evict); 1742 1743 /** 1744 * drm_gpusvm_has_mapping() - Check if GPU SVM has mapping for the given address range 1745 * @gpusvm: Pointer to the GPU SVM structure. 1746 * @start: Start address 1747 * @end: End address 1748 * 1749 * Return: True if GPU SVM has mapping, False otherwise 1750 */ 1751 bool drm_gpusvm_has_mapping(struct drm_gpusvm *gpusvm, unsigned long start, 1752 unsigned long end) 1753 { 1754 struct drm_gpusvm_notifier *notifier; 1755 1756 drm_gpusvm_for_each_notifier(notifier, gpusvm, start, end) { 1757 struct drm_gpusvm_range *range = NULL; 1758 1759 drm_gpusvm_for_each_range(range, notifier, start, end) 1760 return true; 1761 } 1762 1763 return false; 1764 } 1765 EXPORT_SYMBOL_GPL(drm_gpusvm_has_mapping); 1766 1767 /** 1768 * drm_gpusvm_range_set_unmapped() - Mark a GPU SVM range as unmapped 1769 * @range: Pointer to the GPU SVM range structure. 1770 * @mmu_range: Pointer to the MMU notifier range structure. 1771 * 1772 * This function marks a GPU SVM range as unmapped and sets the partial_unmap flag 1773 * if the range partially falls within the provided MMU notifier range. 1774 */ 1775 void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range, 1776 const struct mmu_notifier_range *mmu_range) 1777 { 1778 lockdep_assert_held_write(&range->gpusvm->notifier_lock); 1779 1780 range->pages.flags.unmapped = true; 1781 if (drm_gpusvm_range_start(range) < mmu_range->start || 1782 drm_gpusvm_range_end(range) > mmu_range->end) 1783 range->pages.flags.partial_unmap = true; 1784 } 1785 EXPORT_SYMBOL_GPL(drm_gpusvm_range_set_unmapped); 1786 1787 MODULE_DESCRIPTION("DRM GPUSVM"); 1788 MODULE_LICENSE("GPL"); 1789