hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/nouveau/nouveau_ttm.c
....@@ -31,35 +31,17 @@
3131
3232 #include <core/tegra.h>
3333
34
-static int
35
-nouveau_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
36
-{
37
- return 0;
38
-}
39
-
40
-static int
41
-nouveau_manager_fini(struct ttm_mem_type_manager *man)
42
-{
43
- return 0;
44
-}
45
-
4634 static void
47
-nouveau_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg)
35
+nouveau_manager_del(struct ttm_resource_manager *man, struct ttm_resource *reg)
4836 {
4937 nouveau_mem_del(reg);
5038 }
5139
52
-static void
53
-nouveau_manager_debug(struct ttm_mem_type_manager *man,
54
- struct drm_printer *printer)
55
-{
56
-}
57
-
5840 static int
59
-nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
41
+nouveau_vram_manager_new(struct ttm_resource_manager *man,
6042 struct ttm_buffer_object *bo,
6143 const struct ttm_place *place,
62
- struct ttm_mem_reg *reg)
44
+ struct ttm_resource *reg)
6345 {
6446 struct nouveau_bo *nvbo = nouveau_bo(bo);
6547 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
....@@ -75,29 +57,22 @@
7557 ret = nouveau_mem_vram(reg, nvbo->contig, nvbo->page);
7658 if (ret) {
7759 nouveau_mem_del(reg);
78
- if (ret == -ENOSPC) {
79
- reg->mm_node = NULL;
80
- return 0;
81
- }
8260 return ret;
8361 }
8462
8563 return 0;
8664 }
8765
88
-const struct ttm_mem_type_manager_func nouveau_vram_manager = {
89
- .init = nouveau_manager_init,
90
- .takedown = nouveau_manager_fini,
91
- .get_node = nouveau_vram_manager_new,
92
- .put_node = nouveau_manager_del,
93
- .debug = nouveau_manager_debug,
66
+const struct ttm_resource_manager_func nouveau_vram_manager = {
67
+ .alloc = nouveau_vram_manager_new,
68
+ .free = nouveau_manager_del,
9469 };
9570
9671 static int
97
-nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
72
+nouveau_gart_manager_new(struct ttm_resource_manager *man,
9873 struct ttm_buffer_object *bo,
9974 const struct ttm_place *place,
100
- struct ttm_mem_reg *reg)
75
+ struct ttm_resource *reg)
10176 {
10277 struct nouveau_bo *nvbo = nouveau_bo(bo);
10378 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
....@@ -111,19 +86,16 @@
11186 return 0;
11287 }
11388
114
-const struct ttm_mem_type_manager_func nouveau_gart_manager = {
115
- .init = nouveau_manager_init,
116
- .takedown = nouveau_manager_fini,
117
- .get_node = nouveau_gart_manager_new,
118
- .put_node = nouveau_manager_del,
119
- .debug = nouveau_manager_debug
89
+const struct ttm_resource_manager_func nouveau_gart_manager = {
90
+ .alloc = nouveau_gart_manager_new,
91
+ .free = nouveau_manager_del,
12092 };
12193
12294 static int
123
-nv04_gart_manager_new(struct ttm_mem_type_manager *man,
95
+nv04_gart_manager_new(struct ttm_resource_manager *man,
12496 struct ttm_buffer_object *bo,
12597 const struct ttm_place *place,
126
- struct ttm_mem_reg *reg)
98
+ struct ttm_resource *reg)
12799 {
128100 struct nouveau_bo *nvbo = nouveau_bo(bo);
129101 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
....@@ -139,10 +111,6 @@
139111 reg->num_pages << PAGE_SHIFT, &mem->vma[0]);
140112 if (ret) {
141113 nouveau_mem_del(reg);
142
- if (ret == -ENOSPC) {
143
- reg->mm_node = NULL;
144
- return 0;
145
- }
146114 return ret;
147115 }
148116
....@@ -150,12 +118,41 @@
150118 return 0;
151119 }
152120
153
-const struct ttm_mem_type_manager_func nv04_gart_manager = {
154
- .init = nouveau_manager_init,
155
- .takedown = nouveau_manager_fini,
156
- .get_node = nv04_gart_manager_new,
157
- .put_node = nouveau_manager_del,
158
- .debug = nouveau_manager_debug
121
+const struct ttm_resource_manager_func nv04_gart_manager = {
122
+ .alloc = nv04_gart_manager_new,
123
+ .free = nouveau_manager_del,
124
+};
125
+
126
+static vm_fault_t nouveau_ttm_fault(struct vm_fault *vmf)
127
+{
128
+ struct vm_area_struct *vma = vmf->vma;
129
+ struct ttm_buffer_object *bo = vma->vm_private_data;
130
+ pgprot_t prot;
131
+ vm_fault_t ret;
132
+
133
+ ret = ttm_bo_vm_reserve(bo, vmf);
134
+ if (ret)
135
+ return ret;
136
+
137
+ nouveau_bo_del_io_reserve_lru(bo);
138
+
139
+ prot = vm_get_page_prot(vma->vm_flags);
140
+ ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT, 1);
141
+ if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
142
+ return ret;
143
+
144
+ nouveau_bo_add_io_reserve_lru(bo);
145
+
146
+ dma_resv_unlock(bo->base.resv);
147
+
148
+ return ret;
149
+}
150
+
151
+static struct vm_operations_struct nouveau_ttm_vm_ops = {
152
+ .fault = nouveau_ttm_fault,
153
+ .open = ttm_bo_vm_open,
154
+ .close = ttm_bo_vm_close,
155
+ .access = ttm_bo_vm_access
159156 };
160157
161158 int
....@@ -163,75 +160,14 @@
163160 {
164161 struct drm_file *file_priv = filp->private_data;
165162 struct nouveau_drm *drm = nouveau_drm(file_priv->minor->dev);
166
-
167
- if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
168
-#if defined(CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT)
169
- return drm_legacy_mmap(filp, vma);
170
-#else
171
- return -EINVAL;
172
-#endif
173
-
174
- return ttm_bo_mmap(filp, vma, &drm->ttm.bdev);
175
-}
176
-
177
-static int
178
-nouveau_ttm_mem_global_init(struct drm_global_reference *ref)
179
-{
180
- return ttm_mem_global_init(ref->object);
181
-}
182
-
183
-static void
184
-nouveau_ttm_mem_global_release(struct drm_global_reference *ref)
185
-{
186
- ttm_mem_global_release(ref->object);
187
-}
188
-
189
-int
190
-nouveau_ttm_global_init(struct nouveau_drm *drm)
191
-{
192
- struct drm_global_reference *global_ref;
193163 int ret;
194164
195
- global_ref = &drm->ttm.mem_global_ref;
196
- global_ref->global_type = DRM_GLOBAL_TTM_MEM;
197
- global_ref->size = sizeof(struct ttm_mem_global);
198
- global_ref->init = &nouveau_ttm_mem_global_init;
199
- global_ref->release = &nouveau_ttm_mem_global_release;
200
-
201
- ret = drm_global_item_ref(global_ref);
202
- if (unlikely(ret != 0)) {
203
- DRM_ERROR("Failed setting up TTM memory accounting\n");
204
- drm->ttm.mem_global_ref.release = NULL;
165
+ ret = ttm_bo_mmap(filp, vma, &drm->ttm.bdev);
166
+ if (ret)
205167 return ret;
206
- }
207168
208
- drm->ttm.bo_global_ref.mem_glob = global_ref->object;
209
- global_ref = &drm->ttm.bo_global_ref.ref;
210
- global_ref->global_type = DRM_GLOBAL_TTM_BO;
211
- global_ref->size = sizeof(struct ttm_bo_global);
212
- global_ref->init = &ttm_bo_global_init;
213
- global_ref->release = &ttm_bo_global_release;
214
-
215
- ret = drm_global_item_ref(global_ref);
216
- if (unlikely(ret != 0)) {
217
- DRM_ERROR("Failed setting up TTM BO subsystem\n");
218
- drm_global_item_unref(&drm->ttm.mem_global_ref);
219
- drm->ttm.mem_global_ref.release = NULL;
220
- return ret;
221
- }
222
-
169
+ vma->vm_ops = &nouveau_ttm_vm_ops;
223170 return 0;
224
-}
225
-
226
-void
227
-nouveau_ttm_global_release(struct nouveau_drm *drm)
228
-{
229
- if (drm->ttm.mem_global_ref.release == NULL)
230
- return;
231
-
232
- drm_global_item_unref(&drm->ttm.bo_global_ref.ref);
233
- drm_global_item_unref(&drm->ttm.mem_global_ref);
234
- drm->ttm.mem_global_ref.release = NULL;
235171 }
236172
237173 static int
....@@ -253,6 +189,87 @@
253189
254190 drm->ttm.type_ncoh[!!kind] = typei;
255191 return 0;
192
+}
193
+
194
+static int
195
+nouveau_ttm_init_vram(struct nouveau_drm *drm)
196
+{
197
+ if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
198
+ struct ttm_resource_manager *man = kzalloc(sizeof(*man), GFP_KERNEL);
199
+
200
+ if (!man)
201
+ return -ENOMEM;
202
+
203
+ man->func = &nouveau_vram_manager;
204
+
205
+ ttm_resource_manager_init(man,
206
+ drm->gem.vram_available >> PAGE_SHIFT);
207
+ ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, man);
208
+ ttm_resource_manager_set_used(man, true);
209
+ return 0;
210
+ } else {
211
+ return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_VRAM, false,
212
+ drm->gem.vram_available >> PAGE_SHIFT);
213
+ }
214
+}
215
+
216
+static void
217
+nouveau_ttm_fini_vram(struct nouveau_drm *drm)
218
+{
219
+ struct ttm_resource_manager *man = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM);
220
+
221
+ if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
222
+ ttm_resource_manager_set_used(man, false);
223
+ ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man);
224
+ ttm_resource_manager_cleanup(man);
225
+ ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, NULL);
226
+ kfree(man);
227
+ } else
228
+ ttm_range_man_fini(&drm->ttm.bdev, TTM_PL_VRAM);
229
+}
230
+
231
+static int
232
+nouveau_ttm_init_gtt(struct nouveau_drm *drm)
233
+{
234
+ struct ttm_resource_manager *man;
235
+ unsigned long size_pages = drm->gem.gart_available >> PAGE_SHIFT;
236
+ const struct ttm_resource_manager_func *func = NULL;
237
+
238
+ if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA)
239
+ func = &nouveau_gart_manager;
240
+ else if (!drm->agp.bridge)
241
+ func = &nv04_gart_manager;
242
+ else
243
+ return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT, true,
244
+ size_pages);
245
+
246
+ man = kzalloc(sizeof(*man), GFP_KERNEL);
247
+ if (!man)
248
+ return -ENOMEM;
249
+
250
+ man->func = func;
251
+ man->use_tt = true;
252
+ ttm_resource_manager_init(man, size_pages);
253
+ ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, man);
254
+ ttm_resource_manager_set_used(man, true);
255
+ return 0;
256
+}
257
+
258
+static void
259
+nouveau_ttm_fini_gtt(struct nouveau_drm *drm)
260
+{
261
+ struct ttm_resource_manager *man = ttm_manager_type(&drm->ttm.bdev, TTM_PL_TT);
262
+
263
+ if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA &&
264
+ drm->agp.bridge)
265
+ ttm_range_man_fini(&drm->ttm.bdev, TTM_PL_TT);
266
+ else {
267
+ ttm_resource_manager_set_used(man, false);
268
+ ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man);
269
+ ttm_resource_manager_cleanup(man);
270
+ ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, NULL);
271
+ kfree(man);
272
+ }
256273 }
257274
258275 int
....@@ -296,15 +313,10 @@
296313 drm->agp.cma = pci->agp.cma;
297314 }
298315
299
- ret = nouveau_ttm_global_init(drm);
300
- if (ret)
301
- return ret;
302
-
303316 ret = ttm_bo_device_init(&drm->ttm.bdev,
304
- drm->ttm.bo_global_ref.ref.object,
305317 &nouveau_bo_driver,
306318 dev->anon_inode->i_mapping,
307
- DRM_FILE_PAGE_OFFSET,
319
+ dev->vma_offset_manager,
308320 drm->client.mmu.dmabits <= 32 ? true : false);
309321 if (ret) {
310322 NV_ERROR(drm, "error initialising bo driver, %d\n", ret);
....@@ -317,8 +329,7 @@
317329 arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1),
318330 device->func->resource_size(device, 1));
319331
320
- ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM,
321
- drm->gem.vram_available >> PAGE_SHIFT);
332
+ ret = nouveau_ttm_init_vram(drm);
322333 if (ret) {
323334 NV_ERROR(drm, "VRAM mm init failed, %d\n", ret);
324335 return ret;
....@@ -334,12 +345,14 @@
334345 drm->gem.gart_available = drm->agp.size;
335346 }
336347
337
- ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_TT,
338
- drm->gem.gart_available >> PAGE_SHIFT);
348
+ ret = nouveau_ttm_init_gtt(drm);
339349 if (ret) {
340350 NV_ERROR(drm, "GART mm init failed, %d\n", ret);
341351 return ret;
342352 }
353
+
354
+ mutex_init(&drm->ttm.io_reserve_mutex);
355
+ INIT_LIST_HEAD(&drm->ttm.io_reserve_lru);
343356
344357 NV_INFO(drm, "VRAM: %d MiB\n", (u32)(drm->gem.vram_available >> 20));
345358 NV_INFO(drm, "GART: %d MiB\n", (u32)(drm->gem.gart_available >> 20));
....@@ -351,12 +364,10 @@
351364 {
352365 struct nvkm_device *device = nvxx_device(&drm->client.device);
353366
354
- ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_VRAM);
355
- ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_TT);
367
+ nouveau_ttm_fini_vram(drm);
368
+ nouveau_ttm_fini_gtt(drm);
356369
357370 ttm_bo_device_release(&drm->ttm.bdev);
358
-
359
- nouveau_ttm_global_release(drm);
360371
361372 arch_phys_wc_del(drm->ttm.mtrr);
362373 drm->ttm.mtrr = 0;