[PATCH 1/5] drm/amdgpu: Avoid reclaim fs while eviction lock
Christian König
ckoenig.leichtzumerken at gmail.com
Thu Jan 2 09:16:46 UTC 2020
Am 20.12.19 um 07:24 schrieb Alex Sierra:
> [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.
>
> Change-Id: I5531c9337836e7d4a430df3f16dcc82888e8018c
> Signed-off-by: Alex Sierra <alex.sierra at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 14 ++++++-------
> drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 28 +++++++++++++++++++++++++-
> 2 files changed, 34 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index b999b67ff57a..b36daa6230fb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -678,9 +678,9 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
> }
> }
>
> - mutex_lock(&vm->eviction_lock);
> + vm_eviction_lock(vm);
> vm->evicting = false;
> - mutex_unlock(&vm->eviction_lock);
> + vm_eviction_unlock(vm);
>
> return 0;
> }
> @@ -1559,7 +1559,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);
> + vm_eviction_lock(vm);
> if (vm->evicting) {
> r = -EBUSY;
> goto error_unlock;
> @@ -1576,7 +1576,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
> r = vm->update_funcs->commit(¶ms, fence);
>
> error_unlock:
> - mutex_unlock(&vm->eviction_lock);
> + vm_eviction_unlock(vm);
> return r;
> }
>
> @@ -2537,18 +2537,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 (!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);
> + vm_eviction_unlock(bo_base->vm);
> return false;
> }
>
> bo_base->vm->evicting = true;
> - mutex_unlock(&bo_base->vm->eviction_lock);
> + vm_eviction_unlock(bo_base->vm);
> return true;
> }
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 100547f094ff..d35aa76469ec 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -30,6 +30,7 @@
> #include <drm/gpu_scheduler.h>
> #include <drm/drm_file.h>
> #include <drm/ttm/ttm_bo_driver.h>
> +#include <linux/sched/mm.h>
>
> #include "amdgpu_sync.h"
> #include "amdgpu_ring.h"
> @@ -242,9 +243,12 @@ struct amdgpu_vm {
> /* tree of virtual addresses mapped */
> struct rb_root_cached va;
>
> - /* Lock to prevent eviction while we are updating page tables */
> + /* Lock to prevent eviction while we are updating page tables
> + * use vm_eviction_lock/unlock(vm)
> + */
> struct mutex eviction_lock;
> bool evicting;
> + unsigned int saved_flags;
>
> /* BOs who needs a validation */
> struct list_head evicted;
> @@ -436,4 +440,26 @@ void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
> struct amdgpu_vm *vm);
> void amdgpu_vm_del_from_lru_notify(struct ttm_buffer_object *bo);
>
> +/* 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 vm_eviction_lock(struct amdgpu_vm *vm)
Please add a proper amdgpu_ prefix to the function names.
Additional to that please don't put local static functions into the
header, those shouldn't be used outside of the VM code.
Christian.
> +{
> + mutex_lock(&vm->eviction_lock);
> + vm->saved_flags = memalloc_nofs_save();
> +}
> +static inline int 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 vm_eviction_unlock(struct amdgpu_vm *vm)
> +{
> + memalloc_nofs_restore(vm->saved_flags);
> + mutex_unlock(&vm->eviction_lock);
> +}
> #endif
More information about the amd-gfx
mailing list