|
23 | 23 | * DOC: Overview
|
24 | 24 | *
|
25 | 25 | * GPU Shared Virtual Memory (GPU SVM) layer for the Direct Rendering Manager (DRM)
|
26 |
| - * |
27 |
| - * The GPU SVM layer is a component of the DRM framework designed to manage shared |
28 |
| - * virtual memory between the CPU and GPU. It enables efficient data exchange and |
29 |
| - * processing for GPU-accelerated applications by allowing memory sharing and |
| 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 |
30 | 29 | * synchronization between the CPU's and GPU's virtual address spaces.
|
31 | 30 | *
|
32 | 31 | * Key GPU SVM Components:
|
33 |
| - * - Notifiers: Notifiers: Used for tracking memory intervals and notifying the |
34 |
| - * GPU of changes, notifiers are sized based on a GPU SVM |
35 |
| - * initialization parameter, with a recommendation of 512M or |
36 |
| - * larger. They maintain a Red-BlacK tree and a list of ranges that |
37 |
| - * fall within the notifier interval. Notifiers are tracked within |
38 |
| - * a GPU SVM Red-BlacK tree and list and are dynamically inserted |
39 |
| - * or removed as ranges within the interval are created or |
40 |
| - * destroyed. |
41 |
| - * - Ranges: Represent memory ranges mapped in a DRM device and managed |
42 |
| - * by GPU SVM. They are sized based on an array of chunk sizes, which |
43 |
| - * is a GPU SVM initialization parameter, and the CPU address space. |
44 |
| - * Upon GPU fault, the largest aligned chunk that fits within the |
45 |
| - * faulting CPU address space is chosen for the range size. Ranges are |
46 |
| - * expected to be dynamically allocated on GPU fault and removed on an |
47 |
| - * MMU notifier UNMAP event. As mentioned above, ranges are tracked in |
48 |
| - * a notifier's Red-Black tree. |
49 |
| - * - Operations: Define the interface for driver-specific GPU SVM operations |
50 |
| - * such as range allocation, notifier allocation, and |
51 |
| - * invalidations. |
52 |
| - * - Device Memory Allocations: Embedded structure containing enough information |
53 |
| - * for GPU SVM to migrate to / from device memory. |
54 |
| - * - Device Memory Operations: Define the interface for driver-specific device |
55 |
| - * memory operations release memory, populate pfns, |
56 |
| - * and copy to / from device memory. |
| 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. |
57 | 62 | *
|
58 | 63 | * This layer provides interfaces for allocating, mapping, migrating, and
|
59 | 64 | * releasing memory ranges between the CPU and GPU. It handles all core memory
|
|
63 | 68 | * below.
|
64 | 69 | *
|
65 | 70 | * Expected Driver Components:
|
66 |
| - * - GPU page fault handler: Used to create ranges and notifiers based on the |
67 |
| - * fault address, optionally migrate the range to |
68 |
| - * device memory, and create GPU bindings. |
69 |
| - * - Garbage collector: Used to unmap and destroy GPU bindings for ranges. |
70 |
| - * Ranges are expected to be added to the garbage collector |
71 |
| - * upon a MMU_NOTIFY_UNMAP event in notifier callback. |
72 |
| - * - Notifier callback: Used to invalidate and DMA unmap GPU bindings for |
73 |
| - * ranges. |
| 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. |
74 | 83 | */
|
75 | 84 |
|
76 | 85 | /**
|
|
83 | 92 | * range RB tree and list, as well as the range's DMA mappings and sequence
|
84 | 93 | * number. GPU SVM manages all necessary locking and unlocking operations,
|
85 | 94 | * except for the recheck range's pages being valid
|
86 |
| - * (drm_gpusvm_range_pages_valid) when the driver is committing GPU bindings. This |
87 |
| - * lock corresponds to the 'driver->update' lock mentioned in the HMM |
88 |
| - * documentation (TODO: Link). Future revisions may transition from a GPU SVM |
| 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 |
89 | 98 | * global lock to a per-notifier lock if finer-grained locking is deemed
|
90 | 99 | * necessary.
|
91 | 100 | *
|
|
102 | 111 | * DOC: Migration
|
103 | 112 | *
|
104 | 113 | * The migration support is quite simple, allowing migration between RAM and
|
105 |
| - * device memory at the range granularity. For example, GPU SVM currently does not |
106 |
| - * support mixing RAM and device memory pages within a range. This means that upon GPU |
107 |
| - * fault, the entire range can be migrated to device memory, and upon CPU fault, the |
108 |
| - * entire range is migrated to RAM. Mixed RAM and device memory storage within a range |
109 |
| - * could be added in the future if required. |
| 114 | + * device memory at the range granularity. For example, GPU SVM currently does |
| 115 | + * not support mixing RAM and device memory pages within a range. This means |
| 116 | + * that upon GPU fault, the entire range can be migrated to device memory, and |
| 117 | + * upon CPU fault, the entire range is migrated to RAM. Mixed RAM and device |
| 118 | + * memory storage within a range could be added in the future if required. |
110 | 119 | *
|
111 | 120 | * The reasoning for only supporting range granularity is as follows: it
|
112 | 121 | * simplifies the implementation, and range sizes are driver-defined and should
|
|
119 | 128 | * Partial unmapping of ranges (e.g., 1M out of 2M is unmapped by CPU resulting
|
120 | 129 | * in MMU_NOTIFY_UNMAP event) presents several challenges, with the main one
|
121 | 130 | * being that a subset of the range still has CPU and GPU mappings. If the
|
122 |
| - * backing store for the range is in device memory, a subset of the backing store has |
123 |
| - * references. One option would be to split the range and device memory backing store, |
124 |
| - * but the implementation for this would be quite complicated. Given that |
125 |
| - * partial unmappings are rare and driver-defined range sizes are relatively |
126 |
| - * small, GPU SVM does not support splitting of ranges. |
| 131 | + * backing store for the range is in device memory, a subset of the backing |
| 132 | + * store has references. One option would be to split the range and device |
| 133 | + * memory backing store, but the implementation for this would be quite |
| 134 | + * complicated. Given that partial unmappings are rare and driver-defined range |
| 135 | + * sizes are relatively small, GPU SVM does not support splitting of ranges. |
127 | 136 | *
|
128 | 137 | * With no support for range splitting, upon partial unmapping of a range, the
|
129 | 138 | * driver is expected to invalidate and destroy the entire range. If the range
|
|
144 | 153 | *
|
145 | 154 | * 1) GPU page fault handler
|
146 | 155 | *
|
| 156 | + * .. code-block:: c |
| 157 | + * |
147 | 158 | * int driver_bind_range(struct drm_gpusvm *gpusvm, struct drm_gpusvm_range *range)
|
148 | 159 | * {
|
149 | 160 | * int err = 0;
|
|
208 | 219 | * return err;
|
209 | 220 | * }
|
210 | 221 | *
|
211 |
| - * 2) Garbage Collector. |
| 222 | + * 2) Garbage Collector |
| 223 | + * |
| 224 | + * .. code-block:: c |
212 | 225 | *
|
213 | 226 | * void __driver_garbage_collector(struct drm_gpusvm *gpusvm,
|
214 | 227 | * struct drm_gpusvm_range *range)
|
|
231 | 244 | * __driver_garbage_collector(gpusvm, range);
|
232 | 245 | * }
|
233 | 246 | *
|
234 |
| - * 3) Notifier callback. |
| 247 | + * 3) Notifier callback |
| 248 | + * |
| 249 | + * .. code-block:: c |
235 | 250 | *
|
236 | 251 | * void driver_invalidation(struct drm_gpusvm *gpusvm,
|
237 | 252 | * struct drm_gpusvm_notifier *notifier,
|
@@ -499,7 +514,7 @@ drm_gpusvm_notifier_invalidate(struct mmu_interval_notifier *mni,
|
499 | 514 | return true;
|
500 | 515 | }
|
501 | 516 |
|
502 |
| -/** |
| 517 | +/* |
503 | 518 | * drm_gpusvm_notifier_ops - MMU interval notifier operations for GPU SVM
|
504 | 519 | */
|
505 | 520 | static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
|
@@ -2055,7 +2070,6 @@ static int __drm_gpusvm_migrate_to_ram(struct vm_area_struct *vas,
|
2055 | 2070 |
|
2056 | 2071 | /**
|
2057 | 2072 | * drm_gpusvm_range_evict - Evict GPU SVM range
|
2058 |
| - * @pagemap: Pointer to the GPU SVM structure |
2059 | 2073 | * @range: Pointer to the GPU SVM range to be removed
|
2060 | 2074 | *
|
2061 | 2075 | * This function evicts the specified GPU SVM range. This function will not
|
@@ -2146,8 +2160,8 @@ static vm_fault_t drm_gpusvm_migrate_to_ram(struct vm_fault *vmf)
|
2146 | 2160 | return err ? VM_FAULT_SIGBUS : 0;
|
2147 | 2161 | }
|
2148 | 2162 |
|
2149 |
| -/** |
2150 |
| - * drm_gpusvm_pagemap_ops() - Device page map operations for GPU SVM |
| 2163 | +/* |
| 2164 | + * drm_gpusvm_pagemap_ops - Device page map operations for GPU SVM |
2151 | 2165 | */
|
2152 | 2166 | static const struct dev_pagemap_ops drm_gpusvm_pagemap_ops = {
|
2153 | 2167 | .page_free = drm_gpusvm_page_free,
|
|
0 commit comments