Commit 6e08e099 authored by Felix Kuehling's avatar Felix Kuehling Committed by Oded Gabbay

drm/amdgpu: Avoid reclaim while holding locks taken in MMU notifier

When an MMU notifier runs in memory reclaim context, it can deadlock
trying to take locks that are already held in the thread causing the
memory reclaim. The solution is to avoid memory reclaim while holding
locks that are taken in MMU notifiers.

This commit fixes kmalloc while holding rmn->lock by moving the call
outside the lock. The GFX MMU notifier also locks reservation objects.
I have no good solution for avoiding reclaim while holding reservation
objects. The HSA MMU notifier will not lock any reservation objects.

v2: Moved allocation outside lock instead of using GFP_NOIO
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Acked-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent 0919195f
...@@ -380,7 +380,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) ...@@ -380,7 +380,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
enum amdgpu_mn_type type = enum amdgpu_mn_type type =
bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX; bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX;
struct amdgpu_mn *rmn; struct amdgpu_mn *rmn;
struct amdgpu_mn_node *node = NULL; struct amdgpu_mn_node *node = NULL, *new_node;
struct list_head bos; struct list_head bos;
struct interval_tree_node *it; struct interval_tree_node *it;
...@@ -388,6 +388,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) ...@@ -388,6 +388,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
if (IS_ERR(rmn)) if (IS_ERR(rmn))
return PTR_ERR(rmn); return PTR_ERR(rmn);
new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
if (!new_node)
return -ENOMEM;
INIT_LIST_HEAD(&bos); INIT_LIST_HEAD(&bos);
down_write(&rmn->lock); down_write(&rmn->lock);
...@@ -401,13 +405,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr) ...@@ -401,13 +405,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
list_splice(&node->bos, &bos); list_splice(&node->bos, &bos);
} }
if (!node) { if (!node)
node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL); node = new_node;
if (!node) { else
up_write(&rmn->lock); kfree(new_node);
return -ENOMEM;
}
}
bo->mn = rmn; bo->mn = rmn;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment