[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 Oded,

it looks sane to me and is Reviewed-by: Christian König 
<christian.koenig at amd.com>.

Christian.

Am 11.05.2018 um 09:38 schrieb Oded Gabbay:
> 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