summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
authorAlex Sierra <alex.sierra@amd.com>2019-12-17 16:57:30 -0600
committerAlex Deucher <alexander.deucher@amd.com>2020-01-16 13:33:16 -0500
commita269e44989f3e77fb2ebfb995b8d501924ed07e2 (patch)
treeb9d3d82cec052d8b7599a5cd1e39c8cc4446a208 /drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
parenta9ffe2a9833835b157a53dcc4d725f71426f55ff (diff)
drm/amdgpu: Avoid reclaim fs while eviction lock
[Why] Avoid reclaim filesystem while eviction lock is held called from MMU notifier. [How] Setting PF_MEMALLOC_NOFS flags while eviction mutex is locked. Using memalloc_nofs_save / memalloc_nofs_restore API. Signed-off-by: Alex Sierra <alex.sierra@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 4dc75eda1d91..d16231d6a790 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -83,6 +83,32 @@ struct amdgpu_prt_cb {
};
/**
+ * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
+ * happens while holding this lock anywhere to prevent deadlocks when
+ * an MMU notifier runs in reclaim-FS context.
+ */
+static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
+{
+ mutex_lock(&vm->eviction_lock);
+ vm->saved_flags = memalloc_nofs_save();
+}
+
+static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
+{
+ if (mutex_trylock(&vm->eviction_lock)) {
+ vm->saved_flags = memalloc_nofs_save();
+ return 1;
+ }
+ return 0;
+}
+
+static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
+{
+ memalloc_nofs_restore(vm->saved_flags);
+ mutex_unlock(&vm->eviction_lock);
+}
+
+/**
* amdgpu_vm_level_shift - return the addr shift for each level
*
* @adev: amdgpu_device pointer
@@ -678,9 +704,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
}
}
- mutex_lock(&vm->eviction_lock);
+ amdgpu_vm_eviction_lock(vm);
vm->evicting = false;
- mutex_unlock(&vm->eviction_lock);
+ amdgpu_vm_eviction_unlock(vm);
return 0;
}
@@ -1559,7 +1585,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
if (!(flags & AMDGPU_PTE_VALID))
owner = AMDGPU_FENCE_OWNER_KFD;
- mutex_lock(&vm->eviction_lock);
+ amdgpu_vm_eviction_lock(vm);
if (vm->evicting) {
r = -EBUSY;
goto error_unlock;
@@ -1576,7 +1602,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
r = vm->update_funcs->commit(&params, fence);
error_unlock:
- mutex_unlock(&vm->eviction_lock);
+ amdgpu_vm_eviction_unlock(vm);
return r;
}
@@ -2533,18 +2559,18 @@ bool amdgpu_vm_evictable(struct amdgpu_bo *bo)
return false;
/* Try to block ongoing updates */
- if (!mutex_trylock(&bo_base->vm->eviction_lock))
+ if (!amdgpu_vm_eviction_trylock(bo_base->vm))
return false;
/* Don't evict VM page tables while they are updated */
if (!dma_fence_is_signaled(bo_base->vm->last_direct) ||
!dma_fence_is_signaled(bo_base->vm->last_delayed)) {
- mutex_unlock(&bo_base->vm->eviction_lock);
+ amdgpu_vm_eviction_unlock(bo_base->vm);
return false;
}
bo_base->vm->evicting = true;
- mutex_unlock(&bo_base->vm->eviction_lock);
+ amdgpu_vm_eviction_unlock(bo_base->vm);
return true;
}