diff options
author | Christian König <christian.koenig@amd.com> | 2016-03-08 11:47:46 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-03-09 13:04:01 -0500 |
commit | b5a5ec55041bf129b767e7a2d282887226f4fae1 (patch) | |
tree | bbd48925df0a3e9b581284dcdaa04524c6fc5373 /drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |
parent | fb29b57c34488b343db2e3f00e713901385f8c0d (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.c | 34 |
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 | |||
140 | void amdgpu_gem_object_close(struct drm_gem_object *obj, | 140 | void 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 | ||
164 | static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) | 179 | static 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); |