[PATCH 3/6] drm/amdgpu: Avoid reclaim while holding locks taken in MMU notifier

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
>


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux