|
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