Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: unmap and remove csa_va properly

Root PD BO should be reserved before unmap and remove
a bo_va from VM otherwise lockdep will complain.

v2: check fpriv->csa_va is not NULL instead of amdgpu_mcbp (christian)

[14616.936827] WARNING: CPU: 6 PID: 1711 at drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c:1762 amdgpu_vm_bo_del+0x399/0x3f0 [amdgpu]
[14616.937096] Call Trace:
[14616.937097] <TASK>
[14616.937102] amdgpu_driver_postclose_kms+0x249/0x2f0 [amdgpu]
[14616.937187] drm_file_free+0x1d6/0x300 [drm]
[14616.937207] drm_close_helper.isra.0+0x62/0x70 [drm]
[14616.937220] drm_release+0x5e/0x100 [drm]
[14616.937234] __fput+0x9f/0x280
[14616.937239] ____fput+0xe/0x20
[14616.937241] task_work_run+0x61/0x90
[14616.937246] exit_to_user_mode_prepare+0x215/0x220
[14616.937251] syscall_exit_to_user_mode+0x2a/0x60
[14616.937254] do_syscall_64+0x48/0x90
[14616.937257] entry_SYSCALL_64_after_hwframe+0x63/0xcd

Signed-off-by: Lang Yu <Lang.Yu@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Lang Yu and committed by
Alex Deucher
5daff15c eaa7d830

+46 -5
+38
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c
··· 106 106 ttm_eu_backoff_reservation(&ticket, &list); 107 107 return 0; 108 108 } 109 + 110 + int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, 111 + struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va, 112 + uint64_t csa_addr) 113 + { 114 + struct ww_acquire_ctx ticket; 115 + struct list_head list; 116 + struct amdgpu_bo_list_entry pd; 117 + struct ttm_validate_buffer csa_tv; 118 + int r; 119 + 120 + INIT_LIST_HEAD(&list); 121 + INIT_LIST_HEAD(&csa_tv.head); 122 + csa_tv.bo = &bo->tbo; 123 + csa_tv.num_shared = 1; 124 + 125 + list_add(&csa_tv.head, &list); 126 + amdgpu_vm_get_pd_bo(vm, &list, &pd); 127 + 128 + r = ttm_eu_reserve_buffers(&ticket, &list, true, NULL); 129 + if (r) { 130 + DRM_ERROR("failed to reserve CSA,PD BOs: err=%d\n", r); 131 + return r; 132 + } 133 + 134 + r = amdgpu_vm_bo_unmap(adev, bo_va, csa_addr); 135 + if (r) { 136 + DRM_ERROR("failed to do bo_unmap on static CSA, err=%d\n", r); 137 + ttm_eu_backoff_reservation(&ticket, &list); 138 + return r; 139 + } 140 + 141 + amdgpu_vm_bo_del(adev, bo_va); 142 + 143 + ttm_eu_backoff_reservation(&ticket, &list); 144 + 145 + return 0; 146 + }
+3
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.h
··· 34 34 int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, 35 35 struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va, 36 36 uint64_t csa_addr, uint32_t size); 37 + int amdgpu_unmap_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, 38 + struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va, 39 + uint64_t csa_addr); 37 40 void amdgpu_free_static_csa(struct amdgpu_bo **bo); 38 41 39 42 #endif
+5 -5
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
··· 1311 1311 if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE) != NULL) 1312 1312 amdgpu_vce_free_handles(adev, file_priv); 1313 1313 1314 - if (amdgpu_mcbp) { 1315 - /* TODO: how to handle reserve failure */ 1316 - BUG_ON(amdgpu_bo_reserve(adev->virt.csa_obj, true)); 1317 - amdgpu_vm_bo_del(adev, fpriv->csa_va); 1314 + if (fpriv->csa_va) { 1315 + uint64_t csa_addr = amdgpu_csa_vaddr(adev) & AMDGPU_GMC_HOLE_MASK; 1316 + 1317 + WARN_ON(amdgpu_unmap_static_csa(adev, &fpriv->vm, adev->virt.csa_obj, 1318 + fpriv->csa_va, csa_addr)); 1318 1319 fpriv->csa_va = NULL; 1319 - amdgpu_bo_unreserve(adev->virt.csa_obj); 1320 1320 } 1321 1321 1322 1322 pasid = fpriv->vm.pasid;