Skip to content

Commit fd1fa48

Browse files
ChristianKoenigAMDalexdeucher
authored andcommitted
drm/amdgpu: lock both VM and BO in amdgpu_gem_object_open
The VM was not locked in the past since we initially only cleared the linked list element and not added it to any VM state. But this has changed quite some time ago, we just never realized this problem because the VM state lock was masking it. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
1 parent abde491 commit fd1fa48

4 files changed

Lines changed: 42 additions & 11 deletions

File tree

drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
878878
struct amdgpu_bo *bo[2] = {NULL, NULL};
879879
struct amdgpu_bo_va *bo_va;
880880
bool same_hive = false;
881+
struct drm_exec exec;
881882
int i, ret;
882883

883884
if (!va) {
@@ -958,19 +959,25 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
958959
goto unwind;
959960
}
960961

961-
/* Add BO to VM internal data structures */
962-
ret = amdgpu_bo_reserve(bo[i], false);
963-
if (ret) {
964-
pr_debug("Unable to reserve BO during memory attach");
965-
goto unwind;
962+
drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
963+
drm_exec_until_all_locked(&exec) {
964+
ret = amdgpu_vm_lock_pd(vm, &exec, 0);
965+
drm_exec_retry_on_contention(&exec);
966+
if (unlikely(ret))
967+
goto unwind;
968+
ret = drm_exec_lock_obj(&exec, &bo[i]->tbo.base);
969+
drm_exec_retry_on_contention(&exec);
970+
if (unlikely(ret))
971+
goto unwind;
966972
}
973+
967974
bo_va = amdgpu_vm_bo_find(vm, bo[i]);
968975
if (!bo_va)
969976
bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]);
970977
else
971978
++bo_va->ref_count;
972979
attachment[i]->bo_va = bo_va;
973-
amdgpu_bo_unreserve(bo[i]);
980+
drm_exec_fini(&exec);
974981
if (unlikely(!attachment[i]->bo_va)) {
975982
ret = -ENOMEM;
976983
pr_err("Failed to add BO object to VM. ret == %d\n",

drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
232232
struct amdgpu_vm *vm = &fpriv->vm;
233233
struct amdgpu_bo_va *bo_va;
234234
struct mm_struct *mm;
235+
struct drm_exec exec;
235236
int r;
236237

237238
mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm);
@@ -242,9 +243,18 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
242243
!amdgpu_vm_is_bo_always_valid(vm, abo))
243244
return -EPERM;
244245

245-
r = amdgpu_bo_reserve(abo, false);
246-
if (r)
247-
return r;
246+
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
247+
drm_exec_until_all_locked(&exec) {
248+
r = drm_exec_prepare_obj(&exec, &abo->tbo.base, 1);
249+
drm_exec_retry_on_contention(&exec);
250+
if (unlikely(r))
251+
goto out_unlock;
252+
253+
r = amdgpu_vm_lock_pd(vm, &exec, 0);
254+
drm_exec_retry_on_contention(&exec);
255+
if (unlikely(r))
256+
goto out_unlock;
257+
}
248258

249259
amdgpu_vm_bo_update_shared(abo);
250260
bo_va = amdgpu_vm_bo_find(vm, abo);
@@ -260,8 +270,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
260270
amdgpu_bo_unreserve(abo);
261271
return r;
262272
}
263-
264-
amdgpu_bo_unreserve(abo);
273+
drm_exec_fini(&exec);
265274

266275
/* Validate and add eviction fence to DMABuf imports with dynamic
267276
* attachment in compute VMs. Re-validation will be done by
@@ -294,7 +303,10 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj,
294303
}
295304
}
296305
mutex_unlock(&vm->process_info->lock);
306+
return r;
297307

308+
out_unlock:
309+
drm_exec_fini(&exec);
298310
return r;
299311
}
300312

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1445,6 +1445,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
14451445
{
14461446
struct amdgpu_device *adev = drm_to_adev(dev);
14471447
struct amdgpu_fpriv *fpriv;
1448+
struct drm_exec exec;
14481449
int r, pasid;
14491450

14501451
/* Ensure IB tests are run on ring */
@@ -1484,7 +1485,16 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
14841485
if (r)
14851486
goto error_pasid;
14861487

1488+
drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0);
1489+
drm_exec_until_all_locked(&exec) {
1490+
r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 0);
1491+
drm_exec_retry_on_contention(&exec);
1492+
if (unlikely(r))
1493+
goto error_vm;
1494+
}
1495+
14871496
fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL);
1497+
drm_exec_fini(&exec);
14881498
if (!fpriv->prt_va) {
14891499
r = -ENOMEM;
14901500
goto error_vm;

drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
17351735
{
17361736
struct amdgpu_bo_va *bo_va;
17371737

1738+
amdgpu_vm_assert_locked(vm);
1739+
17381740
bo_va = kzalloc(sizeof(struct amdgpu_bo_va), GFP_KERNEL);
17391741
if (bo_va == NULL) {
17401742
return NULL;

0 commit comments

Comments
 (0)