aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-03-01 09:09:25 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-03-08 11:01:49 -0500
commit971fe9a9414b2ccabc11ff6a5ff6be0d6f2dabda (patch)
tree8d9bbb4983b34c39ead2deb849ce8a48cd9102cf /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parentcffadc83c7016ba68721affe5da537ead279e2d2 (diff)
drm/amdgpu: switch the GDS only on demand v2
Switching the GDS space to often seems to be problematic. This patch together with the following can avoid VM faults on context switch. v2: extend commit message a bit Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1) Reviewed-by: Chunming Zhou <david1.zhou@amd.com> (v1)
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c43
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 5fab5b25b935..8642a1ccd6c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -252,16 +252,53 @@ void amdgpu_vm_flush(struct amdgpu_ring *ring,
252 uint32_t gws_base, uint32_t gws_size, 252 uint32_t gws_base, uint32_t gws_size,
253 uint32_t oa_base, uint32_t oa_size) 253 uint32_t oa_base, uint32_t oa_size)
254{ 254{
255 struct amdgpu_device *adev = ring->adev;
256 struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id];
257
255 if (pd_addr != AMDGPU_VM_NO_FLUSH) { 258 if (pd_addr != AMDGPU_VM_NO_FLUSH) {
256 trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id); 259 trace_amdgpu_vm_flush(pd_addr, ring->idx, vm_id);
257 amdgpu_ring_emit_vm_flush(ring, vm_id, pd_addr); 260 amdgpu_ring_emit_vm_flush(ring, vm_id, pd_addr);
258 } 261 }
259 262
260 if (ring->funcs->emit_gds_switch) 263 if (ring->funcs->emit_gds_switch && (
264 mgr_id->gds_base != gds_base ||
265 mgr_id->gds_size != gds_size ||
266 mgr_id->gws_base != gws_base ||
267 mgr_id->gws_size != gws_size ||
268 mgr_id->oa_base != oa_base ||
269 mgr_id->oa_size != oa_size)) {
270
271 mgr_id->gds_base = gds_base;
272 mgr_id->gds_size = gds_size;
273 mgr_id->gws_base = gws_base;
274 mgr_id->gws_size = gws_size;
275 mgr_id->oa_base = oa_base;
276 mgr_id->oa_size = oa_size;
261 amdgpu_ring_emit_gds_switch(ring, vm_id, 277 amdgpu_ring_emit_gds_switch(ring, vm_id,
262 gds_base, gds_size, 278 gds_base, gds_size,
263 gws_base, gws_size, 279 gws_base, gws_size,
264 oa_base, oa_size); 280 oa_base, oa_size);
281 }
282}
283
284/**
285 * amdgpu_vm_reset_id - reset VMID to zero
286 *
287 * @adev: amdgpu device structure
288 * @vm_id: vmid number to use
289 *
290 * Reset saved GDW, GWS and OA to force switch on next flush.
291 */
292void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vm_id)
293{
294 struct amdgpu_vm_manager_id *mgr_id = &adev->vm_manager.ids[vm_id];
295
296 mgr_id->gds_base = 0;
297 mgr_id->gds_size = 0;
298 mgr_id->gws_base = 0;
299 mgr_id->gws_size = 0;
300 mgr_id->oa_base = 0;
301 mgr_id->oa_size = 0;
265} 302}
266 303
267/** 304/**
@@ -1425,9 +1462,11 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
1425 INIT_LIST_HEAD(&adev->vm_manager.ids_lru); 1462 INIT_LIST_HEAD(&adev->vm_manager.ids_lru);
1426 1463
1427 /* skip over VMID 0, since it is the system VM */ 1464 /* skip over VMID 0, since it is the system VM */
1428 for (i = 1; i < adev->vm_manager.num_ids; ++i) 1465 for (i = 1; i < adev->vm_manager.num_ids; ++i) {
1466 amdgpu_vm_reset_id(adev, i);
1429 list_add_tail(&adev->vm_manager.ids[i].list, 1467 list_add_tail(&adev->vm_manager.ids[i].list,
1430 &adev->vm_manager.ids_lru); 1468 &adev->vm_manager.ids_lru);
1469 }
1431 1470
1432 atomic_set(&adev->vm_manager.vm_pte_next_ring, 0); 1471 atomic_set(&adev->vm_manager.vm_pte_next_ring, 0);
1433} 1472}