Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers v4

2019-06-04 Thread Kuehling, Felix
On 2019-06-04 16:13, Yang, Philip wrote:
> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
> path. The old hmm APIs are deprecated and will be removed in future.
>
> Below are changes in driver:
>
> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
> supports range with multiple vmas, remove the multiple vmas handle path
> and data structure.
> 2. Change hmm_vma_range_done to hmm_range_unregister.
> 3. Use default flags to avoid pre-fill pfn arrays.
> 4. Use new hmm_device_ helpers.
>
> v2: retry if hmm_range_fault returns -EAGAIN
> v3: define MAX_RETRY_HMM_RANGE_FAULT, skip drop mmap_sem if retry
> v4: fine grained up_read(mm->mmap_sem)
>
> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
> Signed-off-by: Philip Yang 

Reviewed-by: Felix Kuehling 

Thanks,
   Felix


> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 152 +++-
>   2 files changed, 68 insertions(+), 85 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index 41ccee49a224..e0bb47ce570b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>   range->flags = hmm_range_flags;
>   range->values = hmm_range_values;
>   range->pfn_shift = PAGE_SHIFT;
> - range->pfns = NULL;
>   INIT_LIST_HEAD(>list);
>   }
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index eb4b85061c7e..00790207086a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>   struct task_struct  *usertask;
>   uint32_tuserflags;
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
> - struct hmm_range*ranges;
> - int nr_ranges;
> + struct hmm_range*range;
>   #endif
>   };
>   
> @@ -725,57 +724,36 @@ struct amdgpu_ttm_tt {
>*/
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>   
> -/* Support Userptr pages cross max 16 vmas */
> -#define MAX_NR_VMAS  (16)
> +#define MAX_RETRY_HMM_RANGE_FAULT16
>   
>   int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>   {
>   struct amdgpu_ttm_tt *gtt = (void *)ttm;
>   struct mm_struct *mm = gtt->usertask->mm;
>   unsigned long start = gtt->userptr;
> - unsigned long end = start + ttm->num_pages * PAGE_SIZE;
> - struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
> - struct hmm_range *ranges;
> - unsigned long nr_pages, i;
> - uint64_t *pfns, f;
> + struct vm_area_struct *vma;
> + struct hmm_range *range;
> + unsigned long i;
> + uint64_t *pfns;
> + int retry = 0;
>   int r = 0;
>   
>   if (!mm) /* Happens during process shutdown */
>   return -ESRCH;
>   
> - down_read(>mmap_sem);
> -
> - /* user pages may cross multiple VMAs */
> - gtt->nr_ranges = 0;
> - do {
> - unsigned long vm_start;
> -
> - if (gtt->nr_ranges >= MAX_NR_VMAS) {
> - DRM_ERROR("Too many VMAs in userptr range\n");
> - r = -EFAULT;
> - goto out;
> - }
> -
> - vm_start = vma ? vma->vm_end : start;
> - vma = find_vma(mm, vm_start);
> - if (unlikely(!vma || vm_start < vma->vm_start)) {
> - r = -EFAULT;
> - goto out;
> - }
> - vmas[gtt->nr_ranges++] = vma;
> - } while (end > vma->vm_end);
> -
> - DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
> - start, gtt->nr_ranges, ttm->num_pages);
> -
> + vma = find_vma(mm, start);
> + if (unlikely(!vma || start < vma->vm_start)) {
> + r = -EFAULT;
> + goto out;
> + }
>   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
> - vmas[0]->vm_file)) {
> + vma->vm_file)) {
>   r = -EPERM;
>   goto out;
>   }
>   
> - ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
> - if (unlikely(!ranges)) {
> + range = kzalloc(sizeof(*range), GFP_KERNEL);
> + if (unlikely(!range)) {
>   r = -ENOMEM;
>   goto out;
>   }
> @@ -786,61 +764,67 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   goto out_free_ranges;
>   }
>   
> - for (i = 0; i < gtt->nr_ranges; i++)
> - amdgpu_hmm_init_range([i]);
> + amdgpu_hmm_init_range(range);
> + range->default_flags = range->flags[HMM_PFN_VALID];
> + range->default_flags |= amdgpu_ttm_tt_is_readonly(ttm) ?
> + 0 : 

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers v3

2019-06-03 Thread Kuehling, Felix
[+Jerome]

On 2019-06-03 7:20 p.m., Yang, Philip wrote:
>
> On 2019-06-03 5:02 p.m., Kuehling, Felix wrote:
>> On 2019-06-03 2:44 p.m., Yang, Philip wrote:
>>> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
>>> path. The old hmm APIs are deprecated and will be removed in future.
>>>
>>> Below are changes in driver:
>>>
>>> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
>>> supports range with multiple vmas, remove the multiple vmas handle path
>>> and data structure.
>>> 2. Change hmm_vma_range_done to hmm_range_unregister.
>>> 3. Use default flags to avoid pre-fill pfn arrays.
>>> 4. Use new hmm_device_ helpers.
>>>
>>> v2: retry if hmm_range_fault returns -EAGAIN
>>> v3: define MAX_RETRY_HMM_RANGE_FAULT, skip drop mmap_sem if retry
>> I think dropping mmap_sem for retry was correct in v2 of this patch. Now
>> you will try to take the mmap_sem multiple times without dropping it if
>> you retry.
>>
>> We don't need to hold the mmap_sem during hmm_range_wait_until_valid.
>>
> hmm_range_fault will drop the mmap_sem internally before returning
> -EAGAIN, I think it does this on purpose to avoid upper level call retry
> whithout release mmap_sem in between.

Good catch.

Looks like the documentation of hmm_range_fault is outdated. It says 
-EAGAIN can only be returned if block==false, and that mmap_sem is not 
dropped if block==true. Both of these statements are no longer true.

The example code in Documentation/vm/hmm.rst drops the mmap_sem 
explicitly after hmm_range_snapshot returned -EAGAIN. It seems that 
hmm_range_snapshot behaves subtly differently from hmm_range_fault with 
respect to dropping the mmap_sem. That's very confusing and annoying.

Regards,
   Felix


>   I find v2 was incorrect after
> reading hmm code again today. I should mention details of this change in
> my commit, see more below.
>
> Philip
>
>> See more below ...
>>
>>
>>> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
>>> Signed-off-by: Philip Yang 
>>> ---
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>>> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 149 ++--
>>> 2 files changed, 64 insertions(+), 86 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>>> index 41ccee49a224..e0bb47ce570b 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>>> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>>> range->flags = hmm_range_flags;
>>> range->values = hmm_range_values;
>>> range->pfn_shift = PAGE_SHIFT;
>>> -   range->pfns = NULL;
>>> INIT_LIST_HEAD(>list);
>>> }
>>> }
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> index eb4b85061c7e..9de6a2f5e572 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>>> struct task_struct  *usertask;
>>> uint32_tuserflags;
>>> #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>> -   struct hmm_range*ranges;
>>> -   int nr_ranges;
>>> +   struct hmm_range*range;
>>> #endif
>>> };
>>> 
>>> @@ -725,57 +724,36 @@ struct amdgpu_ttm_tt {
>>>  */
>>> #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>> 
>>> -/* Support Userptr pages cross max 16 vmas */
>>> -#define MAX_NR_VMAS(16)
>>> +#define MAX_RETRY_HMM_RANGE_FAULT  16
>>> 
>>> int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page 
>>> **pages)
>>> {
>>> struct amdgpu_ttm_tt *gtt = (void *)ttm;
>>> struct mm_struct *mm = gtt->usertask->mm;
>>> unsigned long start = gtt->userptr;
>>> -   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
>>> -   struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
>>> -   struct hmm_range *ranges;
>>> -   unsigned long nr_pages, i;
>>> -   uint64_t *pfns, f;
>>> +   struct vm_area_struct *vma;
>>> +   struct hmm_range *range;
>>> +   unsigned long i;
>>> +   uint64_t *pfns;
>>> +   int retry = 0;
>>> int r = 0;
>>> 
>>> if (!mm) /* Happens during process shutdown */
>>> return -ESRCH;
>>> 
>>> -   down_read(>mmap_sem);
>>> -
>>> -   /* user pages may cross multiple VMAs */
>>> -   gtt->nr_ranges = 0;
>>> -   do {
>>> -   unsigned long vm_start;
>>> -
>>> -   if (gtt->nr_ranges >= MAX_NR_VMAS) {
>>> -   DRM_ERROR("Too many VMAs in userptr range\n");
>>> -   r = -EFAULT;
>>> -   goto out;
>>> -   }
>>> -
>>> -   vm_start = vma ? vma->vm_end : start;
>>> -   vma = find_vma(mm, vm_start);
>>> -   if (unlikely(!vma || vm_start < 

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers v3

2019-06-03 Thread Yang, Philip


On 2019-06-03 5:02 p.m., Kuehling, Felix wrote:
> On 2019-06-03 2:44 p.m., Yang, Philip wrote:
>> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
>> path. The old hmm APIs are deprecated and will be removed in future.
>>
>> Below are changes in driver:
>>
>> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
>> supports range with multiple vmas, remove the multiple vmas handle path
>> and data structure.
>> 2. Change hmm_vma_range_done to hmm_range_unregister.
>> 3. Use default flags to avoid pre-fill pfn arrays.
>> 4. Use new hmm_device_ helpers.
>>
>> v2: retry if hmm_range_fault returns -EAGAIN
>> v3: define MAX_RETRY_HMM_RANGE_FAULT, skip drop mmap_sem if retry
> 
> I think dropping mmap_sem for retry was correct in v2 of this patch. Now
> you will try to take the mmap_sem multiple times without dropping it if
> you retry.
> 
> We don't need to hold the mmap_sem during hmm_range_wait_until_valid.
> 
hmm_range_fault will drop the mmap_sem internally before returning 
-EAGAIN, I think it does this on purpose to avoid upper level call retry 
whithout release mmap_sem in between. I find v2 was incorrect after 
reading hmm code again today. I should mention details of this change in 
my commit, see more below.

Philip

> See more below ...
> 
> 
>>
>> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>>drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 149 ++--
>>2 files changed, 64 insertions(+), 86 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> index 41ccee49a224..e0bb47ce570b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>>  range->flags = hmm_range_flags;
>>  range->values = hmm_range_values;
>>  range->pfn_shift = PAGE_SHIFT;
>> -range->pfns = NULL;
>>  INIT_LIST_HEAD(>list);
>>  }
>>}
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index eb4b85061c7e..9de6a2f5e572 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>>  struct task_struct  *usertask;
>>  uint32_tuserflags;
>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>> -struct hmm_range*ranges;
>> -int nr_ranges;
>> +struct hmm_range*range;
>>#endif
>>};
>>
>> @@ -725,57 +724,36 @@ struct amdgpu_ttm_tt {
>> */
>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>
>> -/* Support Userptr pages cross max 16 vmas */
>> -#define MAX_NR_VMAS (16)
>> +#define MAX_RETRY_HMM_RANGE_FAULT   16
>>
>>int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>>{
>>  struct amdgpu_ttm_tt *gtt = (void *)ttm;
>>  struct mm_struct *mm = gtt->usertask->mm;
>>  unsigned long start = gtt->userptr;
>> -unsigned long end = start + ttm->num_pages * PAGE_SIZE;
>> -struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
>> -struct hmm_range *ranges;
>> -unsigned long nr_pages, i;
>> -uint64_t *pfns, f;
>> +struct vm_area_struct *vma;
>> +struct hmm_range *range;
>> +unsigned long i;
>> +uint64_t *pfns;
>> +int retry = 0;
>>  int r = 0;
>>
>>  if (!mm) /* Happens during process shutdown */
>>  return -ESRCH;
>>
>> -down_read(>mmap_sem);
>> -
>> -/* user pages may cross multiple VMAs */
>> -gtt->nr_ranges = 0;
>> -do {
>> -unsigned long vm_start;
>> -
>> -if (gtt->nr_ranges >= MAX_NR_VMAS) {
>> -DRM_ERROR("Too many VMAs in userptr range\n");
>> -r = -EFAULT;
>> -goto out;
>> -}
>> -
>> -vm_start = vma ? vma->vm_end : start;
>> -vma = find_vma(mm, vm_start);
>> -if (unlikely(!vma || vm_start < vma->vm_start)) {
>> -r = -EFAULT;
>> -goto out;
>> -}
>> -vmas[gtt->nr_ranges++] = vma;
>> -} while (end > vma->vm_end);
>> -
>> -DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
>> -start, gtt->nr_ranges, ttm->num_pages);
>> -
>> +vma = find_vma(mm, start);
>> +if (unlikely(!vma || start < vma->vm_start)) {
>> +r = -EFAULT;
>> +goto out;
>> +}
>>  if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
>> -vmas[0]->vm_file)) {
>> +vma->vm_file)) {
>>  r = -EPERM;
>>  goto out;
>>  }
>>
>> -ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
>> -if 

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers v3

2019-06-03 Thread Kuehling, Felix
On 2019-06-03 2:44 p.m., Yang, Philip wrote:
> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
> path. The old hmm APIs are deprecated and will be removed in future.
>
> Below are changes in driver:
>
> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
> supports range with multiple vmas, remove the multiple vmas handle path
> and data structure.
> 2. Change hmm_vma_range_done to hmm_range_unregister.
> 3. Use default flags to avoid pre-fill pfn arrays.
> 4. Use new hmm_device_ helpers.
>
> v2: retry if hmm_range_fault returns -EAGAIN
> v3: define MAX_RETRY_HMM_RANGE_FAULT, skip drop mmap_sem if retry

I think dropping mmap_sem for retry was correct in v2 of this patch. Now 
you will try to take the mmap_sem multiple times without dropping it if 
you retry.

We don't need to hold the mmap_sem during hmm_range_wait_until_valid.

See more below ...


>
> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
> Signed-off-by: Philip Yang 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 149 ++--
>   2 files changed, 64 insertions(+), 86 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index 41ccee49a224..e0bb47ce570b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>   range->flags = hmm_range_flags;
>   range->values = hmm_range_values;
>   range->pfn_shift = PAGE_SHIFT;
> - range->pfns = NULL;
>   INIT_LIST_HEAD(>list);
>   }
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index eb4b85061c7e..9de6a2f5e572 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>   struct task_struct  *usertask;
>   uint32_tuserflags;
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
> - struct hmm_range*ranges;
> - int nr_ranges;
> + struct hmm_range*range;
>   #endif
>   };
>   
> @@ -725,57 +724,36 @@ struct amdgpu_ttm_tt {
>*/
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>   
> -/* Support Userptr pages cross max 16 vmas */
> -#define MAX_NR_VMAS  (16)
> +#define MAX_RETRY_HMM_RANGE_FAULT16
>   
>   int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>   {
>   struct amdgpu_ttm_tt *gtt = (void *)ttm;
>   struct mm_struct *mm = gtt->usertask->mm;
>   unsigned long start = gtt->userptr;
> - unsigned long end = start + ttm->num_pages * PAGE_SIZE;
> - struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
> - struct hmm_range *ranges;
> - unsigned long nr_pages, i;
> - uint64_t *pfns, f;
> + struct vm_area_struct *vma;
> + struct hmm_range *range;
> + unsigned long i;
> + uint64_t *pfns;
> + int retry = 0;
>   int r = 0;
>   
>   if (!mm) /* Happens during process shutdown */
>   return -ESRCH;
>   
> - down_read(>mmap_sem);
> -
> - /* user pages may cross multiple VMAs */
> - gtt->nr_ranges = 0;
> - do {
> - unsigned long vm_start;
> -
> - if (gtt->nr_ranges >= MAX_NR_VMAS) {
> - DRM_ERROR("Too many VMAs in userptr range\n");
> - r = -EFAULT;
> - goto out;
> - }
> -
> - vm_start = vma ? vma->vm_end : start;
> - vma = find_vma(mm, vm_start);
> - if (unlikely(!vma || vm_start < vma->vm_start)) {
> - r = -EFAULT;
> - goto out;
> - }
> - vmas[gtt->nr_ranges++] = vma;
> - } while (end > vma->vm_end);
> -
> - DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
> - start, gtt->nr_ranges, ttm->num_pages);
> -
> + vma = find_vma(mm, start);
> + if (unlikely(!vma || start < vma->vm_start)) {
> + r = -EFAULT;
> + goto out;
> + }
>   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
> - vmas[0]->vm_file)) {
> + vma->vm_file)) {
>   r = -EPERM;
>   goto out;
>   }
>   
> - ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
> - if (unlikely(!ranges)) {
> + range = kzalloc(sizeof(*range), GFP_KERNEL);
> + if (unlikely(!range)) {
>   r = -ENOMEM;
>   goto out;
>   }
> @@ -786,61 +764,62 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   goto out_free_ranges;
>   }
>   
> - for (i = 0; i < gtt->nr_ranges; i++)
> - amdgpu_hmm_init_range([i]);
> + amdgpu_hmm_init_range(range);
> + 

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-06-03 Thread Yang, Philip


On 2019-06-03 7:23 a.m., Christian König wrote:
> Am 03.06.19 um 12:17 schrieb Christian König:
>> Am 01.06.19 um 00:01 schrieb Kuehling, Felix:
>>> On 2019-05-31 5:32 p.m., Yang, Philip wrote:
 On 2019-05-31 3:42 p.m., Kuehling, Felix wrote:
> On 2019-05-31 1:28 p.m., Yang, Philip wrote:
>> On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
       #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
 -    if (gtt->ranges &&
 -    ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
 - gtt->ranges[0].pfns[0]))
 +    if (gtt->range &&
 +    ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
 + gtt->range->pfns[0]))
>>> I think just checking gtt->range here is enough. If gtt->range is 
>>> not
>>> NULL here, we're leaking memory.
>>>
>> If just checking gtt->range, there is a false warning in amdgpu_test
>> userptr case in amdgpu_cs_list_validate path. If userptr is 
>> invalidated,
>> then ttm->pages[0] is outdated pages, lobj->user_pages is new 
>> pages, it
>> goes to ttm_tt_unbind first to unpin old pages (this causes false
>> warning) then call amdgpu_ttm_tt_set_user_pages.
> But doesn't that mean we're leaking the gtt->range somewhere?
>
 ttm_tt_unbind is called from ttm_tt_destroy and 
 amdgpu_cs_list_validate,
 the later one causes false warning. ttm_ttm_destory path is fine to 
 only
 check gtt->range.

 Double checked, amdgpu_ttm_tt_get_user_pages and
 amdgpu_ttm_tt_get_user_pages_done always match in both paths, so no 
 leak
 gtt->range.

 1. amdgpu_gem_userptr_ioctl
  amdgpu_ttm_tt_get_user_pages
  ttm->pages for userptr pages
  amdgpu_ttm_tt_get_user_pages_done

 2. amdgpu_cs_ioctl
  amdgpu_cs_parser_bos
  amdgpu_ttm_tt_get_user_pages
  if (userpage_invalidated)
  e->user_pages for new pages
  amdgpu_cs_list_validate
  if (userpage_invalidated)
     ttm_tt_unbind ttm->pages // this causes warning
 amdgpu_ttm_tt_set_user_pages(ttm->pages, e->user_pages)
>>> Hmm, I think amdgpu_cs is doing something weird there. It does some
>>> double book-keeping of the user pages in the BO list and the TTM BO. We
>>> did something similar for KFD and simplified it when moving to HMM. It
>>> could probably be simplified for amdgpu_cs as well. But not in this
>>> patch series.
>>
>> That actually sounds like a bug to me.
>>
>> It is most likely a leftover from the time when we couldn't get the 
>> pages for a BO while the BO was reserved.
> 
> Mhm, at least it's not racy in the way I thought it would be. But it is 
> certainly still overkill and should be simplified.
> 
> Philip are you taking a look or should I tackle this?
> 
Hi Christian,

I will submit another patch to simplify amdgpu_cs_ioctl path, please 
help review it.

Thanks,
Philip

> Thanks,
> Christian.
> 
>>
>>
>> Going to take a closer look,
>> Christian.
>>
>>>
>>> I'll review your updated change.
>>>
>>> Thanks,
>>>     Felix
>>>
>>>
  amdgpu_cs_submit
  amdgpu_ttm_tt_get_user_pages_done

> Regards,
>       Felix
>
>
>> I will submit patch v2, to add retry if hmm_range_fault returns 
>> -EAGAIN.
>> use kzalloc to allocate small size range.
>>
>> Thanks,
>> Philip
>>
>>> Regards,
>>>     Felix
>>>
>>>
>>> ___
>>> amd-gfx mailing list
>>> amd-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>>
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-06-03 Thread Christian König

Am 03.06.19 um 12:17 schrieb Christian König:

Am 01.06.19 um 00:01 schrieb Kuehling, Felix:

On 2019-05-31 5:32 p.m., Yang, Philip wrote:

On 2019-05-31 3:42 p.m., Kuehling, Felix wrote:

On 2019-05-31 1:28 p.m., Yang, Philip wrote:

On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:

      #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-    if (gtt->ranges &&
-    ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
- gtt->ranges[0].pfns[0]))
+    if (gtt->range &&
+    ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
+ gtt->range->pfns[0]))
I think just checking gtt->range here is enough. If gtt->range is 
not

NULL here, we're leaking memory.


If just checking gtt->range, there is a false warning in amdgpu_test
userptr case in amdgpu_cs_list_validate path. If userptr is 
invalidated,
then ttm->pages[0] is outdated pages, lobj->user_pages is new 
pages, it

goes to ttm_tt_unbind first to unpin old pages (this causes false
warning) then call amdgpu_ttm_tt_set_user_pages.

But doesn't that mean we're leaking the gtt->range somewhere?

ttm_tt_unbind is called from ttm_tt_destroy and 
amdgpu_cs_list_validate,
the later one causes false warning. ttm_ttm_destory path is fine to 
only

check gtt->range.

Double checked, amdgpu_ttm_tt_get_user_pages and
amdgpu_ttm_tt_get_user_pages_done always match in both paths, so no 
leak

gtt->range.

1. amdgpu_gem_userptr_ioctl
 amdgpu_ttm_tt_get_user_pages
 ttm->pages for userptr pages
 amdgpu_ttm_tt_get_user_pages_done

2. amdgpu_cs_ioctl
 amdgpu_cs_parser_bos
 amdgpu_ttm_tt_get_user_pages
 if (userpage_invalidated)
 e->user_pages for new pages
 amdgpu_cs_list_validate
 if (userpage_invalidated)
    ttm_tt_unbind ttm->pages // this causes warning
amdgpu_ttm_tt_set_user_pages(ttm->pages, e->user_pages)

Hmm, I think amdgpu_cs is doing something weird there. It does some
double book-keeping of the user pages in the BO list and the TTM BO. We
did something similar for KFD and simplified it when moving to HMM. It
could probably be simplified for amdgpu_cs as well. But not in this
patch series.


That actually sounds like a bug to me.

It is most likely a leftover from the time when we couldn't get the 
pages for a BO while the BO was reserved.


Mhm, at least it's not racy in the way I thought it would be. But it is 
certainly still overkill and should be simplified.


Philip are you taking a look or should I tackle this?

Thanks,
Christian.




Going to take a closer look,
Christian.



I'll review your updated change.

Thanks,
    Felix



 amdgpu_cs_submit
 amdgpu_ttm_tt_get_user_pages_done


Regards,
      Felix


I will submit patch v2, to add retry if hmm_range_fault returns 
-EAGAIN.

use kzalloc to allocate small size range.

Thanks,
Philip


Regards,
    Felix



___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx




___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-06-03 Thread Christian König

Am 01.06.19 um 00:01 schrieb Kuehling, Felix:

On 2019-05-31 5:32 p.m., Yang, Philip wrote:

On 2019-05-31 3:42 p.m., Kuehling, Felix wrote:

On 2019-05-31 1:28 p.m., Yang, Philip wrote:

On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
   
   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)

-   if (gtt->ranges &&
-   ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
-gtt->ranges[0].pfns[0]))
+   if (gtt->range &&
+   ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
+ gtt->range->pfns[0]))

I think just checking gtt->range here is enough. If gtt->range is not
NULL here, we're leaking memory.


If just checking gtt->range, there is a false warning in amdgpu_test
userptr case in amdgpu_cs_list_validate path. If userptr is invalidated,
then ttm->pages[0] is outdated pages, lobj->user_pages is new pages, it
goes to ttm_tt_unbind first to unpin old pages (this causes false
warning) then call amdgpu_ttm_tt_set_user_pages.

But doesn't that mean we're leaking the gtt->range somewhere?


ttm_tt_unbind is called from ttm_tt_destroy and amdgpu_cs_list_validate,
the later one causes false warning. ttm_ttm_destory path is fine to only
check gtt->range.

Double checked, amdgpu_ttm_tt_get_user_pages and
amdgpu_ttm_tt_get_user_pages_done always match in both paths, so no leak
gtt->range.

1. amdgpu_gem_userptr_ioctl
 amdgpu_ttm_tt_get_user_pages
 ttm->pages for userptr pages
 amdgpu_ttm_tt_get_user_pages_done

2. amdgpu_cs_ioctl
 amdgpu_cs_parser_bos
 amdgpu_ttm_tt_get_user_pages
 if (userpage_invalidated)
 e->user_pages for new pages
 amdgpu_cs_list_validate
 if (userpage_invalidated)
ttm_tt_unbind ttm->pages // this causes warning
amdgpu_ttm_tt_set_user_pages(ttm->pages, e->user_pages)

Hmm, I think amdgpu_cs is doing something weird there. It does some
double book-keeping of the user pages in the BO list and the TTM BO. We
did something similar for KFD and simplified it when moving to HMM. It
could probably be simplified for amdgpu_cs as well. But not in this
patch series.


That actually sounds like a bug to me.

It is most likely a leftover from the time when we couldn't get the 
pages for a BO while the BO was reserved.


Going to take a closer look,
Christian.



I'll review your updated change.

Thanks,
    Felix



 amdgpu_cs_submit
 amdgpu_ttm_tt_get_user_pages_done


Regards,
  Felix



I will submit patch v2, to add retry if hmm_range_fault returns -EAGAIN.
use kzalloc to allocate small size range.

Thanks,
Philip


Regards,
    Felix



___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers v2

2019-05-31 Thread Kuehling, Felix
On 2019-05-31 3:09 p.m., Yang, Philip wrote:
> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
> path. The old hmm APIs are deprecated and will be removed in future.
>
> Below are changes in driver:
>
> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
> supports range with multiple vmas, remove the multiple vmas handle path
> and data structure.
> 2. Change hmm_vma_range_done to hmm_range_unregister.
> 3. Use default flags to avoid pre-fill pfn arrays.
> 4. Use new hmm_device_ helpers.
>
> v2: retry if hmm_range_fault returns -EAGAIN
>
> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
> Signed-off-by: Philip Yang 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 150 ++--
>   2 files changed, 63 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index 41ccee49a224..e0bb47ce570b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>   range->flags = hmm_range_flags;
>   range->values = hmm_range_values;
>   range->pfn_shift = PAGE_SHIFT;
> - range->pfns = NULL;
>   INIT_LIST_HEAD(>list);
>   }
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index eb4b85061c7e..f129160939bc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>   struct task_struct  *usertask;
>   uint32_tuserflags;
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
> - struct hmm_range*ranges;
> - int nr_ranges;
> + struct hmm_range*range;
>   #endif
>   };
>   
> @@ -725,57 +724,34 @@ struct amdgpu_ttm_tt {
>*/
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>   
> -/* Support Userptr pages cross max 16 vmas */
> -#define MAX_NR_VMAS  (16)
> -
>   int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>   {
>   struct amdgpu_ttm_tt *gtt = (void *)ttm;
>   struct mm_struct *mm = gtt->usertask->mm;
>   unsigned long start = gtt->userptr;
> - unsigned long end = start + ttm->num_pages * PAGE_SIZE;
> - struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
> - struct hmm_range *ranges;
> - unsigned long nr_pages, i;
> - uint64_t *pfns, f;
> + struct vm_area_struct *vma;
> + struct hmm_range *range;
> + unsigned long i;
> + uint64_t *pfns;
> + int retry = 0;
>   int r = 0;
>   
>   if (!mm) /* Happens during process shutdown */
>   return -ESRCH;
>   
> - down_read(>mmap_sem);
> -
> - /* user pages may cross multiple VMAs */
> - gtt->nr_ranges = 0;
> - do {
> - unsigned long vm_start;
> -
> - if (gtt->nr_ranges >= MAX_NR_VMAS) {
> - DRM_ERROR("Too many VMAs in userptr range\n");
> - r = -EFAULT;
> - goto out;
> - }
> -
> - vm_start = vma ? vma->vm_end : start;
> - vma = find_vma(mm, vm_start);
> - if (unlikely(!vma || vm_start < vma->vm_start)) {
> - r = -EFAULT;
> - goto out;
> - }
> - vmas[gtt->nr_ranges++] = vma;
> - } while (end > vma->vm_end);
> -
> - DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
> - start, gtt->nr_ranges, ttm->num_pages);
> -
> + vma = find_vma(mm, start);
> + if (unlikely(!vma || start < vma->vm_start)) {
> + r = -EFAULT;
> + goto out;
> + }
>   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
> - vmas[0]->vm_file)) {
> + vma->vm_file)) {
>   r = -EPERM;
>   goto out;
>   }
>   
> - ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
> - if (unlikely(!ranges)) {
> + range = kzalloc(sizeof(*range), GFP_KERNEL);
> + if (unlikely(!range)) {
>   r = -ENOMEM;
>   goto out;
>   }
> @@ -786,61 +762,61 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   goto out_free_ranges;
>   }
>   
> - for (i = 0; i < gtt->nr_ranges; i++)
> - amdgpu_hmm_init_range([i]);
> -
> - f = ranges[0].flags[HMM_PFN_VALID];
> - f |= amdgpu_ttm_tt_is_readonly(ttm) ?
> - 0 : ranges[0].flags[HMM_PFN_WRITE];
> - memset64(pfns, f, ttm->num_pages);
> + amdgpu_hmm_init_range(range);
> + range->default_flags = range->flags[HMM_PFN_VALID];
> + range->default_flags |= amdgpu_ttm_tt_is_readonly(ttm) ?
> + 0 : 

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-05-31 Thread Kuehling, Felix
On 2019-05-31 5:32 p.m., Yang, Philip wrote:
>
> On 2019-05-31 3:42 p.m., Kuehling, Felix wrote:
>> On 2019-05-31 1:28 p.m., Yang, Philip wrote:
>>> On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
>   
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
> - if (gtt->ranges &&
> - ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
> -  gtt->ranges[0].pfns[0]))
> + if (gtt->range &&
> + ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
> +   gtt->range->pfns[0]))
 I think just checking gtt->range here is enough. If gtt->range is not
 NULL here, we're leaking memory.

>>> If just checking gtt->range, there is a false warning in amdgpu_test
>>> userptr case in amdgpu_cs_list_validate path. If userptr is invalidated,
>>> then ttm->pages[0] is outdated pages, lobj->user_pages is new pages, it
>>> goes to ttm_tt_unbind first to unpin old pages (this causes false
>>> warning) then call amdgpu_ttm_tt_set_user_pages.
>> But doesn't that mean we're leaking the gtt->range somewhere?
>>
> ttm_tt_unbind is called from ttm_tt_destroy and amdgpu_cs_list_validate,
> the later one causes false warning. ttm_ttm_destory path is fine to only
> check gtt->range.
>
> Double checked, amdgpu_ttm_tt_get_user_pages and
> amdgpu_ttm_tt_get_user_pages_done always match in both paths, so no leak
> gtt->range.
>
> 1. amdgpu_gem_userptr_ioctl
> amdgpu_ttm_tt_get_user_pages
> ttm->pages for userptr pages
> amdgpu_ttm_tt_get_user_pages_done
>
> 2. amdgpu_cs_ioctl
> amdgpu_cs_parser_bos
> amdgpu_ttm_tt_get_user_pages
> if (userpage_invalidated)
> e->user_pages for new pages
> amdgpu_cs_list_validate
> if (userpage_invalidated)
>ttm_tt_unbind ttm->pages // this causes warning
>amdgpu_ttm_tt_set_user_pages(ttm->pages, e->user_pages)

Hmm, I think amdgpu_cs is doing something weird there. It does some 
double book-keeping of the user pages in the BO list and the TTM BO. We 
did something similar for KFD and simplified it when moving to HMM. It 
could probably be simplified for amdgpu_cs as well. But not in this 
patch series.

I'll review your updated change.

Thanks,
   Felix


> amdgpu_cs_submit
> amdgpu_ttm_tt_get_user_pages_done
>
>> Regards,
>>  Felix
>>
>>
>>> I will submit patch v2, to add retry if hmm_range_fault returns -EAGAIN.
>>> use kzalloc to allocate small size range.
>>>
>>> Thanks,
>>> Philip
>>>
 Regards,
    Felix


___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-05-31 Thread Yang, Philip


On 2019-05-31 3:42 p.m., Kuehling, Felix wrote:
> On 2019-05-31 1:28 p.m., Yang, Philip wrote:
>>
>> On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
  
  #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
 -  if (gtt->ranges &&
 -  ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
 -   gtt->ranges[0].pfns[0]))
 +  if (gtt->range &&
 +  ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
 +gtt->range->pfns[0]))
>>> I think just checking gtt->range here is enough. If gtt->range is not
>>> NULL here, we're leaking memory.
>>>
>> If just checking gtt->range, there is a false warning in amdgpu_test
>> userptr case in amdgpu_cs_list_validate path. If userptr is invalidated,
>> then ttm->pages[0] is outdated pages, lobj->user_pages is new pages, it
>> goes to ttm_tt_unbind first to unpin old pages (this causes false
>> warning) then call amdgpu_ttm_tt_set_user_pages.
> 
> But doesn't that mean we're leaking the gtt->range somewhere?
> 
ttm_tt_unbind is called from ttm_tt_destroy and amdgpu_cs_list_validate, 
the later one causes false warning. ttm_ttm_destory path is fine to only 
check gtt->range.

Double checked, amdgpu_ttm_tt_get_user_pages and 
amdgpu_ttm_tt_get_user_pages_done always match in both paths, so no leak 
gtt->range.

1. amdgpu_gem_userptr_ioctl
   amdgpu_ttm_tt_get_user_pages
   ttm->pages for userptr pages
   amdgpu_ttm_tt_get_user_pages_done

2. amdgpu_cs_ioctl
   amdgpu_cs_parser_bos
   amdgpu_ttm_tt_get_user_pages
   if (userpage_invalidated)
   e->user_pages for new pages
   amdgpu_cs_list_validate
   if (userpage_invalidated)
  ttm_tt_unbind ttm->pages // this causes warning
  amdgpu_ttm_tt_set_user_pages(ttm->pages, e->user_pages)
   amdgpu_cs_submit
   amdgpu_ttm_tt_get_user_pages_done

> Regards,
>     Felix
> 
> 
>>

>> I will submit patch v2, to add retry if hmm_range_fault returns -EAGAIN.
>> use kzalloc to allocate small size range.
>>
>> Thanks,
>> Philip
>>
>>> Regards,
>>>   Felix
>>>
>>>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-05-31 Thread Kuehling, Felix
On 2019-05-31 1:28 p.m., Yang, Philip wrote:
>
> On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
>>> 
>>> #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>> -   if (gtt->ranges &&
>>> -   ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
>>> -gtt->ranges[0].pfns[0]))
>>> +   if (gtt->range &&
>>> +   ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
>>> + gtt->range->pfns[0]))
>> I think just checking gtt->range here is enough. If gtt->range is not
>> NULL here, we're leaking memory.
>>
> If just checking gtt->range, there is a false warning in amdgpu_test
> userptr case in amdgpu_cs_list_validate path. If userptr is invalidated,
> then ttm->pages[0] is outdated pages, lobj->user_pages is new pages, it
> goes to ttm_tt_unbind first to unpin old pages (this causes false
> warning) then call amdgpu_ttm_tt_set_user_pages.

But doesn't that mean we're leaking the gtt->range somewhere?

Regards,
   Felix


>
> I will submit patch v2, to add retry if hmm_range_fault returns -EAGAIN.
> use kzalloc to allocate small size range.
>
> Thanks,
> Philip
>
>> Regards,
>>  Felix
>>
>>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-05-31 Thread Yang, Philip


On 2019-05-30 6:36 p.m., Kuehling, Felix wrote:
>>
>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>> -if (gtt->ranges &&
>> -ttm->pages[0] == hmm_pfn_to_page(>ranges[0],
>> - gtt->ranges[0].pfns[0]))
>> +if (gtt->range &&
>> +ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
>> +  gtt->range->pfns[0]))
> I think just checking gtt->range here is enough. If gtt->range is not
> NULL here, we're leaking memory.
> 
If just checking gtt->range, there is a false warning in amdgpu_test 
userptr case in amdgpu_cs_list_validate path. If userptr is invalidated, 
then ttm->pages[0] is outdated pages, lobj->user_pages is new pages, it 
goes to ttm_tt_unbind first to unpin old pages (this causes false 
warning) then call amdgpu_ttm_tt_set_user_pages.

I will submit patch v2, to add retry if hmm_range_fault returns -EAGAIN. 
use kzalloc to allocate small size range.

Thanks,
Philip

> Regards,
>     Felix
> 
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: use new HMM APIs and helpers

2019-05-30 Thread Kuehling, Felix
This is a nice simplification. See a few comments inline.

On 2019-05-30 10:41 a.m., Yang, Philip wrote:
> HMM provides new APIs and helps in kernel 5.2-rc1 to simplify driver
> path. The old hmm APIs are deprecated and will be removed in future.
>
> Below are changes in driver:
>
> 1. Change hmm_vma_fault to hmm_range_register and hmm_range_fault which
> supports range with multiple vmas, remove the multiple vmas handle path
> and data structure.
> 2. Change hmm_vma_range_done to hmm_range_unregister.
> 3. Use default flags to avoid pre-fill pfn arrays.
> 4. Use new hmm_device_ helpers.
>
> Change-Id: I1a00f88459f3b96c9536933e9a17eb1ebaa78113
> Signed-off-by: Philip Yang 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  |   1 -
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 140 +---
>   2 files changed, 53 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index 41ccee49a224..e0bb47ce570b 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -519,7 +519,6 @@ void amdgpu_hmm_init_range(struct hmm_range *range)
>   range->flags = hmm_range_flags;
>   range->values = hmm_range_values;
>   range->pfn_shift = PAGE_SHIFT;
> - range->pfns = NULL;
>   INIT_LIST_HEAD(>list);
>   }
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 7138dc1dd1f4..25a9fcb409c6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -711,8 +711,7 @@ struct amdgpu_ttm_tt {
>   struct task_struct  *usertask;
>   uint32_tuserflags;
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
> - struct hmm_range*ranges;
> - int nr_ranges;
> + struct hmm_range*range;
>   #endif
>   };
>   
> @@ -725,57 +724,33 @@ struct amdgpu_ttm_tt {
>*/
>   #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>   
> -/* Support Userptr pages cross max 16 vmas */
> -#define MAX_NR_VMAS  (16)
> -
>   int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
>   {
>   struct amdgpu_ttm_tt *gtt = (void *)ttm;
>   struct mm_struct *mm = gtt->usertask->mm;
>   unsigned long start = gtt->userptr;
> - unsigned long end = start + ttm->num_pages * PAGE_SIZE;
> - struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
> - struct hmm_range *ranges;
> - unsigned long nr_pages, i;
> - uint64_t *pfns, f;
> + struct vm_area_struct *vma;
> + struct hmm_range *range;
> + unsigned long i;
> + uint64_t *pfns;
>   int r = 0;
>   
>   if (!mm) /* Happens during process shutdown */
>   return -ESRCH;
>   
> - down_read(>mmap_sem);
> -
> - /* user pages may cross multiple VMAs */
> - gtt->nr_ranges = 0;
> - do {
> - unsigned long vm_start;
> -
> - if (gtt->nr_ranges >= MAX_NR_VMAS) {
> - DRM_ERROR("Too many VMAs in userptr range\n");
> - r = -EFAULT;
> - goto out;
> - }
> -
> - vm_start = vma ? vma->vm_end : start;
> - vma = find_vma(mm, vm_start);
> - if (unlikely(!vma || vm_start < vma->vm_start)) {
> - r = -EFAULT;
> - goto out;
> - }
> - vmas[gtt->nr_ranges++] = vma;
> - } while (end > vma->vm_end);
> -
> - DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
> - start, gtt->nr_ranges, ttm->num_pages);
> -
> + vma = find_vma(mm, start);
> + if (unlikely(!vma || start < vma->vm_start)) {
> + r = -EFAULT;
> + goto out;
> + }
>   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
> - vmas[0]->vm_file)) {
> + vma->vm_file)) {
>   r = -EPERM;
>   goto out;
>   }
>   
> - ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
> - if (unlikely(!ranges)) {
> + range = kvmalloc(sizeof(*range), GFP_KERNEL | __GFP_ZERO);

A single range is pretty small. You can probably allocate that with 
kmalloc now (or kcalloc/kzalloc since you specified GFP_ZERO).


> + if (unlikely(!range)) {
>   r = -ENOMEM;
>   goto out;
>   }
> @@ -786,61 +761,52 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   goto out_free_ranges;
>   }
>   
> - for (i = 0; i < gtt->nr_ranges; i++)
> - amdgpu_hmm_init_range([i]);
> + amdgpu_hmm_init_range(range);
> + range->default_flags = range->flags[HMM_PFN_VALID];
> + range->default_flags |= amdgpu_ttm_tt_is_readonly(ttm) ?
> + 0 : range->flags[HMM_PFN_WRITE];
> + range->pfn_flags_mask = 0;
> + range->pfns