[PATCH 3/6] drm/amdgpu: Avoid reclaim while holding locks taken in MMU notifier
Oded Gabbay
oded.gabbay at gmail.com
Fri May 11 07:38:29 UTC 2018
Hi Felix,
Same as patch 2. ACK but I want an extra review from amdgpu people.
Thanks,
Oded
On Fri, Mar 23, 2018 at 10:32 PM, Felix Kuehling <Felix.Kuehling at amd.com> wrote:
> 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: Felix Kuehling <Felix.Kuehling at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 17 +++++++++--------
> 1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index f2ed18e..83e344f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -380,7 +380,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
> enum amdgpu_mn_type type =
> bo->kfd_bo ? AMDGPU_MN_TYPE_HSA : AMDGPU_MN_TYPE_GFX;
> struct amdgpu_mn *rmn;
> - struct amdgpu_mn_node *node = NULL;
> + struct amdgpu_mn_node *node = NULL, *new_node;
> struct list_head bos;
> struct interval_tree_node *it;
>
> @@ -388,6 +388,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
> if (IS_ERR(rmn))
> return PTR_ERR(rmn);
>
> + new_node = kmalloc(sizeof(*new_node), GFP_KERNEL);
> + if (!new_node)
> + return -ENOMEM;
> +
> INIT_LIST_HEAD(&bos);
>
> down_write(&rmn->lock);
> @@ -401,13 +405,10 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
> list_splice(&node->bos, &bos);
> }
>
> - if (!node) {
> - node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL);
> - if (!node) {
> - up_write(&rmn->lock);
> - return -ENOMEM;
> - }
> - }
> + if (!node)
> + node = new_node;
> + else
> + kfree(new_node);
>
> bo->mn = rmn;
>
> --
> 2.7.4
>
More information about the amd-gfx
mailing list