aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-03-08 11:47:46 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-03-09 13:04:01 -0500
commitb5a5ec55041bf129b767e7a2d282887226f4fae1 (patch)
treebbd48925df0a3e9b581284dcdaa04524c6fc5373 /drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
parentfb29b57c34488b343db2e3f00e713901385f8c0d (diff)
drm/amdgpu: reserve the PD during unmap and remove
We not only need to protect the mapping tree and freed list itself, but also the items on those list. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index cb27754ec07f..7f6b4d9841e5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -140,25 +140,40 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri
140void amdgpu_gem_object_close(struct drm_gem_object *obj, 140void amdgpu_gem_object_close(struct drm_gem_object *obj,
141 struct drm_file *file_priv) 141 struct drm_file *file_priv)
142{ 142{
143 struct amdgpu_bo *rbo = gem_to_amdgpu_bo(obj); 143 struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
144 struct amdgpu_device *adev = rbo->adev; 144 struct amdgpu_device *adev = bo->adev;
145 struct amdgpu_fpriv *fpriv = file_priv->driver_priv; 145 struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
146 struct amdgpu_vm *vm = &fpriv->vm; 146 struct amdgpu_vm *vm = &fpriv->vm;
147
148 struct amdgpu_bo_list_entry vm_pd;
149 struct list_head list, duplicates;
150 struct ttm_validate_buffer tv;
151 struct ww_acquire_ctx ticket;
147 struct amdgpu_bo_va *bo_va; 152 struct amdgpu_bo_va *bo_va;
148 int r; 153 int r;
149 r = amdgpu_bo_reserve(rbo, true); 154
155 INIT_LIST_HEAD(&list);
156 INIT_LIST_HEAD(&duplicates);
157
158 tv.bo = &bo->tbo;
159 tv.shared = true;
160 list_add(&tv.head, &list);
161
162 amdgpu_vm_get_pd_bo(vm, &list, &vm_pd);
163
164 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
150 if (r) { 165 if (r) {
151 dev_err(adev->dev, "leaking bo va because " 166 dev_err(adev->dev, "leaking bo va because "
152 "we fail to reserve bo (%d)\n", r); 167 "we fail to reserve bo (%d)\n", r);
153 return; 168 return;
154 } 169 }
155 bo_va = amdgpu_vm_bo_find(vm, rbo); 170 bo_va = amdgpu_vm_bo_find(vm, bo);
156 if (bo_va) { 171 if (bo_va) {
157 if (--bo_va->ref_count == 0) { 172 if (--bo_va->ref_count == 0) {
158 amdgpu_vm_bo_rmv(adev, bo_va); 173 amdgpu_vm_bo_rmv(adev, bo_va);
159 } 174 }
160 } 175 }
161 amdgpu_bo_unreserve(rbo); 176 ttm_eu_backoff_reservation(&ticket, &list);
162} 177}
163 178
164static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) 179static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r)
@@ -580,11 +595,10 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
580 tv.shared = true; 595 tv.shared = true;
581 list_add(&tv.head, &list); 596 list_add(&tv.head, &list);
582 597
583 if (args->operation == AMDGPU_VA_OP_MAP) { 598 tv_pd.bo = &fpriv->vm.page_directory->tbo;
584 tv_pd.bo = &fpriv->vm.page_directory->tbo; 599 tv_pd.shared = true;
585 tv_pd.shared = true; 600 list_add(&tv_pd.head, &list);
586 list_add(&tv_pd.head, &list); 601
587 }
588 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); 602 r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates);
589 if (r) { 603 if (r) {
590 drm_gem_object_unreference_unlocked(gobj); 604 drm_gem_object_unreference_unlocked(gobj);