Re: [PATCH v2 14/15] drm/amdgpu: Use mmu_range_notifier instead of hmm_mirror

2019-11-01 Thread Yang, Philip
Sorry, resend patch, the one in previous email missed couple of lines 
duo to copy/paste.

On 2019-11-01 3:45 p.m., Yang, Philip wrote:
> 
> 
> On 2019-11-01 1:42 p.m., Jason Gunthorpe wrote:
>> On Fri, Nov 01, 2019 at 03:59:26PM +0000, Yang, Philip wrote:
>>>> This test for range_blockable should be before mutex_lock, I can move
>>>> it up
>>>>
>>> yes, thanks.
>>
>> Okay, I wrote it like this:
>>
>>  if (mmu_notifier_range_blockable(range))
>>  mutex_lock(>notifier_lock);
>>  else if (!mutex_trylock(>notifier_lock))
>>  return false;
>>
>>>> Also, do you know if notifier_lock is held while calling
>>>> amdgpu_ttm_tt_get_user_pages_done()? Can we add a 'lock assert held'
>>>> to amdgpu_ttm_tt_get_user_pages_done()?
>>>
>>> gpu side hold notifier_lock but kfd side doesn't. kfd side doesn't check
>>> amdgpu_ttm_tt_get_user_pages_done/mmu_range_read_retry return value but
>>> check mem->invalid flag which is updated from invalidate callback. It
>>> takes more time to change, I will come to another patch to fix it later.
>>
>> Ah.. confusing, OK, I'll let you sort that
>>
>>>> However, this is all pre-existing bugs, so I'm OK go ahead with this
>>>> patch as modified. I advise AMD to make a followup patch ..
>>>>
>>> yes, I will.
>>
>> While you are here, this is also wrong:
>>
>> int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
>> {
>>  down_read(>mmap_sem);
>>  r = hmm_range_fault(range, 0);
>>  up_read(>mmap_sem);
>>  if (unlikely(r <= 0)) {
>>  if ((r == 0 || r == -EBUSY) && !time_after(jiffies, timeout))
>>  goto retry;
>>  goto out_free_pfns;
>>  }
>>
>>  for (i = 0; i < ttm->num_pages; i++) {
>>  pages[i] = hmm_device_entry_to_page(range, range->pfns[i]);
>>
>> It is not allowed to read the results of hmm_range_fault() outside
>> locking, and in particular, we can't convert to a struct page.
>>
>> This must be done inside the notifier_lock, after checking
>> mmu_range_read_retry(), all handling of the struct page must be
>> structured like that.
>>
> Below change will fix this, then driver will call mmu_range_read_retry
> second time using same range->notifier_seq to check if range is
> invalidated inside amdgpu_cs_submit, this looks ok for me.
> 
@@ -797,6 +797,7 @@ static const uint64_t 
hmm_range_values[HMM_PFN_VALUE_MAX] = {
   */
  int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page 
**pages)
  {
+   struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 struct ttm_tt *ttm = bo->tbo.ttm;
 struct amdgpu_ttm_tt *gtt = (void *)ttm;
 unsigned long start = gtt->userptr;
@@ -868,6 +869,13 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo 
*bo, struct page **pages)
 goto out_free_pfns;
 }

+   mutex_lock(>notifier_lock);
+
+   if (mmu_range_read_retry(>notifier, range->notifier_seq)) {
+   mutex_unlock(>notifier_lock);
+   goto retry;
+   }
+
 for (i = 0; i < ttm->num_pages; i++) {
 pages[i] = hmm_device_entry_to_page(range, range->pfns[i]);
 if (unlikely(!pages[i])) {
@@ -875,10 +883,12 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo 
*bo, struct page **pages)
i, range->pfns[i]);
 r = -ENOMEM;

+   mutex_unlock(>notifier_lock);
 goto out_free_pfns;
 }
 }

+   mutex_unlock(>notifier_lock);
 gtt->range = range;
 mmput(mm);

> 
> Philip
> 
>>>>> @@ -997,10 +1004,18 @@ static void amdgpu_ttm_tt_unpin_userptr(struct 
>>>>> ttm_tt *ttm)
>>>>>   sg_free_table(ttm->sg);
>>>>> 
>>>>> #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>>>> - if (gtt->range &&
>>>>> - ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
>>>>> -   gtt->range->pfns[0]))
>>>>> - WARN_ONCE(1, "Missing get_user_page_done\n");
>>>>> + if (gtt->range) {
>>>>> + unsigned long i;
>>>>> +
>>>>> + for (i = 0; i < ttm->num_pages; i++) {
>>>>> + if (ttm->pages[i] !=

Re: [PATCH v2 14/15] drm/amdgpu: Use mmu_range_notifier instead of hmm_mirror

2019-11-01 Thread Yang, Philip


On 2019-11-01 1:42 p.m., Jason Gunthorpe wrote:
> On Fri, Nov 01, 2019 at 03:59:26PM +0000, Yang, Philip wrote:
>>> This test for range_blockable should be before mutex_lock, I can move
>>> it up
>>>
>> yes, thanks.
> 
> Okay, I wrote it like this:
> 
>   if (mmu_notifier_range_blockable(range))
>   mutex_lock(>notifier_lock);
>   else if (!mutex_trylock(>notifier_lock))
>   return false;
> 
>>> Also, do you know if notifier_lock is held while calling
>>> amdgpu_ttm_tt_get_user_pages_done()? Can we add a 'lock assert held'
>>> to amdgpu_ttm_tt_get_user_pages_done()?
>>
>> gpu side hold notifier_lock but kfd side doesn't. kfd side doesn't check
>> amdgpu_ttm_tt_get_user_pages_done/mmu_range_read_retry return value but
>> check mem->invalid flag which is updated from invalidate callback. It
>> takes more time to change, I will come to another patch to fix it later.
> 
> Ah.. confusing, OK, I'll let you sort that
> 
>>> However, this is all pre-existing bugs, so I'm OK go ahead with this
>>> patch as modified. I advise AMD to make a followup patch ..
>>>
>> yes, I will.
> 
> While you are here, this is also wrong:
> 
> int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
> {
>   down_read(>mmap_sem);
>   r = hmm_range_fault(range, 0);
>   up_read(>mmap_sem);
>   if (unlikely(r <= 0)) {
>   if ((r == 0 || r == -EBUSY) && !time_after(jiffies, timeout))
>   goto retry;
>   goto out_free_pfns;
>   }
> 
>   for (i = 0; i < ttm->num_pages; i++) {
>   pages[i] = hmm_device_entry_to_page(range, range->pfns[i]);
> 
> It is not allowed to read the results of hmm_range_fault() outside
> locking, and in particular, we can't convert to a struct page.
> 
> This must be done inside the notifier_lock, after checking
> mmu_range_read_retry(), all handling of the struct page must be
> structured like that.
> 
Below change will fix this, then driver will call mmu_range_read_retry 
second time using same range->notifier_seq to check if range is 
invalidated inside amdgpu_cs_submit, this looks ok for me.

@@ -868,6 +869,13 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo 
*bo, struct page **pages)
 goto out_free_pfns;
 }

+   mutex_lock(>notifier_lock);
+
+   if (mmu_range_read_retry(>notifier, range->notifier_seq)) {
+   mutex_unlock(>notifier_lock);
+   goto retry;
+   }
+
 for (i = 0; i < ttm->num_pages; i++) {
 pages[i] = hmm_device_entry_to_page(range, range->pfns[i]);
 if (unlikely(!pages[i])) {
@@ -875,10 +883,12 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo 
*bo, struct page **pages)
i, range->pfns[i]);
 r = -ENOMEM;

+   mutex_unlock(>notifier_lock);
 goto out_free_pfns;
 }
 }

+   mutex_unlock(>notifier_lock);
 gtt->range = range;
 mmput(mm);

Philip

>>>> @@ -997,10 +1004,18 @@ static void amdgpu_ttm_tt_unpin_userptr(struct 
>>>> ttm_tt *ttm)
>>>>sg_free_table(ttm->sg);
>>>>
>>>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>>>> -  if (gtt->range &&
>>>> -  ttm->pages[0] == hmm_device_entry_to_page(gtt->range,
>>>> -gtt->range->pfns[0]))
>>>> -  WARN_ONCE(1, "Missing get_user_page_done\n");
>>>> +  if (gtt->range) {
>>>> +  unsigned long i;
>>>> +
>>>> +  for (i = 0; i < ttm->num_pages; i++) {
>>>> +  if (ttm->pages[i] !=
>>>> +  hmm_device_entry_to_page(gtt->range,
>>>> +gtt->range->pfns[i]))
>>>> +  break;
>>>> +  }
>>>> +
>>>> +  WARN((i == ttm->num_pages), "Missing get_user_page_done\n");
>>>> +  }
>>>
>>> Is this related/necessary? I can put it in another patch if it is just
>>> debugging improvement? Please advise
>>>
>> I see this WARN backtrace now, but I didn't see it before. This is
>> somehow related.
> 
> Hm, might be instructive to learn what is going on..
> 
> Thanks,
> Jason
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH v2 14/15] drm/amdgpu: Use mmu_range_notifier instead of hmm_mirror

2019-11-01 Thread Yang, Philip


On 2019-11-01 11:12 a.m., Jason Gunthorpe wrote:
> On Fri, Nov 01, 2019 at 02:44:51PM +0000, Yang, Philip wrote:
>>
>>
>> On 2019-10-29 3:25 p.m., Jason Gunthorpe wrote:
>>> On Tue, Oct 29, 2019 at 07:22:37PM +, Yang, Philip wrote:
>>>> Hi Jason,
>>>>
>>>> I did quick test after merging amd-staging-drm-next with the
>>>> mmu_notifier branch, which includes this set changes. The test result
>>>> has different failures, app stuck intermittently, GUI no display etc. I
>>>> am understanding the changes and will try to figure out the cause.
>>>
>>> Thanks! I'm not surprised by this given how difficult this patch was
>>> to make. Let me know if I can assist in any way
>>>
>>> Please ensure to run with lockdep enabled.. Your symptops sounds sort
>>> of like deadlocking?
>>>
>> Hi Jason,
>>
>> Attached patch fix several issues in amdgpu driver, maybe you can squash
>> this into patch 14. With this is done, patch 12, 13, 14 is Reviewed-by
>> and Tested-by Philip Yang 
> 
> Wow, this is great thanks! Can you clarify what the problems you found
> were? Was the bug the 'return !r' below?
> 
Yes. return !r is critical one, and retry if hmm_range_fault return 
-EBUSY is needed too.

> I'll also add your signed off by
> 
> Here are some remarks:
> 
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> index cb718a064eb4..c8bbd06f1009 100644
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> @@ -67,21 +67,15 @@ static bool amdgpu_mn_invalidate_gfx(struct 
>> mmu_range_notifier *mrn,
>>  struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>>  long r;
>>   
>> -/*
>> - * FIXME: Must hold some lock shared with
>> - * amdgpu_ttm_tt_get_user_pages_done()
>> - */
>> -mmu_range_set_seq(mrn, cur_seq);
>> +mutex_lock(>notifier_lock);
>>   
>> -/* FIXME: Is this necessary? */
>> -if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, range->start,
>> -  range->end))
>> -return true;
>> +mmu_range_set_seq(mrn, cur_seq);
>>   
>> -if (!mmu_notifier_range_blockable(range))
>> +if (!mmu_notifier_range_blockable(range)) {
>> +mutex_unlock(>notifier_lock);
>>  return false;
> 
> This test for range_blockable should be before mutex_lock, I can move
> it up
> 
yes, thanks.
> Also, do you know if notifier_lock is held while calling
> amdgpu_ttm_tt_get_user_pages_done()? Can we add a 'lock assert held'
> to amdgpu_ttm_tt_get_user_pages_done()?
> 
gpu side hold notifier_lock but kfd side doesn't. kfd side doesn't check 
amdgpu_ttm_tt_get_user_pages_done/mmu_range_read_retry return value but 
check mem->invalid flag which is updated from invalidate callback. It 
takes more time to change, I will come to another patch to fix it later.

>> @@ -854,12 +853,20 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, 
>> struct page **pages)
>>  r = -EPERM;
>>  goto out_unlock;
>>  }
>> +up_read(>mmap_sem);
>> +timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
>> +
>> +retry:
>> +range->notifier_seq = mmu_range_read_begin(>notifier);
>>   
>> +down_read(>mmap_sem);
>>  r = hmm_range_fault(range, 0);
>>  up_read(>mmap_sem);
>> -
>> -if (unlikely(r < 0))
>> +if (unlikely(r <= 0)) {
>> +if ((r == 0 || r == -EBUSY) && !time_after(jiffies, timeout))
>> +goto retry;
>>  goto out_free_pfns;
>> +}
> 
> This isn't really right, a retry loop like this needs to go all the
> way to mmu_range_read_retry() and done under the notifier_lock. ie
> mmu_range_read_retry() can fail just as likely as hmm_range_fault()
> can, and drivers are supposed to retry in both cases, with a single
> timeout.
> 
For gpu, check mmu_range_read_retry return value under the notifier_lock 
to do retry is in seperate location, not in same retry loop.

> AFAICT it is a major bug that many places ignore the return code of
> amdgpu_ttm_tt_get_user_pages_done() ???
>
For kfd, explained above.

> However, this is all pre-existing bugs, so I'm OK go ahead with this
> patch as modified. I advise AMD to make a followup patch ..
> 
yes, I will.
> I'll add a FIXME note to this effect.
> 
>>  for (i = 0; i < ttm->num_pages; i++) {
>>

Re: [PATCH v2 14/15] drm/amdgpu: Use mmu_range_notifier instead of hmm_mirror

2019-11-01 Thread Yang, Philip


On 2019-10-29 3:25 p.m., Jason Gunthorpe wrote:
> On Tue, Oct 29, 2019 at 07:22:37PM +0000, Yang, Philip wrote:
>> Hi Jason,
>>
>> I did quick test after merging amd-staging-drm-next with the
>> mmu_notifier branch, which includes this set changes. The test result
>> has different failures, app stuck intermittently, GUI no display etc. I
>> am understanding the changes and will try to figure out the cause.
> 
> Thanks! I'm not surprised by this given how difficult this patch was
> to make. Let me know if I can assist in any way
> 
> Please ensure to run with lockdep enabled.. Your symptops sounds sort
> of like deadlocking?
> 
Hi Jason,

Attached patch fix several issues in amdgpu driver, maybe you can squash 
this into patch 14. With this is done, patch 12, 13, 14 is Reviewed-by 
and Tested-by Philip Yang 

Regards,
Philip

> Regards,
> Jason
> 
From 5a0bd4d8cef8472fe2904550142d288feed8cd81 Mon Sep 17 00:00:00 2001
From: Philip Yang 
Date: Thu, 31 Oct 2019 09:10:30 -0400
Subject: [PATCH] drm/amdgpu: issues with new mmu_range_notifier api

put mmu_range_set_seq under the same lock which is used to call
mmu_range_read_retry.

fix amdgpu_ttm_tt_get_user_pages_done return value, because
mmu_range_read_retry means !hmm_range_valid

retry if hmm_range_fault return -EBUSY

fix false WARN for missing get_user_page_done, we should check all
pages not just the first page, don't understand why this issue is
triggered by this change.

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c  | 32 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 37 +
 2 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index cb718a064eb4..c8bbd06f1009 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -67,21 +67,15 @@ static bool amdgpu_mn_invalidate_gfx(struct mmu_range_notifier *mrn,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	long r;
 
-	/*
-	 * FIXME: Must hold some lock shared with
-	 * amdgpu_ttm_tt_get_user_pages_done()
-	 */
-	mmu_range_set_seq(mrn, cur_seq);
+	mutex_lock(>notifier_lock);
 
-	/* FIXME: Is this necessary? */
-	if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, range->start,
-	  range->end))
-		return true;
+	mmu_range_set_seq(mrn, cur_seq);
 
-	if (!mmu_notifier_range_blockable(range))
+	if (!mmu_notifier_range_blockable(range)) {
+		mutex_unlock(>notifier_lock);
 		return false;
+	}
 
-	mutex_lock(>notifier_lock);
 	r = dma_resv_wait_timeout_rcu(bo->tbo.base.resv, true, false,
   MAX_SCHEDULE_TIMEOUT);
 	mutex_unlock(>notifier_lock);
@@ -110,21 +104,15 @@ static bool amdgpu_mn_invalidate_hsa(struct mmu_range_notifier *mrn,
 	struct amdgpu_bo *bo = container_of(mrn, struct amdgpu_bo, notifier);
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
-	/*
-	 * FIXME: Must hold some lock shared with
-	 * amdgpu_ttm_tt_get_user_pages_done()
-	 */
-	mmu_range_set_seq(mrn, cur_seq);
+	mutex_lock(>notifier_lock);
 
-	/* FIXME: Is this necessary? */
-	if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, range->start,
-	  range->end))
-		return true;
+	mmu_range_set_seq(mrn, cur_seq);
 
-	if (!mmu_notifier_range_blockable(range))
+	if (!mmu_notifier_range_blockable(range)) {
+		mutex_unlock(>notifier_lock);
 		return false;
+	}
 
-	mutex_lock(>notifier_lock);
 	amdgpu_amdkfd_evict_userptr(bo->kfd_bo, bo->notifier.mm);
 	mutex_unlock(>notifier_lock);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index a38437fd290a..56fde43d5efa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -799,10 +799,11 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
 {
 	struct ttm_tt *ttm = bo->tbo.ttm;
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	struct mm_struct *mm;
-	struct hmm_range *range;
 	unsigned long start = gtt->userptr;
 	struct vm_area_struct *vma;
+	struct hmm_range *range;
+	unsigned long timeout;
+	struct mm_struct *mm;
 	unsigned long i;
 	int r = 0;
 
@@ -841,8 +842,6 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
 		goto out_free_ranges;
 	}
 
-	range->notifier_seq = mmu_range_read_begin(>notifier);
-
 	down_read(>mmap_sem);
 	vma = find_vma(mm, start);
 	if (unlikely(!vma || start < vma->vm_start)) {
@@ -854,12 +853,20 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages)
 		r = -EPERM;
 		goto out_unlock;
 	}
+	up_read(>mmap_sem);
+	timeout = jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
+
+retry:
+	range->notifier_seq = mmu_range_read_begin(>notifier);
 
+	down_read(>mmap_sem);
 	r = hmm_range_fault(range, 0);
 	up_read(>mm

Re: [PATCH v2 14/15] drm/amdgpu: Use mmu_range_notifier instead of hmm_mirror

2019-10-29 Thread Yang, Philip
Hi Jason,

I did quick test after merging amd-staging-drm-next with the 
mmu_notifier branch, which includes this set changes. The test result 
has different failures, app stuck intermittently, GUI no display etc. I 
am understanding the changes and will try to figure out the cause.

Regards,
Philip

On 2019-10-28 4:10 p.m., Jason Gunthorpe wrote:
> From: Jason Gunthorpe 
> 
> Convert the collision-retry lock around hmm_range_fault to use the one now
> provided by the mmu_range notifier.
> 
> Although this driver does not seem to use the collision retry lock that
> hmm provides correctly, it can still be converted over to use the
> mmu_range_notifier api instead of hmm_mirror without too much trouble.
> 
> This also deletes another place where a driver is associating additional
> data (struct amdgpu_mn) with a mmu_struct.
> 
> Cc: Alex Deucher 
> Cc: Christian König 
> Cc: David (ChunMing) Zhou 
> Cc: amd-gfx@lists.freedesktop.org
> Signed-off-by: Jason Gunthorpe 
> ---
>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |   4 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c|  14 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c| 148 ++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|  49 --
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   |  76 -
>   5 files changed, 66 insertions(+), 225 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index 47700302a08b7f..1bcedb9b477dce 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -1738,6 +1738,10 @@ static int update_invalid_user_pages(struct 
> amdkfd_process_info *process_info,
>   return ret;
>   }
>   
> + /*
> +  * FIXME: Cannot ignore the return code, must hold
> +  * notifier_lock
> +  */
>   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>   
>   /* Mark the BO as valid unless it was invalidated
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index 2e53feed40e230..76771f5f0b60ab 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -607,8 +607,6 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser 
> *p,
>   e->tv.num_shared = 2;
>   
>   amdgpu_bo_list_get_list(p->bo_list, >validated);
> - if (p->bo_list->first_userptr != p->bo_list->num_entries)
> - p->mn = amdgpu_mn_get(p->adev, AMDGPU_MN_TYPE_GFX);
>   
>   INIT_LIST_HEAD();
>   amdgpu_vm_get_pd_bo(>vm, >validated, >vm_pd);
> @@ -1291,11 +1289,11 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser 
> *p,
>   if (r)
>   goto error_unlock;
>   
> - /* No memory allocation is allowed while holding the mn lock.
> -  * p->mn is hold until amdgpu_cs_submit is finished and fence is added
> -  * to BOs.
> + /* No memory allocation is allowed while holding the notifier lock.
> +  * The lock is held until amdgpu_cs_submit is finished and fence is
> +  * added to BOs.
>*/
> - amdgpu_mn_lock(p->mn);
> + mutex_lock(>adev->notifier_lock);
>   
>   /* If userptr are invalidated after amdgpu_cs_parser_bos(), return
>* -EAGAIN, drmIoctl in libdrm will restart the amdgpu_cs_ioctl.
> @@ -1338,13 +1336,13 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser 
> *p,
>   amdgpu_vm_move_to_lru_tail(p->adev, >vm);
>   
>   ttm_eu_fence_buffer_objects(>ticket, >validated, p->fence);
> - amdgpu_mn_unlock(p->mn);
> + mutex_unlock(>adev->notifier_lock);
>   
>   return 0;
>   
>   error_abort:
>   drm_sched_job_cleanup(>base);
> - amdgpu_mn_unlock(p->mn);
> + mutex_unlock(>adev->notifier_lock);
>   
>   error_unlock:
>   amdgpu_job_free(job);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> index 4ffd7b90f4d907..cb718a064eb491 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
> @@ -50,28 +50,6 @@
>   #include "amdgpu.h"
>   #include "amdgpu_amdkfd.h"
>   
> -/**
> - * amdgpu_mn_lock - take the write side lock for this notifier
> - *
> - * @mn: our notifier
> - */
> -void amdgpu_mn_lock(struct amdgpu_mn *mn)
> -{
> - if (mn)
> - down_write(>lock);
> -}
> -
> -/**
> - * amdgpu_mn_unlock - drop the write side lock for this notifier
> - *
> - * @mn: our notifier
> - */
> -void amdgpu_mn_unlock(struct amdgpu_mn *mn)
> -{
> - if (mn)
> - up_write(>lock);
> -}
> -
>   /**
>* amdgpu_mn_invalidate_gfx - callback to notify about mm change
>*
> @@ -82,12 +60,19 @@ void amdgpu_mn_unlock(struct amdgpu_mn *mn)
>* potentially dirty.
>*/
>   static bool amdgpu_mn_invalidate_gfx(struct mmu_range_notifier *mrn,
> -

Re: [PATCH v2] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-22 Thread Yang, Philip


On 2019-10-22 3:36 p.m., Grodzovsky, Andrey wrote:
> 
> On 10/22/19 3:19 PM, Yang, Philip wrote:
>>
>> On 2019-10-22 2:40 p.m., Grodzovsky, Andrey wrote:
>>> On 10/22/19 2:38 PM, Grodzovsky, Andrey wrote:
>>>> On 10/22/19 2:28 PM, Yang, Philip wrote:
>>>>> If device reset/suspend/resume failed for some reason, dqm lock is
>>>>> hold forever and this causes deadlock. Below is a kernel backtrace when
>>>>> application open kfd after suspend/resume failed.
>>>>>
>>>>> Instead of holding dqm lock in pre_reset and releasing dqm lock in
>>>>> post_reset, add dqm->device_stopped flag which is modified in
>>>>> dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
>>>>> because write/read are all inside dqm lock.
>>>>>
>>>>> For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
>>>>> device_stopped flag before sending the updated runlist.
>>>> Is there a chance of race condition here where dqm->device_stopped
>>>> returns true for some operation (e.g.map_queues_cpsch) but just as it
>>>> proceeds GPU reset starts  ?
>>>>
>>>> Andrey
>>>
>>> Correction -
>>>
>>> dqm->device_stopped returns FALSE
>>>
>> No race condition here, dqm->device_stopped is set to FALSE in
>> kgd2kfd_post_reset -> dqm->ops.start(), which the last step of
>> amdgpu_device_gpu_recover, so it's safe to do map_queue_cpsch.
>>
>> Regards,
>> Philip
> 
> Sorry - i was confused by the commit description vs. body - in the
> description it's called device_stopped flag while in the body it's
> sched_running - probably the description needs to be fixed.
> 
Thanks, commit description is updated.

> So i mean the switch true->false when GPU reset just begins - you get an
> IOCTL to map a queue (if i understood KFD code correctly), check
> dqm->sched_running == true and continue, what if right then GPU reset
> started due to some issue like job timeout or user triggered reset -
> dqm->sched_running becomes false but you already past that checkpoint in
> the IOCTL, no ?
>
map a queue is done under dqm lock, to send the updated runlist to HWS, 
then relase dqm lock. GPU reset start pre_reset will unmap all queues 
first under dqm lock, then set dqm->sched_running to false, release dqm 
lock, and then continue to reset HW. dqm lock guarantee the two 
operations are serialized.

Philip

> Andrey
> 
>>
>>> Andrey
>>>
>>>>
>>>>> v2: For no-HWS case, when device is stopped, don't call
>>>>> load/destroy_mqd for eviction, restore and create queue, and avoid
>>>>> debugfs dump hdqs.
>>>>>
>>>>> Backtrace of dqm lock deadlock:
>>>>>
>>>>> [Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
>>>>> than 120 seconds.
>>>>> [Thu Oct 17 16:43:37 2019]   Not tainted
>>>>> 5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
>>>>> [Thu Oct 17 16:43:37 2019] "echo 0 >
>>>>> /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>>>>> [Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
>>>>> 0x8000
>>>>> [Thu Oct 17 16:43:37 2019] Call Trace:
>>>>> [Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
>>>>> [Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
>>>>> [Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
>>>>> [Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
>>>>> [Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
>>>>> [Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
>>>>> [amdgpu]
>>>>> [Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
>>>>> [amdgpu]
>>>>> [Thu Oct 17 16:43:37 2019]
>>>>> kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
>>>>> [Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
>>>>> [amdgpu]
>>>>> [Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
>>>>> [Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
>>>>> [Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
>>>>> [Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
>>>>> [Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
>>>>> [Thu Oct 17 16:43:37 2019]  do_exit+0

Re: [PATCH v2] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-22 Thread Yang, Philip
On 2019-10-22 2:44 p.m., Kuehling, Felix wrote:
> On 2019-10-22 14:28, Yang, Philip wrote:
>> If device reset/suspend/resume failed for some reason, dqm lock is
>> hold forever and this causes deadlock. Below is a kernel backtrace when
>> application open kfd after suspend/resume failed.
>>
>> Instead of holding dqm lock in pre_reset and releasing dqm lock in
>> post_reset, add dqm->device_stopped flag which is modified in
>> dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
>> because write/read are all inside dqm lock.
>>
>> For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
>> device_stopped flag before sending the updated runlist.
>>
>> v2: For no-HWS case, when device is stopped, don't call
>> load/destroy_mqd for eviction, restore and create queue, and avoid
>> debugfs dump hdqs.
>>
>> Backtrace of dqm lock deadlock:
>>
>> [Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
>> than 120 seconds.
>> [Thu Oct 17 16:43:37 2019]   Not tainted
>> 5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
>> [Thu Oct 17 16:43:37 2019] "echo 0 >
>> /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
>> 0x8000
>> [Thu Oct 17 16:43:37 2019] Call Trace:
>> [Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
>> [Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
>> [Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
>> [Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
>> [Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
>> [Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]
>> kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
>> [Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
>> [Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
>> [Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
>> [Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
>> [Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
>> [Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
>> [Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
>> [Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
>> [Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
>> [Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>
>> Suggested-by: Felix Kuehling 
>> Signed-off-by: Philip Yang 
> 
> Three more comments inline. With those comments addressed, this patch is
> 
> Reviewed-by: Felix Kuehling 
> 
> 
>> ---
>>drivers/gpu/drm/amd/amdkfd/kfd_chardev.c  |  6 +--
>>drivers/gpu/drm/amd/amdkfd/kfd_device.c   |  5 --
>>.../drm/amd/amdkfd/kfd_device_queue_manager.c | 47 +--
>>.../drm/amd/amdkfd/kfd_device_queue_manager.h |  1 +
>>4 files changed, 46 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
>> b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> index d9e36dbf13d5..40d75c39f08e 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> @@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
>> *filep)
>>  return -EPERM;
>>  }
>>
>> +if (kfd_is_locked())
>> +return -EAGAIN;
>> +
>>  process = kfd_create_process(filep);
>>  if (IS_ERR(process))
>>  return PTR_ERR(process);
>>
>> -if (kfd_is_locked())
>> -return -EAGAIN;
>> -
> 
> Is this part of the change still needed? I remember that this sequence
> was a bit tricky with some potential race condition when Shaoyun was
> working on it. This may have unintended side effects.
> 
> 
Revert this change to be safe, it is not needed and not clear if there 
are side effects.

>>  dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
>>  process->pasid, process->is_32bit_user_mode);
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
>> b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
>> index 8f4b24e84964..4fa8834ce7cb 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
>> +++ b/drivers/gpu/drm/amd/amdk

Re: [PATCH v2] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-22 Thread Yang, Philip


On 2019-10-22 2:40 p.m., Grodzovsky, Andrey wrote:
> 
> On 10/22/19 2:38 PM, Grodzovsky, Andrey wrote:
>> On 10/22/19 2:28 PM, Yang, Philip wrote:
>>> If device reset/suspend/resume failed for some reason, dqm lock is
>>> hold forever and this causes deadlock. Below is a kernel backtrace when
>>> application open kfd after suspend/resume failed.
>>>
>>> Instead of holding dqm lock in pre_reset and releasing dqm lock in
>>> post_reset, add dqm->device_stopped flag which is modified in
>>> dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
>>> because write/read are all inside dqm lock.
>>>
>>> For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
>>> device_stopped flag before sending the updated runlist.
>>
>> Is there a chance of race condition here where dqm->device_stopped
>> returns true for some operation (e.g.map_queues_cpsch) but just as it
>> proceeds GPU reset starts  ?
>>
>> Andrey
> 
> 
> Correction -
> 
> dqm->device_stopped returns FALSE
> 
No race condition here, dqm->device_stopped is set to FALSE in 
kgd2kfd_post_reset -> dqm->ops.start(), which the last step of 
amdgpu_device_gpu_recover, so it's safe to do map_queue_cpsch.

Regards,
Philip

> Andrey
> 
>>
>>
>>> v2: For no-HWS case, when device is stopped, don't call
>>> load/destroy_mqd for eviction, restore and create queue, and avoid
>>> debugfs dump hdqs.
>>>
>>> Backtrace of dqm lock deadlock:
>>>
>>> [Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
>>> than 120 seconds.
>>> [Thu Oct 17 16:43:37 2019]   Not tainted
>>> 5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
>>> [Thu Oct 17 16:43:37 2019] "echo 0 >
>>> /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>>> [Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
>>> 0x8000
>>> [Thu Oct 17 16:43:37 2019] Call Trace:
>>> [Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
>>> [Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
>>> [Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
>>> [Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
>>> [Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
>>> [Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
>>> [amdgpu]
>>> [Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
>>> [amdgpu]
>>> [Thu Oct 17 16:43:37 2019]
>>> kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
>>> [Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
>>> [amdgpu]
>>> [Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
>>> [Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
>>> [Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
>>> [Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
>>> [Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
>>> [Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
>>> [Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
>>> [Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
>>> [Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
>>> [Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
>>> [Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>>
>>> Suggested-by: Felix Kuehling 
>>> Signed-off-by: Philip Yang 
>>> ---
>>> drivers/gpu/drm/amd/amdkfd/kfd_chardev.c  |  6 +--
>>> drivers/gpu/drm/amd/amdkfd/kfd_device.c   |  5 --
>>> .../drm/amd/amdkfd/kfd_device_queue_manager.c | 47 +--
>>> .../drm/amd/amdkfd/kfd_device_queue_manager.h |  1 +
>>> 4 files changed, 46 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
>>> b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>>> index d9e36dbf13d5..40d75c39f08e 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>>> @@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
>>> *filep)
>>> return -EPERM;
>>> }
>>> 
>>> +   if (kfd_is_locked())
>>> +   return -EAGAIN;
>>> +
>>> process = kfd_create_process(filep);
>>> if (IS_ERR(process))
>>> return PTR_ERR(process);
>>> 
>

[PATCH v2] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-22 Thread Yang, Philip
If device reset/suspend/resume failed for some reason, dqm lock is
hold forever and this causes deadlock. Below is a kernel backtrace when
application open kfd after suspend/resume failed.

Instead of holding dqm lock in pre_reset and releasing dqm lock in
post_reset, add dqm->device_stopped flag which is modified in
dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
because write/read are all inside dqm lock.

For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
device_stopped flag before sending the updated runlist.

v2: For no-HWS case, when device is stopped, don't call
load/destroy_mqd for eviction, restore and create queue, and avoid
debugfs dump hdqs.

Backtrace of dqm lock deadlock:

[Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
than 120 seconds.
[Thu Oct 17 16:43:37 2019]   Not tainted
5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
[Thu Oct 17 16:43:37 2019] "echo 0 >
/proc/sys/kernel/hung_task_timeout_secs" disables this message.
[Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
0x8000
[Thu Oct 17 16:43:37 2019] Call Trace:
[Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
[Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
[Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
[Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
[Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
[Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]
kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
[Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
[amdgpu]
[Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
[Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
[Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
[Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
[Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
[Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
[Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
[Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
[Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
[Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
[Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Suggested-by: Felix Kuehling 
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c  |  6 +--
 drivers/gpu/drm/amd/amdkfd/kfd_device.c   |  5 --
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 47 +--
 .../drm/amd/amdkfd/kfd_device_queue_manager.h |  1 +
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index d9e36dbf13d5..40d75c39f08e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
*filep)
return -EPERM;
}
 
+   if (kfd_is_locked())
+   return -EAGAIN;
+
process = kfd_create_process(filep);
if (IS_ERR(process))
return PTR_ERR(process);
 
-   if (kfd_is_locked())
-   return -EAGAIN;
-
dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
process->pasid, process->is_32bit_user_mode);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 8f4b24e84964..4fa8834ce7cb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -730,9 +730,6 @@ int kgd2kfd_pre_reset(struct kfd_dev *kfd)
return 0;
kgd2kfd_suspend(kfd);
 
-   /* hold dqm->lock to prevent further execution*/
-   dqm_lock(kfd->dqm);
-
kfd_signal_reset_event(kfd);
return 0;
 }
@@ -750,8 +747,6 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd)
if (!kfd->init_complete)
return 0;
 
-   dqm_unlock(kfd->dqm);
-
ret = kfd_resume(kfd);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 81fb545cf42c..82e1c6280d13 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -340,6 +340,10 @@ static int create_queue_nocpsch(struct 
device_queue_manager *dqm,
mqd_mgr->init_mqd(mqd_mgr, >mqd, q->mqd_mem_obj,
>gart_mqd_addr, >properties);
if (q->properties.is_active) {
+   if (!dqm->sched_running) {
+   WARN_ONCE(1, "Load non-HWS mqd while stopped\n");
+   goto add_queue_to_list;
+   }
 
if (WARN(q->process->mm != current->mm,
"should only run in user thread"))
@@ 

Re: [PATCH] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-22 Thread Yang, Philip


On 2019-10-21 9:03 p.m., Kuehling, Felix wrote:
> 
> On 2019-10-21 5:04 p.m., Yang, Philip wrote:
>> If device reset/suspend/resume failed for some reason, dqm lock is
>> hold forever and this causes deadlock. Below is a kernel backtrace when
>> application open kfd after suspend/resume failed.
>>
>> Instead of holding dqm lock in pre_reset and releasing dqm lock in
>> post_reset, add dqm->device_stopped flag which is modified in
>> dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
>> because write/read are all inside dqm lock.
>>
>> For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
>> device_stopped flag before sending the updated runlist.
> 
> What about the non-HWS case?
> 
> In theory in non-HWS case new queues should be created in evicted state
> while the device (and all processes) are suspended. So we should never
> try to map or unmap queues to HQDs during suspend. But I'd feel better
> with a WARN_ON and error return in the right places to make sure we're
> not missing anything. Basically, we can't call any of the
> load/destroy_mqd functions while suspended.
> 
v2 patch add non-HWS case.

> That reminds me, we also have to add some checks in the debugfs code to
> avoid dumping HQDs of a DQM that's stopped.
>
Thanks, done in v2 patch

> Last comment: dqm->device_stopped must be initialized as true. It will
> get set to false when the device is first started. It may be easier to
> reverse the logic, something like dqm->sched_running that gets
> implicitly initialized as false.
> 
Change to dqm->sched_running in v2 patch.

Regards,
Philip

> Regards,
>     Felix
> 
> 
>>
>> Backtrace of dqm lock deadlock:
>>
>> [Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
>> than 120 seconds.
>> [Thu Oct 17 16:43:37 2019]   Not tainted
>> 5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
>> [Thu Oct 17 16:43:37 2019] "echo 0 >
>> /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
>> 0x8000
>> [Thu Oct 17 16:43:37 2019] Call Trace:
>> [Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
>> [Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
>> [Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
>> [Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
>> [Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
>> [Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]
>> kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
>> [Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
>> [Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
>> [Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
>> [Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
>> [Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
>> [Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
>> [Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
>> [Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
>> [Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
>> [Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>
>> Suggested-by: Felix Kuehling 
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdkfd/kfd_chardev.c|  6 +++---
>>drivers/gpu/drm/amd/amdkfd/kfd_device.c |  5 -
>>.../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   | 13 ++---
>>.../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h   |  1 +
>>4 files changed, 14 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
>> b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> index d9e36dbf13d5..40d75c39f08e 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> @@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
>> *filep)
>>  return -EPERM;
>>  }
>>
>> +if (kfd_is_locked())
>> +return -EAGAIN;
>> +
>>  process = kfd_create_process(filep);
>>  if (IS_ERR(process))
>>  return PTR_ERR(process);
>>
>> -if (kfd_is_locked())
>> -return -EAGAIN;
>> -
>>

[PATCH] drm/amdkfd: don't use dqm lock during device reset/suspend/resume

2019-10-21 Thread Yang, Philip
If device reset/suspend/resume failed for some reason, dqm lock is
hold forever and this causes deadlock. Below is a kernel backtrace when
application open kfd after suspend/resume failed.

Instead of holding dqm lock in pre_reset and releasing dqm lock in
post_reset, add dqm->device_stopped flag which is modified in
dqm->ops.start and dqm->ops.stop. The flag doesn't need lock protection
because write/read are all inside dqm lock.

For HWS case, map_queues_cpsch and unmap_queues_cpsch checks
device_stopped flag before sending the updated runlist.

Backtrace of dqm lock deadlock:

[Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
than 120 seconds.
[Thu Oct 17 16:43:37 2019]   Not tainted
5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
[Thu Oct 17 16:43:37 2019] "echo 0 >
/proc/sys/kernel/hung_task_timeout_secs" disables this message.
[Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
0x8000
[Thu Oct 17 16:43:37 2019] Call Trace:
[Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
[Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
[Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
[Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
[Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
[Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]
kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
[Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
[amdgpu]
[Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
[Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
[Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
[Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
[Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
[Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
[Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
[Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
[Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
[Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
[Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Suggested-by: Felix Kuehling 
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c|  6 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_device.c |  5 -
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c   | 13 ++---
 .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.h   |  1 +
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index d9e36dbf13d5..40d75c39f08e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
*filep)
return -EPERM;
}
 
+   if (kfd_is_locked())
+   return -EAGAIN;
+
process = kfd_create_process(filep);
if (IS_ERR(process))
return PTR_ERR(process);
 
-   if (kfd_is_locked())
-   return -EAGAIN;
-
dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
process->pasid, process->is_32bit_user_mode);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
index 8f4b24e84964..4fa8834ce7cb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -730,9 +730,6 @@ int kgd2kfd_pre_reset(struct kfd_dev *kfd)
return 0;
kgd2kfd_suspend(kfd);
 
-   /* hold dqm->lock to prevent further execution*/
-   dqm_lock(kfd->dqm);
-
kfd_signal_reset_event(kfd);
return 0;
 }
@@ -750,8 +747,6 @@ int kgd2kfd_post_reset(struct kfd_dev *kfd)
if (!kfd->init_complete)
return 0;
 
-   dqm_unlock(kfd->dqm);
-
ret = kfd_resume(kfd);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 81fb545cf42c..04a40fabe9d7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -915,7 +915,8 @@ static int start_nocpsch(struct device_queue_manager *dqm)

if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
return pm_init(>packets, dqm);
-   
+   dqm->device_stopped = false;
+
return 0;
 }
 
@@ -923,7 +924,8 @@ static int stop_nocpsch(struct device_queue_manager *dqm)
 {
if (dqm->dev->device_info->asic_family == CHIP_HAWAII)
pm_uninit(>packets);
-   
+   dqm->device_stopped = true;
+
return 0;
 }
 
@@ -1074,6 +1076,7 @@ static int start_cpsch(struct device_queue_manager *dqm)
dqm_lock(dqm);
/* clear hang status when driver try to start the hw 

[PATCH v2] drm/amdkfd: kfd open return failed if device is locked

2019-10-18 Thread Yang, Philip
If device is locked for suspend and resume, kfd open should return
failed -EAGAIN without creating process, otherwise the application exit
to release the process will hang to wait for resume is done if the suspend
and resume is stuck somewhere. This is backtrace:

v2: fix processes that were created before suspend/resume got stuck

[Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
than 120 seconds.
[Thu Oct 17 16:43:37 2019]   Not tainted
5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
[Thu Oct 17 16:43:37 2019] "echo 0 >
/proc/sys/kernel/hung_task_timeout_secs" disables this message.
[Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
0x8000
[Thu Oct 17 16:43:37 2019] Call Trace:
[Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
[Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
[Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
[Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
[Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
[Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]
kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
[Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
[amdgpu]
[Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
[Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
[Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
[Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
[Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
[Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
[Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
[Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
[Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
[Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
[Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c   | 6 +++---
 drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 6 ++
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index d9e36dbf13d5..40d75c39f08e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
*filep)
return -EPERM;
}
 
+   if (kfd_is_locked())
+   return -EAGAIN;
+
process = kfd_create_process(filep);
if (IS_ERR(process))
return PTR_ERR(process);
 
-   if (kfd_is_locked())
-   return -EAGAIN;
-
dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
process->pasid, process->is_32bit_user_mode);
 
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 8509814a6ff0..3784013b92a0 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -128,6 +128,12 @@ void kfd_process_dequeue_from_all_devices(struct 
kfd_process *p)
 {
struct kfd_process_device *pdd;
 
+   /* If suspend/resume got stuck, dqm_lock is hold,
+* skip process_termination_cpsch to avoid deadlock
+*/
+   if (kfd_is_locked())
+   return;
+
list_for_each_entry(pdd, >per_device_data, per_device_list)
kfd_process_dequeue_from_device(pdd);
 }
-- 
2.17.1

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

Re: [PATCH] drm/amdkfd: kfd open return failed if device is locked

2019-10-18 Thread Yang, Philip


On 2019-10-18 11:40 a.m., Kuehling, Felix wrote:
> On 2019-10-18 10:27 a.m., Yang, Philip wrote:
>> If device is locked for suspend and resume, kfd open should return
>> failed -EAGAIN without creating process, otherwise the application exit
>> to release the process will hang to wait for resume is done if the suspend
>> and resume is stuck somewhere. This is backtrace:
> 
> This doesn't fix processes that were created before suspend/resume got
> stuck. They would still get stuck with the same backtrace. So this is
> jut a band-aid. The real underlying problem, that is not getting
> addressed, is suspend/resume getting stuck.
> 
> Am I missing something?
> 
This is to address application stuck to quit issue after suspend/resume 
got stuck. The real underlying suspend/resume issue should be addressed 
separately.

I will submit v2 patch to fix processes that were created before 
suspend/resume got stuck.

Philip

> Regards,
>     Felix
> 
> 
>>
>> [Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
>> than 120 seconds.
>> [Thu Oct 17 16:43:37 2019]   Not tainted
>> 5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
>> [Thu Oct 17 16:43:37 2019] "echo 0 >
>> /proc/sys/kernel/hung_task_timeout_secs" disables this message.
>> [Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
>> 0x8000
>> [Thu Oct 17 16:43:37 2019] Call Trace:
>> [Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
>> [Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
>> [Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
>> [Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
>> [Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
>> [Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]
>> kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
>> [amdgpu]
>> [Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
>> [Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
>> [Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
>> [Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
>> [Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
>> [Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
>> [Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
>> [Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
>> [Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
>> [Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
>> [Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 6 +++---
>>1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
>> b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> index d9e36dbf13d5..40d75c39f08e 100644
>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
>> @@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
>> *filep)
>>  return -EPERM;
>>  }
>>
>> +if (kfd_is_locked())
>> +return -EAGAIN;
>> +
>>  process = kfd_create_process(filep);
>>  if (IS_ERR(process))
>>  return PTR_ERR(process);
>>
>> -if (kfd_is_locked())
>> -return -EAGAIN;
>> -
>>  dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
>>  process->pasid, process->is_32bit_user_mode);
>>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdkfd: kfd open return failed if device is locked

2019-10-18 Thread Yang, Philip
If device is locked for suspend and resume, kfd open should return
failed -EAGAIN without creating process, otherwise the application exit
to release the process will hang to wait for resume is done if the suspend
and resume is stuck somewhere. This is backtrace:

[Thu Oct 17 16:43:37 2019] INFO: task rocminfo:3024 blocked for more
than 120 seconds.
[Thu Oct 17 16:43:37 2019]   Not tainted
5.0.0-rc1-kfd-compute-rocm-dkms-no-npi-1131 #1
[Thu Oct 17 16:43:37 2019] "echo 0 >
/proc/sys/kernel/hung_task_timeout_secs" disables this message.
[Thu Oct 17 16:43:37 2019] rocminfoD0  3024   2947
0x8000
[Thu Oct 17 16:43:37 2019] Call Trace:
[Thu Oct 17 16:43:37 2019]  ? __schedule+0x3d9/0x8a0
[Thu Oct 17 16:43:37 2019]  schedule+0x32/0x70
[Thu Oct 17 16:43:37 2019]  schedule_preempt_disabled+0xa/0x10
[Thu Oct 17 16:43:37 2019]  __mutex_lock.isra.9+0x1e3/0x4e0
[Thu Oct 17 16:43:37 2019]  ? __call_srcu+0x264/0x3b0
[Thu Oct 17 16:43:37 2019]  ? process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]  process_termination_cpsch+0x24/0x2f0
[amdgpu]
[Thu Oct 17 16:43:37 2019]
kfd_process_dequeue_from_all_devices+0x42/0x60 [amdgpu]
[Thu Oct 17 16:43:37 2019]  kfd_process_notifier_release+0x1be/0x220
[amdgpu]
[Thu Oct 17 16:43:37 2019]  __mmu_notifier_release+0x3e/0xc0
[Thu Oct 17 16:43:37 2019]  exit_mmap+0x160/0x1a0
[Thu Oct 17 16:43:37 2019]  ? __handle_mm_fault+0xba3/0x1200
[Thu Oct 17 16:43:37 2019]  ? exit_robust_list+0x5a/0x110
[Thu Oct 17 16:43:37 2019]  mmput+0x4a/0x120
[Thu Oct 17 16:43:37 2019]  do_exit+0x284/0xb20
[Thu Oct 17 16:43:37 2019]  ? handle_mm_fault+0xfa/0x200
[Thu Oct 17 16:43:37 2019]  do_group_exit+0x3a/0xa0
[Thu Oct 17 16:43:37 2019]  __x64_sys_exit_group+0x14/0x20
[Thu Oct 17 16:43:37 2019]  do_syscall_64+0x4f/0x100
[Thu Oct 17 16:43:37 2019]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index d9e36dbf13d5..40d75c39f08e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -120,13 +120,13 @@ static int kfd_open(struct inode *inode, struct file 
*filep)
return -EPERM;
}
 
+   if (kfd_is_locked())
+   return -EAGAIN;
+
process = kfd_create_process(filep);
if (IS_ERR(process))
return PTR_ERR(process);
 
-   if (kfd_is_locked())
-   return -EAGAIN;
-
dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
process->pasid, process->is_32bit_user_mode);
 
-- 
2.17.1

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

Re: [PATCH] drm/amdgpu: fix compiler warnings for df perfmons

2019-10-17 Thread Yang, Philip
Reviewed-by: Philip Yang 

On 2019-10-17 1:56 p.m., Kim, Jonathan wrote:
> fixing compiler warnings in df v3.6 for c-state toggle and pmc count.
> 
> Change-Id: I74f8f1eafccf523a89d60d005e3549235f75c6b8
> Signed-off-by: Jonathan Kim 
> ---
>   drivers/gpu/drm/amd/amdgpu/df_v3_6.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c 
> b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
> index f403c62c944e..e1cf7e9c616a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
> +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
> @@ -93,7 +93,7 @@ const struct attribute_group *df_v3_6_attr_groups[] = {
>   NULL
>   };
>   
> -static df_v3_6_set_df_cstate(struct amdgpu_device *adev, int allow)
> +static int df_v3_6_set_df_cstate(struct amdgpu_device *adev, int allow)
>   {
>   int r = 0;
>   
> @@ -546,7 +546,7 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device 
> *adev,
> uint64_t config,
> uint64_t *count)
>   {
> - uint32_t lo_base_addr, hi_base_addr, lo_val, hi_val;
> + uint32_t lo_base_addr, hi_base_addr, lo_val = 0, hi_val = 0;
>   *count = 0;
>   
>   switch (adev->asic_type) {
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: disable c-states on xgmi perfmons

2019-10-17 Thread Yang, Philip
I got compiler warnings after update this morning, because the variables 
are not initialized in df_v3_6_set_df_cstate() return failed path.

  CC [M]  drivers/gpu/drm/amd/amdgpu/gmc_v9_0.o
   CC [M]  drivers/gpu/drm/amd/amdgpu/gfxhub_v1_1.o
/home/yangp/git/compute_staging/kernel/drivers/gpu/drm/amd/amdgpu/df_v3_6.c:96:8:
 
warning: return type defaults to ‘int’ [-Wreturn-type]
  static df_v3_6_set_df_cstate(struct amdgpu_device *adev, int allow)
 ^
/home/yangp/git/compute_staging/kernel/drivers/gpu/drm/amd/amdgpu/df_v3_6.c: 
In function ‘df_v3_6_pmc_get_count’:
/home/yangp/git/compute_staging/kernel/drivers/gpu/drm/amd/amdgpu/df_v3_6.c:564:22:
 
warning: ‘hi_val’ may be used uninitialized in this function 
[-Wmaybe-uninitialized]
*count  = ((hi_val | 0ULL) << 32) | (lo_val | 0ULL);
   ^~~
/home/yangp/git/compute_staging/kernel/drivers/gpu/drm/amd/amdgpu/df_v3_6.c:564:47:
 
warning: ‘lo_val’ may be used uninitialized in this function 
[-Wmaybe-uninitialized]
*count  = ((hi_val | 0ULL) << 32) | (lo_val | 0ULL);
^~~
   CC [M]  drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.o


Regards,
Philip

On 2019-10-16 10:54 p.m., Quan, Evan wrote:
> Reviewed-by: Evan Quan 
> 
>> -Original Message-
>> From: Kim, Jonathan 
>> Sent: 2019年10月17日 10:06
>> To: amd-gfx@lists.freedesktop.org
>> Cc: Kuehling, Felix ; Quan, Evan
>> ; Kim, Jonathan ; Kim,
>> Jonathan 
>> Subject: [PATCH] drm/amdgpu: disable c-states on xgmi perfmons
>>
>> read or writes to df registers when gpu df is in c-states will result in
>> hang.  df c-states should be disabled prior to read or writes then
>> re-enabled after read or writes.
>>
>> v2: use old powerplay routines for vega20
>>
>> Change-Id: I6d5a83e4fe13e29c73dfb03a94fe7c611e867fec
>> Signed-off-by: Jonathan Kim 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/df_v3_6.c | 36
>> +++-
>>   1 file changed, 35 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
>> b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
>> index 16fbd2bc8ad1..f403c62c944e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/df_v3_6.c
>> @@ -93,6 +93,21 @@ const struct attribute_group *df_v3_6_attr_groups[] =
>> {
>>  NULL
>>   };
>>
>> +static df_v3_6_set_df_cstate(struct amdgpu_device *adev, int allow)
>> +{
>> +int r = 0;
>> +
>> +if (is_support_sw_smu(adev)) {
>> +r = smu_set_df_cstate(>smu, allow);
>> +} else if (adev->powerplay.pp_funcs
>> +&& adev->powerplay.pp_funcs->set_df_cstate) {
>> +r = adev->powerplay.pp_funcs->set_df_cstate(
>> +adev->powerplay.pp_handle, allow);
>> +}
>> +
>> +return r;
>> +}
>> +
>>   static uint64_t df_v3_6_get_fica(struct amdgpu_device *adev,
>>   uint32_t ficaa_val)
>>   {
>> @@ -102,6 +117,9 @@ static uint64_t df_v3_6_get_fica(struct
>> amdgpu_device *adev,
>>  address = adev->nbio.funcs->get_pcie_index_offset(adev);
>>  data = adev->nbio.funcs->get_pcie_data_offset(adev);
>>
>> +if (df_v3_6_set_df_cstate(adev, DF_CSTATE_DISALLOW))
>> +return 0x;
>> +
>>  spin_lock_irqsave(>pcie_idx_lock, flags);
>>  WREG32(address,
>> smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
>>  WREG32(data, ficaa_val);
>> @@ -114,6 +132,8 @@ static uint64_t df_v3_6_get_fica(struct
>> amdgpu_device *adev,
>>
>>  spin_unlock_irqrestore(>pcie_idx_lock, flags);
>>
>> +df_v3_6_set_df_cstate(adev, DF_CSTATE_ALLOW);
>> +
>>  return (((ficadh_val & 0x) << 32) | ficadl_val);
>>   }
>>
>> @@ -125,6 +145,9 @@ static void df_v3_6_set_fica(struct amdgpu_device
>> *adev, uint32_t ficaa_val,
>>  address = adev->nbio.funcs->get_pcie_index_offset(adev);
>>  data = adev->nbio.funcs->get_pcie_data_offset(adev);
>>
>> +if (df_v3_6_set_df_cstate(adev, DF_CSTATE_DISALLOW))
>> +return;
>> +
>>  spin_lock_irqsave(>pcie_idx_lock, flags);
>>  WREG32(address,
>> smnDF_PIE_AON_FabricIndirectConfigAccessAddress3);
>>  WREG32(data, ficaa_val);
>> @@ -134,8 +157,9 @@ static void df_v3_6_set_fica(struct amdgpu_device
>> *adev, uint32_t ficaa_val,
>>
>>  WREG32(address,
>> smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3);
>>  WREG32(data, ficadh_val);
>> -
>>  spin_unlock_irqrestore(>pcie_idx_lock, flags);
>> +
>> +df_v3_6_set_df_cstate(adev, DF_CSTATE_ALLOW);
>>   }
>>
>>   /*
>> @@ -153,12 +177,17 @@ static void df_v3_6_perfmon_rreg(struct
>> amdgpu_device *adev,
>>  address = adev->nbio.funcs->get_pcie_index_offset(adev);
>>  data = adev->nbio.funcs->get_pcie_data_offset(adev);
>>
>> +if (df_v3_6_set_df_cstate(adev, DF_CSTATE_DISALLOW))
>> +return;
>> +
>>  spin_lock_irqsave(>pcie_idx_lock, flags);
>>  WREG32(address, lo_addr);
>>  *lo_val = RREG32(data);
>>  

Re: [PATCH hmm 00/15] Consolidate the mmu notifier interval_tree and locking

2019-10-17 Thread Yang, Philip


On 2019-10-17 4:54 a.m., Christian König wrote:
> Am 16.10.19 um 18:04 schrieb Jason Gunthorpe:
>> On Wed, Oct 16, 2019 at 10:58:02AM +0200, Christian König wrote:
>>> Am 15.10.19 um 20:12 schrieb Jason Gunthorpe:
 From: Jason Gunthorpe 

 8 of the mmu_notifier using drivers (i915_gem, radeon_mn, umem_odp, 
 hfi1,
 scif_dma, vhost, gntdev, hmm) drivers are using a common pattern where
 they only use invalidate_range_start/end and immediately check the
 invalidating range against some driver data structure to tell if the
 driver is interested. Half of them use an interval_tree, the others are
 simple linear search lists.

 Of the ones I checked they largely seem to have various kinds of races,
 bugs and poor implementation. This is a result of the complexity in how
 the notifier interacts with get_user_pages(). It is extremely 
 difficult to
 use it correctly.

 Consolidate all of this code together into the core mmu_notifier and
 provide a locking scheme similar to hmm_mirror that allows the user to
 safely use get_user_pages() and reliably know if the page list still
 matches the mm.
>>> That sounds really good, but could you outline for a moment how that is
>>> archived?
>> It uses the same basic scheme as hmm and rdma odp, outlined in the
>> revisions to hmm.rst later on.
>>
>> Basically,
>>
>>   seq = mmu_range_read_begin();
>>
>>   // This is a speculative region
>>   .. get_user_pages()/hmm_range_fault() ..
> 
> How do we enforce that this get_user_pages()/hmm_range_fault() doesn't 
> see outdated page table information?
> 
> In other words how the the following race prevented:
> 
> CPU A CPU B
> invalidate_range_start()
>        mmu_range_read_begin()
>        get_user_pages()/hmm_range_fault()
> Updating the ptes
> invalidate_range_end()
> 
> 
> I mean get_user_pages() tries to circumvent this issue by grabbing a 
> reference to the pages in question, but that isn't sufficient for the 
> SVM use case.
> 
> That's the reason why we had this horrible solution with a r/w lock and 
> a linked list of BOs in an interval tree.
> 
> Regards,
> Christian.
get_user_pages/hmm_range_fault() and invalidate_range_start() both are 
called while holding mm->map_sem, so they are always serialized.

Philip
> 
>>   // Result cannot be derferenced
>>
>>   take_lock(driver->update);
>>   if (mmu_range_read_retry(, range.notifier_seq) {
>>  // collision! The results are not correct
>>  goto again
>>   }
>>
>>   // no collision, and now under lock. Now we can de-reference the 
>> pages/etc
>>   // program HW
>>   // Now the invalidate callback is responsible to synchronize against 
>> changes
>>   unlock(driver->update)
>>
>> Basically, anything that was using hmm_mirror correctly transisions
>> over fairly trivially, just with the modification to store a sequence
>> number to close that race described in the hmm commit.
>>
>> For something like AMD gpu I expect it to transition to use dma_fence
>> from the notifier for coherency right before it unlocks driver->update.
>>
>> Jason
>> ___
>> 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
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH v3] drm/amdgpu: user pages array memory leak fix

2019-10-11 Thread Yang, Philip


On 2019-10-11 1:33 p.m., Kuehling, Felix wrote:
> On 2019-10-11 10:36 a.m., Yang, Philip wrote:
>> user_pages array should always be freed after validation regardless if
>> user pages are changed after bo is created because with HMM change parse
>> bo always allocate user pages array to get user pages for userptr bo.
>>
>> v2: remove unused local variable and amend commit
>>
>> v3: add back get user pages in gem_userptr_ioctl, to detect application
>> bug where an userptr VMA is not ananymous memory and reject it.
>>
>> Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962
>>
>> Signed-off-by: Philip Yang 
>> Tested-by: Joe Barnett 
>> Reviewed-by: Christian König 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +---
>>1 file changed, 1 insertion(+), 3 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> index c18a153b3d2a..e7b39daa22f6 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> @@ -476,7 +476,6 @@ static int amdgpu_cs_list_validate(struct 
>> amdgpu_cs_parser *p,
>>
>>  list_for_each_entry(lobj, validated, tv.head) {
>>  struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
>> -bool binding_userptr = false;
>>  struct mm_struct *usermm;
>>
>>  usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
>> @@ -493,14 +492,13 @@ static int amdgpu_cs_list_validate(struct 
>> amdgpu_cs_parser *p,
>>
>>  amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
>>   lobj->user_pages);
>> -binding_userptr = true;
>>  }
>>
>>  r = amdgpu_cs_validate(p, bo);
>>  if (r)
>>  return r;
>>
>> -if (binding_userptr) {
>> +if (lobj->user_pages) {
> 
> This if is not needed. kvfree should be able to handle NULL pointers,
> and unconditionally setting the pointer to NULL afterwards is not a
> problem either. With that fixed, this commit is
> 
> Reviewed-by: Felix Kuehling 
> 
> However, I don't think this should be the final solution. My concern
> with this solution is, that you end up freeing and regenerating the
> user_pages arrays more frequently than necessary: On every command
> submission, even if there was no MMU notifier since the last command
> submission. I was hoping we could get back to a solution where we can
> maintain the same user_pages array across command submissions, since MMU
> notifiers are rare. That should reduce overhead from doing all thos page
> table walks in HMM on every command submissions when using userptrs.
> 
Yes, I will have another patch to address this using hmm_range_valid, 
the idea is to allow hmm range tracking cross gem_userptr_ioctl and 
cs_ioctl.

Thanks,
Philip

> Regards,
>     Felix
> 
> 
>>  kvfree(lobj->user_pages);
>>  lobj->user_pages = NULL;
>>  }
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH v3] drm/amdgpu: user pages array memory leak fix

2019-10-11 Thread Yang, Philip
user_pages array should always be freed after validation regardless if
user pages are changed after bo is created because with HMM change parse
bo always allocate user pages array to get user pages for userptr bo.

v2: remove unused local variable and amend commit

v3: add back get user pages in gem_userptr_ioctl, to detect application
bug where an userptr VMA is not ananymous memory and reject it.

Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962

Signed-off-by: Philip Yang 
Tested-by: Joe Barnett 
Reviewed-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index c18a153b3d2a..e7b39daa22f6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -476,7 +476,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser 
*p,
 
list_for_each_entry(lobj, validated, tv.head) {
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
-   bool binding_userptr = false;
struct mm_struct *usermm;
 
usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
@@ -493,14 +492,13 @@ static int amdgpu_cs_list_validate(struct 
amdgpu_cs_parser *p,
 
amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
 lobj->user_pages);
-   binding_userptr = true;
}
 
r = amdgpu_cs_validate(p, bo);
if (r)
return r;
 
-   if (binding_userptr) {
+   if (lobj->user_pages) {
kvfree(lobj->user_pages);
lobj->user_pages = NULL;
}
-- 
2.17.1

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

Re: [PATCH] drm/amdgpu: user pages array memory leak fix

2019-10-11 Thread Yang, Philip


On 2019-10-11 4:40 a.m., Christian König wrote:
> Am 03.10.19 um 21:44 schrieb Yang, Philip:
>> user_pages array should always be freed after validation regardless if
>> user pages are changed after bo is created because with HMM change parse
>> bo always allocate user pages array to get user pages for userptr bo.
>>
>> Don't need to get user pages while creating uerptr bo because user pages
>> will only be used while validating after parsing userptr bo.
>>
>> Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962
>>
>> v2: remove unused local variable and amend commit
>>
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  4 +---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 +--
>>   2 files changed, 2 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> index 49b767b7238f..961186e7113e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
>> @@ -474,7 +474,6 @@ static int amdgpu_cs_list_validate(struct 
>> amdgpu_cs_parser *p,
>>   list_for_each_entry(lobj, validated, tv.head) {
>>   struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
>> -    bool binding_userptr = false;
>>   struct mm_struct *usermm;
>>   usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
>> @@ -491,14 +490,13 @@ static int amdgpu_cs_list_validate(struct 
>> amdgpu_cs_parser *p,
>>   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
>>    lobj->user_pages);
>> -    binding_userptr = true;
>>   }
>>   r = amdgpu_cs_validate(p, bo);
>>   if (r)
>>   return r;
>> -    if (binding_userptr) {
>> +    if (lobj->user_pages) {
>>   kvfree(lobj->user_pages);
>>   lobj->user_pages = NULL;
>>   }
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> index a828e3d0bfbd..3ccd61d69964 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>> @@ -283,7 +283,6 @@ int amdgpu_gem_create_ioctl(struct drm_device 
>> *dev, void *data,
>>   int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
>>    struct drm_file *filp)
>>   {
>> -    struct ttm_operation_ctx ctx = { true, false };
>>   struct amdgpu_device *adev = dev->dev_private;
>>   struct drm_amdgpu_gem_userptr *args = data;
>>   struct drm_gem_object *gobj;
>> @@ -326,32 +325,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device 
>> *dev, void *data,
>>   goto release_object;
>>   }
>> -    if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
> 
> We can't drop that handling here, it is mandatory to detect an 
> application bug where an application tries to user an userptr with a VMA 
> which is not anonymous memory.
> 
> This must be detected and rejected as invalid here.
> 
> I suggest that we allocate a local pages array similar to how we do it 
> during CS and release that after the function is done.
> 
Thanks for this, we can use bo->tbo.ttm->pages array here to avoid extra 
alloc/free of pages array because CS uses local pages array and update 
to bo->tbo.ttm->pages if user pages are moved. I will submit patch v3 
for review.

> Regards,
> Christian.
> 
>> -    r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
>> -    if (r)
>> -    goto release_object;
>> -
>> -    r = amdgpu_bo_reserve(bo, true);
>> -    if (r)
>> -    goto user_pages_done;
>> -
>> -    amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
>> -    r = ttm_bo_validate(>tbo, >placement, );
>> -    amdgpu_bo_unreserve(bo);
>> -    if (r)
>> -    goto user_pages_done;
>> -    }
>> -
>>   r = drm_gem_handle_create(filp, gobj, );
>>   if (r)
>> -    goto user_pages_done;
>> +    goto release_object;
>>   args->handle = handle;
>> -user_pages_done:
>> -    if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
>> -    amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>> -
>>   release_object:
>>   drm_gem_object_put_unlocked(gobj);
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: user pages array memory leak fix

2019-10-04 Thread Yang, Philip
Thanks Joe for the test, I will add your Tested-by.

Hi Christian,

May you help review? The change removes the get user pages from 
gem_userptr_ioctl, this was done if flags AMDGPU_GEM_USERPTR_VALIDATE is 
set, and delay the get user pages to amdgpu_cs_parser_bos, and check if 
user pages are invalidated when amdgpu_cs_submit. I don't find issue for 
overnight test, but not sure if there is potential side effect.

Thanks,
Philip

On 2019-10-03 3:44 p.m., Yang, Philip wrote:
> user_pages array should always be freed after validation regardless if
> user pages are changed after bo is created because with HMM change parse
> bo always allocate user pages array to get user pages for userptr bo.
> 
> Don't need to get user pages while creating uerptr bo because user pages
> will only be used while validating after parsing userptr bo.
> 
> Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962
> 
> v2: remove unused local variable and amend commit
> 
> Signed-off-by: Philip Yang 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  4 +---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 +--
>   2 files changed, 2 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index 49b767b7238f..961186e7113e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -474,7 +474,6 @@ static int amdgpu_cs_list_validate(struct 
> amdgpu_cs_parser *p,
>   
>   list_for_each_entry(lobj, validated, tv.head) {
>   struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
> - bool binding_userptr = false;
>   struct mm_struct *usermm;
>   
>   usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
> @@ -491,14 +490,13 @@ static int amdgpu_cs_list_validate(struct 
> amdgpu_cs_parser *p,
>   
>   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
>lobj->user_pages);
> - binding_userptr = true;
>   }
>   
>   r = amdgpu_cs_validate(p, bo);
>   if (r)
>   return r;
>   
> - if (binding_userptr) {
> + if (lobj->user_pages) {
>   kvfree(lobj->user_pages);
>   lobj->user_pages = NULL;
>   }
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> index a828e3d0bfbd..3ccd61d69964 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> @@ -283,7 +283,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void 
> *data,
>   int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
>struct drm_file *filp)
>   {
> - struct ttm_operation_ctx ctx = { true, false };
>   struct amdgpu_device *adev = dev->dev_private;
>   struct drm_amdgpu_gem_userptr *args = data;
>   struct drm_gem_object *gobj;
> @@ -326,32 +325,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, 
> void *data,
>   goto release_object;
>   }
>   
> - if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
> - r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
> - if (r)
> - goto release_object;
> -
> - r = amdgpu_bo_reserve(bo, true);
> - if (r)
> - goto user_pages_done;
> -
> - amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
> - r = ttm_bo_validate(>tbo, >placement, );
> - amdgpu_bo_unreserve(bo);
> - if (r)
> - goto user_pages_done;
> - }
> -
>   r = drm_gem_handle_create(filp, gobj, );
>   if (r)
> - goto user_pages_done;
> + goto release_object;
>   
>   args->handle = handle;
>   
> -user_pages_done:
> - if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
> - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
> -
>   release_object:
>   drm_gem_object_put_unlocked(gobj);
>   
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdgpu: user pages array memory leak fix

2019-10-03 Thread Yang, Philip
user_pages array should always be freed after validation regardless if
user pages are changed after bo is created because with HMM change parse
bo always allocate user pages array to get user pages for userptr bo.

Don't need to get user pages while creating uerptr bo because user pages
will only be used while validating after parsing userptr bo.

Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962

v2: remove unused local variable and amend commit

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  4 +---
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 +--
 2 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 49b767b7238f..961186e7113e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -474,7 +474,6 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser 
*p,
 
list_for_each_entry(lobj, validated, tv.head) {
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(lobj->tv.bo);
-   bool binding_userptr = false;
struct mm_struct *usermm;
 
usermm = amdgpu_ttm_tt_get_usermm(bo->tbo.ttm);
@@ -491,14 +490,13 @@ static int amdgpu_cs_list_validate(struct 
amdgpu_cs_parser *p,
 
amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm,
 lobj->user_pages);
-   binding_userptr = true;
}
 
r = amdgpu_cs_validate(p, bo);
if (r)
return r;
 
-   if (binding_userptr) {
+   if (lobj->user_pages) {
kvfree(lobj->user_pages);
lobj->user_pages = NULL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a828e3d0bfbd..3ccd61d69964 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -283,7 +283,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void 
*data,
 int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
 struct drm_file *filp)
 {
-   struct ttm_operation_ctx ctx = { true, false };
struct amdgpu_device *adev = dev->dev_private;
struct drm_amdgpu_gem_userptr *args = data;
struct drm_gem_object *gobj;
@@ -326,32 +325,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void 
*data,
goto release_object;
}
 
-   if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
-   r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
-   if (r)
-   goto release_object;
-
-   r = amdgpu_bo_reserve(bo, true);
-   if (r)
-   goto user_pages_done;
-
-   amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
-   r = ttm_bo_validate(>tbo, >placement, );
-   amdgpu_bo_unreserve(bo);
-   if (r)
-   goto user_pages_done;
-   }
-
r = drm_gem_handle_create(filp, gobj, );
if (r)
-   goto user_pages_done;
+   goto release_object;
 
args->handle = handle;
 
-user_pages_done:
-   if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-
 release_object:
drm_gem_object_put_unlocked(gobj);
 
-- 
2.17.1

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

[PATCH] drm/amdgpu: user pages array memory leak fix

2019-10-03 Thread Yang, Philip
user_pages array should be freed regardless if user pages are
invalidated after bo is created because HMM change to always allocate
user pages array to get user pages while parsing user page bo.

Don't need to to get user pages while creating bo because user pages
will only be used after parsing user page bo.

Bugzilla: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1844962

Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c  |  2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 23 +--
 2 files changed, 2 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 49b767b7238f..e861de259def 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -498,7 +498,7 @@ static int amdgpu_cs_list_validate(struct amdgpu_cs_parser 
*p,
if (r)
return r;
 
-   if (binding_userptr) {
+   if (lobj->user_pages) {
kvfree(lobj->user_pages);
lobj->user_pages = NULL;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index a828e3d0bfbd..3ccd61d69964 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -283,7 +283,6 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void 
*data,
 int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
 struct drm_file *filp)
 {
-   struct ttm_operation_ctx ctx = { true, false };
struct amdgpu_device *adev = dev->dev_private;
struct drm_amdgpu_gem_userptr *args = data;
struct drm_gem_object *gobj;
@@ -326,32 +325,12 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void 
*data,
goto release_object;
}
 
-   if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) {
-   r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages);
-   if (r)
-   goto release_object;
-
-   r = amdgpu_bo_reserve(bo, true);
-   if (r)
-   goto user_pages_done;
-
-   amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
-   r = ttm_bo_validate(>tbo, >placement, );
-   amdgpu_bo_unreserve(bo);
-   if (r)
-   goto user_pages_done;
-   }
-
r = drm_gem_handle_create(filp, gobj, );
if (r)
-   goto user_pages_done;
+   goto release_object;
 
args->handle = handle;
 
-user_pages_done:
-   if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE)
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-
 release_object:
drm_gem_object_put_unlocked(gobj);
 
-- 
2.17.1

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

Re: [PATCH 9/9] drm/amdgpu: add graceful VM fault handling v2

2019-09-09 Thread Yang, Philip


On 2019-09-09 8:03 a.m., Christian König wrote:
> Am 04.09.19 um 22:12 schrieb Yang, Philip:
>> This series looks nice and clear for me, two questions embedded below.
>>
>> Are we going to use dedicated sdma page queue for direct VM update path
>> during a fault?
>>
>> Thanks,
>> Philip
>>
>> On 2019-09-04 11:02 a.m., Christian König wrote:
>>> Next step towards HMM support. For now just silence the retry fault and
>>> optionally redirect the request to the dummy page.
>>>
>>> v2: make sure the VM is not destroyed while we handle the fault.
>>>
>>> Signed-off-by: Christian König 
>>> ---
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 74 
>>> ++
>>>    drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  2 +
>>>    drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  4 ++
>>>    3 files changed, 80 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> index 951608fc1925..410d89966a66 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
>>> @@ -3142,3 +3142,77 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm 
>>> *vm)
>>>    }
>>>    }
>>>    }
>>> +
>>> +/**
>>> + * amdgpu_vm_handle_fault - graceful handling of VM faults.
>>> + * @adev: amdgpu device pointer
>>> + * @pasid: PASID of the VM
>>> + * @addr: Address of the fault
>>> + *
>>> + * Try to gracefully handle a VM fault. Return true if the fault was 
>>> handled and
>>> + * shouldn't be reported any more.
>>> + */
>>> +bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int 
>>> pasid,
>>> +    uint64_t addr)
>>> +{
>>> +    struct amdgpu_ring *ring = >sdma.instance[0].page;
>>> +    struct amdgpu_bo *root;
>>> +    uint64_t value, flags;
>>> +    struct amdgpu_vm *vm;
>>> +    long r;
>>> +
>>> +    if (!ring->sched.ready)
>>> +    return false;
>>> +
>>> +    spin_lock(>vm_manager.pasid_lock);
>>> +    vm = idr_find(>vm_manager.pasid_idr, pasid);
>>> +    if (vm)
>>> +    root = amdgpu_bo_ref(vm->root.base.bo);
>>> +    else
>>> +    root = NULL;
>>> +    spin_unlock(>vm_manager.pasid_lock);
>>> +
>>> +    if (!root)
>>> +    return false;
>>> +
>>> +    r = amdgpu_bo_reserve(root, true);
>>> +    if (r)
>>> +    goto error_unref;
>>> +
>>> +    spin_lock(>vm_manager.pasid_lock);
>>> +    vm = idr_find(>vm_manager.pasid_idr, pasid);
>>> +    spin_unlock(>vm_manager.pasid_lock);
>>> +
>> Here get vm from pasid second time, and check if PD bo is changed, is
>> this to handle vm fault race with vm destory?
> 
> Yes, exactly.
> 
>>
>>> +    if (!vm || vm->root.base.bo != root)
>>> +    goto error_unlock;
>>> +
>>> +    addr /= AMDGPU_GPU_PAGE_SIZE;
>>> +    flags = AMDGPU_PTE_VALID | AMDGPU_PTE_SNOOPED |
>>> +    AMDGPU_PTE_SYSTEM;
>>> +
>>> +    if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_NEVER) {
>>> +    /* Redirect the access to the dummy page */
>>> +    value = adev->dummy_page_addr;
>>> +    flags |= AMDGPU_PTE_EXECUTABLE | AMDGPU_PTE_READABLE |
>>> +    AMDGPU_PTE_WRITEABLE;
>>> +    } else {
>>> +    value = 0;
>>> +    }
>>> +
>>> +    r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr 
>>> + 1,
>>> +    flags, value, NULL, NULL);
>>> +    if (r)
>>> +    goto error_unlock;
>>> +
>> After fault address redirect to dummy page, will the fault recover and
>> retry continue to execute?
> 
> Yes, the read/write operation will just retry and use the value from the 
> dummy page instead.
> 
>> Is this dangerous to update PTE to use system
>> memory address 0?
> 
> What are you talking about? The dummy page is a page allocate by TTM 
> where we redirect faulty accesses to.
> 
For amdgpu_vm_fault_stop equals to AMDGPU_VM_FAULT_STOP_FIRST/ALWAYS 
case, value is 0, this will redirect to system memory 0. Maybe redirect 
is only needed for AMDGPU_VM_FAULT_STOP_NEVER?

Regards,
Philip

> Regards,
> Christian.
> 
>>
>>> +    r = amdgpu_vm_

[PATCH] drm/amdgpu: check if nbio->ras_if exist

2019-09-06 Thread Yang, Philip
To avoid NULL function pointer access. This happens on VG10, reboot
command hangs and have to power off/on to reboot the machine. This is
serial console log:

[  OK  ] Reached target Unmount All Filesystems.
[  OK  ] Reached target Final Step.
 Starting Reboot...
[  305.696271] systemd-shutdown[1]: Syncing filesystems and block
devices.
[  306.947328] systemd-shutdown[1]: Sending SIGTERM to remaining
processes...
[  306.963920] systemd-journald[1722]: Received SIGTERM from PID 1
(systemd-shutdow).
[  307.322717] systemd-shutdown[1]: Sending SIGKILL to remaining
processes...
[  307.336472] systemd-shutdown[1]: Unmounting file systems.
[  307.454202] EXT4-fs (sda2): re-mounted. Opts: errors=remount-ro
[  307.480523] systemd-shutdown[1]: All filesystems unmounted.
[  307.486537] systemd-shutdown[1]: Deactivating swaps.
[  307.491962] systemd-shutdown[1]: All swaps deactivated.
[  307.497624] systemd-shutdown[1]: Detaching loop devices.
[  307.504418] systemd-shutdown[1]: All loop devices detached.
[  307.510418] systemd-shutdown[1]: Detaching DM devices.
[  307.565907] sd 2:0:0:0: [sda] Synchronizing SCSI cache
[  307.731313] BUG: kernel NULL pointer dereference, address:

[  307.738802] #PF: supervisor read access in kernel mode
[  307.744326] #PF: error_code(0x) - not-present page
[  307.749850] PGD 0 P4D 0
[  307.752568] Oops:  [#1] SMP PTI
[  307.756314] CPU: 3 PID: 1 Comm: systemd-shutdow Not tainted
5.2.0-rc1-kfd-yangp #453
[  307.764644] Hardware name: ASUS All Series/Z97-PRO(Wi-Fi ac)/USB 3.1,
BIOS 9001 03/07/2016
[  307.773580] RIP: 0010:soc15_common_hw_fini+0x33/0xc0 [amdgpu]
[  307.779760] Code: 89 fb e8 60 f5 ff ff f6 83 50 df 01 00 04 75 3d 48
8b b3 90 7d 00 00 48 c7 c7 17 b8 530
[  307.799967] RSP: 0018:ac9483153d40 EFLAGS: 00010286
[  307.805585] RAX:  RBX: 9eb299da RCX:
0006
[  307.813261] RDX:  RSI: 9eb29e3508a0 RDI:
9eb29e35
[  307.820935] RBP: 9eb299da R08:  R09:

[  307.828609] R10:  R11:  R12:
9eb299dbd1f8
[  307.836284] R13: c04f8368 R14: 9eb29cebd130 R15:

[  307.843959] FS:  7f06721c9940() GS:9eb2a18c()
knlGS:
[  307.852663] CS:  0010 DS:  ES:  CR0: 80050033
[  307.858842] CR2:  CR3: 00081d798005 CR4:
001606e0
[  307.866516] Call Trace:
[  307.869169]  amdgpu_device_ip_suspend_phase2+0x80/0x110 [amdgpu]
[  307.875654]  ? amdgpu_device_ip_suspend_phase1+0x4d/0xd0 [amdgpu]
[  307.882230]  amdgpu_device_ip_suspend+0x2e/0x60 [amdgpu]
[  307.887966]  amdgpu_pci_shutdown+0x2f/0x40 [amdgpu]
[  307.893211]  pci_device_shutdown+0x31/0x60
[  307.897613]  device_shutdown+0x14c/0x1f0
[  307.901829]  kernel_restart+0xe/0x50
[  307.905669]  __do_sys_reboot+0x1df/0x210
[  307.909884]  ? task_work_run+0x73/0xb0
[  307.913914]  ? trace_hardirqs_off_thunk+0x1a/0x1c
[  307.918970]  do_syscall_64+0x4a/0x1c0
[  307.922904]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[  307.928336] RIP: 0033:0x7f0671cf8373
[  307.932176] Code: 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00
00 0f 1f 44 00 00 89 fa be 69 19 128
[  307.952384] RSP: 002b:7ffdd1723d68 EFLAGS: 0202 ORIG_RAX:
00a9
[  307.960527] RAX: ffda RBX: 01234567 RCX:
7f0671cf8373
[  307.968201] RDX: 01234567 RSI: 28121969 RDI:
fee1dead
[  307.975875] RBP: 7ffdd1723dd0 R08:  R09:

[  307.983550] R10: 0002 R11: 0202 R12:
7ffdd1723dd8
[  307.991224] R13:  R14: 001b0004 R15:
7ffdd17240c8
[  307.998901] Modules linked in: xt_MASQUERADE nfnetlink iptable_nat
xt_addrtype xt_conntrack nf_nat nf_cos
[  308.026505] CR2: 
[  308.039998] RIP: 0010:soc15_common_hw_fini+0x33/0xc0 [amdgpu]
[  308.046180] Code: 89 fb e8 60 f5 ff ff f6 83 50 df 01 00 04 75 3d 48
8b b3 90 7d 00 00 48 c7 c7 17 b8 530
[  308.066392] RSP: 0018:ac9483153d40 EFLAGS: 00010286
[  308.072013] RAX:  RBX: 9eb299da RCX:
0006
[  308.079689] RDX:  RSI: 9eb29e3508a0 RDI:
9eb29e35
[  308.087366] RBP: 9eb299da R08:  R09:

[  308.095042] R10:  R11:  R12:
9eb299dbd1f8
[  308.102717] R13: c04f8368 R14: 9eb29cebd130 R15:

[  308.110394] FS:  7f06721c9940() GS:9eb2a18c()
knlGS:
[  308.119099] CS:  0010 DS:  ES:  CR0: 80050033
[  308.125280] CR2:  CR3: 00081d798005 CR4:
001606e0
[  308.135304] printk: systemd-shutdow: 3 output lines suppressed due to
ratelimiting
[  308.143518] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x0009
[  308.151798] Kernel Offset: 0x1500 from 0x8100

Re: [PATCH 1/1] drm/amdgpu: Disable retry faults in VMID0

2019-09-05 Thread Yang, Philip
VMID0 init path was missed when enabling amdgpu_noretry option. Good 
catch and fix.

Reviewed-by: Philip Yang 

On 2019-09-04 7:31 p.m., Kuehling, Felix wrote:
> There is no point retrying page faults in VMID0. Those faults are
> always fatal.
> 
> Signed-off-by: Felix Kuehling 
> ---
>   drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c | 2 ++
>   drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c | 2 ++
>   drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c  | 2 ++
>   drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c  | 2 ++
>   drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c  | 2 ++
>   5 files changed, 10 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
> index 6ce37ce77d14..9ec4297e61e5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c
> @@ -178,6 +178,8 @@ static void gfxhub_v1_0_enable_system_domain(struct 
> amdgpu_device *adev)
>   tmp = RREG32_SOC15(GC, 0, mmVM_CONTEXT0_CNTL);
>   tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
>   tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
> + tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL,
> + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
>   WREG32_SOC15(GC, 0, mmVM_CONTEXT0_CNTL, tmp);
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> index 8b789f750b72..a9238735d361 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c
> @@ -166,6 +166,8 @@ static void gfxhub_v2_0_enable_system_domain(struct 
> amdgpu_device *adev)
>   tmp = RREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_CNTL);
>   tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
>   tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
> + tmp = REG_SET_FIELD(tmp, GCVM_CONTEXT0_CNTL,
> + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
>   WREG32_SOC15(GC, 0, mmGCVM_CONTEXT0_CNTL, tmp);
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c 
> b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
> index b9d6c0bfa594..4c7e8c64a94e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
> @@ -207,6 +207,8 @@ static void mmhub_v1_0_enable_system_domain(struct 
> amdgpu_device *adev)
>   tmp = RREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_CNTL);
>   tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
>   tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
> + tmp = REG_SET_FIELD(tmp, VM_CONTEXT0_CNTL,
> + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
>   WREG32_SOC15(MMHUB, 0, mmVM_CONTEXT0_CNTL, tmp);
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c 
> b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
> index 3542c203c3c8..86ed8cb915a8 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
> @@ -152,6 +152,8 @@ static void mmhub_v2_0_enable_system_domain(struct 
> amdgpu_device *adev)
>   tmp = RREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL);
>   tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
>   tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
> + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL,
> + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
>   WREG32_SOC15(MMHUB, 0, mmMMVM_CONTEXT0_CNTL, tmp);
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c 
> b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
> index 0cf7ef44b4b5..657970f9ebfb 100644
> --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
> +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
> @@ -240,6 +240,8 @@ static void mmhub_v9_4_enable_system_domain(struct 
> amdgpu_device *adev,
> hubid * MMHUB_INSTANCE_REGISTER_OFFSET);
>   tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1);
>   tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT0_CNTL, PAGE_TABLE_DEPTH, 0);
> + tmp = REG_SET_FIELD(tmp, VML2VC0_VM_CONTEXT0_CNTL,
> + RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0);
>   WREG32_SOC15_OFFSET(MMHUB, 0, mmVML2VC0_VM_CONTEXT0_CNTL,
>   hubid * MMHUB_INSTANCE_REGISTER_OFFSET, tmp);
>   }
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 9/9] drm/amdgpu: add graceful VM fault handling v2

2019-09-04 Thread Yang, Philip
This series looks nice and clear for me, two questions embedded below.

Are we going to use dedicated sdma page queue for direct VM update path 
during a fault?

Thanks,
Philip

On 2019-09-04 11:02 a.m., Christian König wrote:
> Next step towards HMM support. For now just silence the retry fault and
> optionally redirect the request to the dummy page.
> 
> v2: make sure the VM is not destroyed while we handle the fault.
> 
> Signed-off-by: Christian König 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 74 ++
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  2 +
>   drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c  |  4 ++
>   3 files changed, 80 insertions(+)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index 951608fc1925..410d89966a66 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -3142,3 +3142,77 @@ void amdgpu_vm_set_task_info(struct amdgpu_vm *vm)
>   }
>   }
>   }
> +
> +/**
> + * amdgpu_vm_handle_fault - graceful handling of VM faults.
> + * @adev: amdgpu device pointer
> + * @pasid: PASID of the VM
> + * @addr: Address of the fault
> + *
> + * Try to gracefully handle a VM fault. Return true if the fault was handled 
> and
> + * shouldn't be reported any more.
> + */
> +bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
> + uint64_t addr)
> +{
> + struct amdgpu_ring *ring = >sdma.instance[0].page;
> + struct amdgpu_bo *root;
> + uint64_t value, flags;
> + struct amdgpu_vm *vm;
> + long r;
> +
> + if (!ring->sched.ready)
> + return false;
> +
> + spin_lock(>vm_manager.pasid_lock);
> + vm = idr_find(>vm_manager.pasid_idr, pasid);
> + if (vm)
> + root = amdgpu_bo_ref(vm->root.base.bo);
> + else
> + root = NULL;
> + spin_unlock(>vm_manager.pasid_lock);
> +
> + if (!root)
> + return false;
> +
> + r = amdgpu_bo_reserve(root, true);
> + if (r)
> + goto error_unref;
> +
> + spin_lock(>vm_manager.pasid_lock);
> + vm = idr_find(>vm_manager.pasid_idr, pasid);
> + spin_unlock(>vm_manager.pasid_lock);
> +
Here get vm from pasid second time, and check if PD bo is changed, is 
this to handle vm fault race with vm destory?

> + if (!vm || vm->root.base.bo != root)
> + goto error_unlock;
> +
> + addr /= AMDGPU_GPU_PAGE_SIZE;
> + flags = AMDGPU_PTE_VALID | AMDGPU_PTE_SNOOPED |
> + AMDGPU_PTE_SYSTEM;
> +
> + if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_NEVER) {
> + /* Redirect the access to the dummy page */
> + value = adev->dummy_page_addr;
> + flags |= AMDGPU_PTE_EXECUTABLE | AMDGPU_PTE_READABLE |
> + AMDGPU_PTE_WRITEABLE;
> + } else {
> + value = 0;
> + }
> +
> + r = amdgpu_vm_bo_update_mapping(adev, vm, true, NULL, addr, addr + 1,
> + flags, value, NULL, NULL);
> + if (r)
> + goto error_unlock;
> +
After fault address redirect to dummy page, will the fault recover and 
retry continue to execute? Is this dangerous to update PTE to use system 
memory address 0?

> + r = amdgpu_vm_update_pdes(adev, vm, true);
> +
> +error_unlock:
> + amdgpu_bo_unreserve(root);
> + if (r < 0)
> + DRM_ERROR("Can't handle page fault (%ld)\n", r);
> +
> +error_unref:
> + amdgpu_bo_unref();
> +
> + return false;
> +}
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index 0a97dc839f3b..4dbbe1b6b413 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -413,6 +413,8 @@ void amdgpu_vm_check_compute_bug(struct amdgpu_device 
> *adev);
>   
>   void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid,
>struct amdgpu_task_info *task_info);
> +bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, unsigned int pasid,
> + uint64_t addr);
>   
>   void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c 
> b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> index 9d15679df6e0..15a1ce51befa 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
> @@ -353,6 +353,10 @@ static int gmc_v9_0_process_interrupt(struct 
> amdgpu_device *adev,
>   }
>   
>   /* If it's the first fault for this address, process it normally */
> + if (retry_fault && !in_interrupt() &&
> + amdgpu_vm_handle_fault(adev, entry->pasid, addr))
> + return 1; /* This also prevents sending it to KFD */
> +
>   if (!amdgpu_sriov_vf(adev)) {
>   /*
>* Issue a dummy read to wait for the status register to
> 

Re: [PATCH] mm/hmm: hmm_range_fault handle pages swapped out

2019-08-16 Thread Yang, Philip


On 2019-08-15 8:54 p.m., Jason Gunthorpe wrote:
> On Thu, Aug 15, 2019 at 08:52:56PM +0000, Yang, Philip wrote:
>> hmm_range_fault may return NULL pages because some of pfns are equal to
>> HMM_PFN_NONE. This happens randomly under memory pressure. The reason is
>> for swapped out page pte path, hmm_vma_handle_pte doesn't update fault
>> variable from cpu_flags, so it failed to call hmm_vam_do_fault to swap
>> the page in.
>>
>> The fix is to call hmm_pte_need_fault to update fault variable.
> 
>> Change-Id: I2e8611485563d11d938881c18b7935fa1e7c91ee
> 
> I'll fix it for you but please be careful not to send Change-id's to
> the public lists.
> 
Thanks, the change-id was added by our Gerrit hook, I need generate 
patch files, remove change-id line and then send out modified patch 
files in future.

> Also what is the Fixes line for this?
> 
This fixes the issue found by the internal rocrtst, the 
rocrtstFunc.Memory_Max_Mem evicted some user buffers, and then following 
test restore those user buffers failed because the buffers are swapped 
out and application doesn't touch the buffers to swap it in.

>> Signed-off-by: Philip Yang 
>>   mm/hmm.c | 3 +++
>>   1 file changed, 3 insertions(+)
> 
> Ralph has also been looking at this area also so I'll give him a bit
> to chime in, otherwise with Jerome's review this looks OK to go to
> linux-next
>
Ok, thanks for helping push this to hmm branch at 
https://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git

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

[PATCH] mm/hmm: hmm_range_fault handle pages swapped out

2019-08-15 Thread Yang, Philip
hmm_range_fault may return NULL pages because some of pfns are equal to
HMM_PFN_NONE. This happens randomly under memory pressure. The reason is
for swapped out page pte path, hmm_vma_handle_pte doesn't update fault
variable from cpu_flags, so it failed to call hmm_vam_do_fault to swap
the page in.

The fix is to call hmm_pte_need_fault to update fault variable.

Change-Id: I2e8611485563d11d938881c18b7935fa1e7c91ee
Signed-off-by: Philip Yang 
---
 mm/hmm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mm/hmm.c b/mm/hmm.c
index 9f22562e2c43..7ca4fb39d3d8 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -544,6 +544,9 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, 
unsigned long addr,
swp_entry_t entry = pte_to_swp_entry(pte);
 
if (!non_swap_entry(entry)) {
+   cpu_flags = pte_to_hmm_pfn_flags(range, pte);
+   hmm_pte_need_fault(hmm_vma_walk, orig_pfn, cpu_flags,
+  , _fault);
if (fault || write_fault)
goto fault;
return 0;
-- 
2.17.1

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

Re: [PATCH 1/1] drm/amdkfd: Consistently apply noretry setting

2019-07-04 Thread Yang, Philip

On 2019-07-04 12:02 p.m., Kuehling, Felix wrote:
> On 2019-07-03 6:19 p.m., Yang, Philip wrote:
>> amdgpu_noretry default value is 0, this will generate VM fault storm
>> because the vm fault is not recovered. It may slow down the machine and
>> need reboot after application VM fault. Maybe change default value to 1?
> 
> This is the same as the current behaviour. My change doesn't modify the
> default behaviour, it only makes it configurable in a sensible way.
> 
> If we want to change the default, I'd do that in a separate commit.
>
I misunderstood VM_CONTEXT1_CNT/RETRY_PERMISSION_OR_INVALID_PAGE_FAULT 
change, yes, this is the same behavior. retry was already enabled by 
another patch "drm/amdgpu: re-enable retry faults" before. But I don't 
find the patch to silent retry storm on the mailing list.

Regards,
Philip

> Regards,
>     Felix
> 
>>
>> Other than that, this is reviewed by Philip Yang 
>>
>> On 2019-07-02 3:05 p.m., Kuehling, Felix wrote:
>>> Ping.
>>>
>>> Christian, Philip, any opinion about this patch?
>>>
>>> On 2019-06-21 8:20 p.m., Kuehling, Felix wrote:
>>>> Apply the same setting to SH_MEM_CONFIG and VM_CONTEXT1_CNTL. This
>>>> makes the noretry param no longer KFD-specific. On GFX10 I'm not
>>>> changing SH_MEM_CONFIG in this commit because GFX10 has different
>>>> retry behaviour in the SQ and I don't have a way to test it at the
>>>> moment.
>>>>
>>>> Suggested-by: Christian König 
>>>> CC: Philip Yang 
>>>> Signed-off-by: Felix Kuehling 
>>>> ---
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  1 +
>>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 16 +---
>>>>  drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c|  4 
>>>>  drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c |  3 ++-
>>>>  drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |  3 ++-
>>>>  drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c  |  3 ++-
>>>>  drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c  |  3 ++-
>>>>  .../drm/amd/amdkfd/kfd_device_queue_manager_v9.c |  2 +-
>>>>  drivers/gpu/drm/amd/amdkfd/kfd_priv.h|  2 +-
>>>>  9 files changed, 20 insertions(+), 17 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>>> index 9b1efdf94bdf..05875279c09e 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>>>> @@ -164,6 +164,7 @@ extern int amdgpu_async_gfx_ring;
>>>>  extern int amdgpu_mcbp;
>>>>  extern int amdgpu_discovery;
>>>>  extern int amdgpu_mes;
>>>> +extern int amdgpu_noretry;
>>>>  
>>>>  #ifdef CONFIG_DRM_AMDGPU_SI
>>>>  extern int amdgpu_si_support;
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>>> index 7cf6ab07b113..0d578d95be93 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>>>> @@ -140,6 +140,7 @@ int amdgpu_async_gfx_ring = 1;
>>>>  int amdgpu_mcbp = 0;
>>>>  int amdgpu_discovery = 0;
>>>>  int amdgpu_mes = 0;
>>>> +int amdgpu_noretry;
>>>>  
>>>>  struct amdgpu_mgpu_info mgpu_info = {
>>>>.mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
>>>> @@ -591,6 +592,10 @@ MODULE_PARM_DESC(mes,
>>>>"Enable Micro Engine Scheduler (0 = disabled (default), 1 = 
>>>> enabled)");
>>>>  module_param_named(mes, amdgpu_mes, int, 0444);
>>>>  
>>>> +MODULE_PARM_DESC(noretry,
>>>> +  "Disable retry faults (0 = retry enabled (default), 1 = retry 
>>>> disabled)");
>>>> +module_param_named(noretry, amdgpu_noretry, int, 0644);
>>>> +
>>>>  #ifdef CONFIG_HSA_AMD
>>>>  /**
>>>>   * DOC: sched_policy (int)
>>>> @@ -666,17 +671,6 @@ module_param(ignore_crat, int, 0444);
>>>>  MODULE_PARM_DESC(ignore_crat,
>>>>"Ignore CRAT table during KFD initialization (0 = use CRAT 
>>>> (default), 1 = ignore CRAT)");
>>>>  
>>>> -/**
>>>> - * DOC: noretry (int)
>>>> - * This

Re: [PATCH 1/1] drm/amdkfd: Consistently apply noretry setting

2019-07-03 Thread Yang, Philip
amdgpu_noretry default value is 0, this will generate VM fault storm 
because the vm fault is not recovered. It may slow down the machine and 
need reboot after application VM fault. Maybe change default value to 1?

Other than that, this is reviewed by Philip Yang 

On 2019-07-02 3:05 p.m., Kuehling, Felix wrote:
> Ping.
> 
> Christian, Philip, any opinion about this patch?
> 
> On 2019-06-21 8:20 p.m., Kuehling, Felix wrote:
>> Apply the same setting to SH_MEM_CONFIG and VM_CONTEXT1_CNTL. This
>> makes the noretry param no longer KFD-specific. On GFX10 I'm not
>> changing SH_MEM_CONFIG in this commit because GFX10 has different
>> retry behaviour in the SQ and I don't have a way to test it at the
>> moment.
>>
>> Suggested-by: Christian König 
>> CC: Philip Yang 
>> Signed-off-by: Felix Kuehling 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu.h  |  1 +
>>drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 16 +---
>>drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c|  4 
>>drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c |  3 ++-
>>drivers/gpu/drm/amd/amdgpu/gfxhub_v2_0.c |  3 ++-
>>drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c  |  3 ++-
>>drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c  |  3 ++-
>>.../drm/amd/amdkfd/kfd_device_queue_manager_v9.c |  2 +-
>>drivers/gpu/drm/amd/amdkfd/kfd_priv.h|  2 +-
>>9 files changed, 20 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> index 9b1efdf94bdf..05875279c09e 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
>> @@ -164,6 +164,7 @@ extern int amdgpu_async_gfx_ring;
>>extern int amdgpu_mcbp;
>>extern int amdgpu_discovery;
>>extern int amdgpu_mes;
>> +extern int amdgpu_noretry;
>>
>>#ifdef CONFIG_DRM_AMDGPU_SI
>>extern int amdgpu_si_support;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> index 7cf6ab07b113..0d578d95be93 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
>> @@ -140,6 +140,7 @@ int amdgpu_async_gfx_ring = 1;
>>int amdgpu_mcbp = 0;
>>int amdgpu_discovery = 0;
>>int amdgpu_mes = 0;
>> +int amdgpu_noretry;
>>
>>struct amdgpu_mgpu_info mgpu_info = {
>>  .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
>> @@ -591,6 +592,10 @@ MODULE_PARM_DESC(mes,
>>  "Enable Micro Engine Scheduler (0 = disabled (default), 1 = enabled)");
>>module_param_named(mes, amdgpu_mes, int, 0444);
>>
>> +MODULE_PARM_DESC(noretry,
>> +"Disable retry faults (0 = retry enabled (default), 1 = retry 
>> disabled)");
>> +module_param_named(noretry, amdgpu_noretry, int, 0644);
>> +
>>#ifdef CONFIG_HSA_AMD
>>/**
>> * DOC: sched_policy (int)
>> @@ -666,17 +671,6 @@ module_param(ignore_crat, int, 0444);
>>MODULE_PARM_DESC(ignore_crat,
>>  "Ignore CRAT table during KFD initialization (0 = use CRAT (default), 1 
>> = ignore CRAT)");
>>
>> -/**
>> - * DOC: noretry (int)
>> - * This parameter sets sh_mem_config.retry_disable. Default value, 0, 
>> enables retry.
>> - * Setting 1 disables retry.
>> - * Retry is needed for recoverable page faults.
>> - */
>> -int noretry;
>> -module_param(noretry, int, 0644);
>> -MODULE_PARM_DESC(noretry,
>> -"Set sh_mem_config.retry_disable on Vega10 (0 = retry enabled 
>> (default), 1 = retry disabled)");
>> -
>>/**
>> * DOC: halt_if_hws_hang (int)
>> * Halt if HWS hang is detected. Default value, 0, disables the halt on 
>> hang.
>> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c 
>> b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
>> index e0f3014e76ea..c4e715170bfe 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
>> @@ -1938,11 +1938,15 @@ static void gfx_v9_0_constants_init(struct 
>> amdgpu_device *adev)
>>  if (i == 0) {
>>  tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
>>  SH_MEM_ALIGNMENT_MODE_UNALIGNED);
>> +tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
>> +!!amdgpu_noretry);
>>  WREG32_SOC15_RLC(GC, 0, mmSH_MEM_CONFIG, tmp);
>>  WREG32_SOC15_RLC(GC, 0, mmSH_MEM_BASES, 0);
>>  } else {
>>  tmp = REG_SET_FIELD(0, SH_MEM_CONFIG, ALIGNMENT_MODE,
>>  SH_MEM_ALIGNMENT_MODE_UNALIGNED);
>> +tmp = REG_SET_FIELD(tmp, SH_MEM_CONFIG, RETRY_DISABLE,
>> +!!amdgpu_noretry);
>>  WREG32_SOC15_RLC(GC, 0, mmSH_MEM_CONFIG, tmp);
>>  tmp = REG_SET_FIELD(0, SH_MEM_BASES, PRIVATE_BASE,
>>  (adev->gmc.private_aperture_start >> 

[PATCH] drm/amdgpu: improve HMM error -ENOMEM and -EBUSY handling

2019-06-14 Thread Yang, Philip
Under memory pressure, hmm_range_fault may return error code -ENOMEM
or -EBUSY, change pr_info to pr_debug to remove unnecessary kernel log
message because we will retry restore again.

Call get_user_pages_done if TTM get user pages failed will have
WARN_ONCE kernel calling stack dump log.

Change-Id: I086f92944630f9d1a70365c00417cb9440662464
Signed-off-by: Philip Yang 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 38 +++
 1 file changed, 6 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 74e86952553f..10abae398e51 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1731,35 +1731,17 @@ static int update_invalid_user_pages(struct 
amdkfd_process_info *process_info,
ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm,
   bo->tbo.ttm->pages);
if (ret) {
-   bo->tbo.ttm->pages[0] = NULL;
-   pr_info("%s: Failed to get user pages: %d\n",
+   pr_debug("%s: Failed to get user pages: %d\n",
__func__, ret);
-   /* Pretend it succeeded. It will fail later
-* with a VM fault if the GPU tries to access
-* it. Better than hanging indefinitely with
-* stalled user mode queues.
-*/
-   }
-   }
-
-   return 0;
-}
 
-/* Remove invalid userptr BOs from hmm track list
- *
- * Stop HMM track the userptr update
- */
-static void untrack_invalid_user_pages(struct amdkfd_process_info 
*process_info)
-{
-   struct kgd_mem *mem, *tmp_mem;
-   struct amdgpu_bo *bo;
+   /* Return error -EBUSY or -ENOMEM, retry restore */
+   return ret;
+   }
 
-   list_for_each_entry_safe(mem, tmp_mem,
-_info->userptr_inval_list,
-validate_list.head) {
-   bo = mem->bo;
amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
}
+
+   return 0;
 }
 
 /* Validate invalid userptr BOs
@@ -1841,13 +1823,6 @@ static int validate_invalid_user_pages(struct 
amdkfd_process_info *process_info)
list_move_tail(>validate_list.head,
   _info->userptr_valid_list);
 
-   /* Stop HMM track the userptr update. We dont check the return
-* value for concurrent CPU page table update because we will
-* reschedule the restore worker if process_info->evicted_bos
-* is updated.
-*/
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-
/* Update mapping. If the BO was not validated
 * (because we couldn't get user pages), this will
 * clear the page table entries, which will result in
@@ -1946,7 +1921,6 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct 
work_struct *work)
}
 
 unlock_out:
-   untrack_invalid_user_pages(process_info);
mutex_unlock(_info->lock);
mmput(mm);
put_task_struct(usertask);
-- 
2.17.1

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

Re: [PATCH 1/4] Revert "drm/amdkfd: Fix sdma queue allocate race condition"

2019-06-14 Thread Yang, Philip
I just figured out previous patch have issue. New patch is simple and 
looks good to me.

This series is Reviewed-by: Philip.Yang 

On 2019-06-14 9:27 p.m., Zeng, Oak wrote:
> This reverts commit 0a7c7281bdaae8cf63d77be26a4b46128114bdec.
> This fix is not proper. allocate_mqd can't be moved before
> allocate_sdma_queue as it depends on q->properties->sdma_id
> set in later.
> 
> Change-Id: If4934afebda8cf37dfcde9b50ce53643d526584d
> Signed-off-by: Oak Zeng 
> ---
>   .../gpu/drm/amd/amdkfd/kfd_device_queue_manager.c  | 26 
> --
>   1 file changed, 14 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
> b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> index 250798b..d566c26 100644
> --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
> @@ -1133,27 +1133,23 @@ static int create_queue_cpsch(struct 
> device_queue_manager *dqm, struct queue *q,
>   if (dqm->total_queue_count >= max_num_of_queues_per_device) {
>   pr_warn("Can't create new usermode queue because %d queues were 
> already created\n",
>   dqm->total_queue_count);
> - return -EPERM;
> + retval = -EPERM;
> + goto out;
>   }
>   
> - mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
> - q->properties.type)];
> - q->mqd_mem_obj = mqd_mgr->allocate_mqd(mqd_mgr->dev, >properties);
> - if (!q->mqd_mem_obj)
> - return -ENOMEM;
> -
> - dqm_lock(dqm);
>   if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
>   q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) {
>   retval = allocate_sdma_queue(dqm, q);
>   if (retval)
> - goto out_unlock;
> + goto out;
>   }
>   
>   retval = allocate_doorbell(qpd, q);
>   if (retval)
>   goto out_deallocate_sdma_queue;
>   
> + mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type(
> + q->properties.type)];
>   /*
>* Eviction state logic: mark all queues as evicted, even ones
>* not currently active. Restoring inactive queues later only
> @@ -1165,8 +1161,14 @@ static int create_queue_cpsch(struct 
> device_queue_manager *dqm, struct queue *q,
>   dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
>   q->properties.tba_addr = qpd->tba_addr;
>   q->properties.tma_addr = qpd->tma_addr;
> + q->mqd_mem_obj = mqd_mgr->allocate_mqd(mqd_mgr->dev, >properties);
> + if (!q->mqd_mem_obj) {
> + retval = -ENOMEM;
> + goto out_deallocate_doorbell;
> + }
>   mqd_mgr->init_mqd(mqd_mgr, >mqd, q->mqd_mem_obj,
>   >gart_mqd_addr, >properties);
> + dqm_lock(dqm);
>   
>   list_add(>list, >queues_list);
>   qpd->queue_count++;
> @@ -1192,13 +1194,13 @@ static int create_queue_cpsch(struct 
> device_queue_manager *dqm, struct queue *q,
>   dqm_unlock(dqm);
>   return retval;
>   
> +out_deallocate_doorbell:
> + deallocate_doorbell(qpd, q);
>   out_deallocate_sdma_queue:
>   if (q->properties.type == KFD_QUEUE_TYPE_SDMA ||
>   q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
>   deallocate_sdma_queue(dqm, q);
> -out_unlock:
> - dqm_unlock(dqm);
> - mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
> +out:
>   return retval;
>   }
>   
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: Need to set the baco cap before baco reset

2019-06-14 Thread Yang, Philip
Hi Emily,

I am not familiar with vbios and driver init part, just based on my 
experience, the patch don't modify amdgpu_get_bios but move 
amdgpu_get_bios to amdgpu_device_ip_early_init from amdgpu_device_init, 
so amdgpu_get_bios is executed earlier. The kernel error message "BUG: 
kernel NULL pointer dereference" means something is not initialized. 
Please review the change. This issue blocks rocm release now.

Regards,
Philip

On 2019-06-13 11:19 p.m., Deng, Emily wrote:
> Hi Russell,
>   This patch will read vbios, and parse vbios to get the baco reset 
> feature bit.  From the call trace, it shows error in " amdgpu_get_bios ", but 
> this patch don't modify amdgpu_get_bios, and code before amdgpu_get_bios. 
> Please first check why it will has error when read vbios.
> 
> Best wishes
> Emily Deng
> 
> 
> 
>> -Original Message-
>> From: Russell, Kent 
>> Sent: Thursday, June 13, 2019 7:11 PM
>> To: Quan, Evan ; Deng, Emily
>> ; amd-gfx@lists.freedesktop.org
>> Cc: Deng, Emily 
>> Subject: RE: [PATCH] drm/amdgpu: Need to set the baco cap before baco reset
>>
>> Hi Emily,
>>
>> This patch caused a regression on MI25 (Chip 6860, VBIOS 113-D0513700-001)
>> machines where the driver would not boot. Note that this was not seen on
>> Vega10 Frontier (Chip 6863, VBIOS 113-D0501100-X09) or Radeon64 (Chip
>> 697f). Reverting this patch resolved the issue with no other work required 
>> and
>> was confirmed on all 3 machines.
>>
>> Here is the dmesg:
>>
>> [3.908653] amdgpu :23:00.0: BAR 6: can't assign [??? 0x flags
>> 0x2000] (bogus alignment)
>> [3.908692] BUG: kernel NULL pointer dereference, address:
>> 0008
>> [3.908716] #PF: supervisor read access in kernel mode
>> [3.908734] #PF: error_code(0x) - not-present page
>> [3.908753] PGD 0 P4D 0
>> [3.908767] Oops:  [#1] SMP NOPTI
>> [3.909293] CPU: 8 PID: 409 Comm: kworker/8:1 Not tainted 5.2.0-rc1-kfd-
>> compute-roc-master-10734 #1
>> [3.909753] Hardware name: Inventec P47  
>> WC2071019001
>> /P47 , BIOS 0.64 04/09/2018
>> [3.910534] Workqueue: events work_for_cpu_fn
>> [3.910953] RIP: 0010:amdgpu_get_bios+0x3aa/0x580 [amdgpu]
>> [3.911314] Code: c0 48 c7 44 24 5c 00 00 00 00 48 c7 84 24 90 00 00 00 
>> 00 00
>> 00 00 48 89 d9 48 29 f9 83 c1 3c c1 e9 03 f3 48 ab 49 8b 44 24 38 <48> 8b 40 
>> 08
>> 48 85 c0 74 24 ba 3c 00 00 00 48 89 de 4c 89 e7 ff d0
>> [3.912069] RSP: 0018:a27dce28fc50 EFLAGS: 00010212
>> [3.912502] RAX:  RBX: a27dce28fcac RCX:
>> 
>> [3.912980] RDX:  RSI: 0082 RDI:
>> a27dce28fce8
>> [3.913467] RBP:  R08: 0001 R09:
>> 079a
>> [3.913940] R10:  R11: 0001 R12:
>> 88d657af
>> [3.914349] R13: c0c38120 R14: a27dce28fc68 R15:
>> 88d657af
>> [3.914767] FS:  () GS:88d65f40()
>> knlGS:
>> [3.915203] CS:  0010 DS:  ES:  CR0: 80050033
>> [3.915637] CR2: 0008 CR3: 003e7540a000 CR4:
>> 003406e0
>> [3.916075] Call Trace:
>> [3.916522]  ? pcie_capability_clear_and_set_word+0x53/0x80
>> [3.917014]  amdgpu_device_init+0x923/0x1820 [amdgpu]
>> [3.917515]  amdgpu_driver_load_kms+0x71/0x310 [amdgpu]
>> [3.917997]  drm_dev_register+0x113/0x1a0 [drm]
>> [3.918514]  amdgpu_pci_probe+0xb8/0x150 [amdgpu]
>> [3.919003]  ? __pm_runtime_resume+0x54/0x70
>> [3.919270] usb 1-2: New USB device found, idVendor=14dd, idProduct=1005,
>> bcdDevice= 0.00
>> [3.919498]  local_pci_probe+0x3d/0x90
>> [3.919503]  ? __schedule+0x3de/0x690
>> [3.920374] usb 1-2: New USB device strings: Mfr=1, Product=2,
>> SerialNumber=3
>> [3.921137]  work_for_cpu_fn+0x10/0x20
>> [3.922028] usb 1-2: Product: D2CIM-VUSB
>> [3.922815]  process_one_work+0x159/0x3e0
>> [3.923633] usb 1-2: Manufacturer: Raritan
>> [3.923635] usb 1-2: SerialNumber: EFFB212D0A6E32F
>> [3.924416]  worker_thread+0x22b/0x440
>> [3.924419]  ? rescuer_thread+0x350/0x350
>> [3.927812]  kthread+0xf6/0x130
>> [3.928157] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
>> [3.928365]  ? kthread_destroy_worker+0x40/0x40
>> [3.929401] ata1.00: ATA-10: INTEL SSDSC2KG960G7, SCV10100, max
>> UDMA/133
>> [3.930101]  ret_from_fork+0x1f/0x30
>> [3.930103] Modules linked in: amdgpu(+) crct10dif_pclmul crc32_pclmul
>> ghash_clmulni_intel ast amd_iommu_v2 aesni_intel gpu_sched i2c_algo_bit
>> aes_x86_64 ttm crypto_simd drm_kms_helper cryptd glue_helper
>> syscopyarea sysfillrect ahci sysimgblt libahci fb_sys_fops ixgbe(+) drm dca
>> mdio
>> [3.930965] ata1.00: 1875385008 sectors, multi 1: LBA48 NCQ (depth 32)
>> [3.931085] ata1.00: configured for UDMA/133
>> [3.931809] CR2: 0008
>> [3.934723] 

Re: [PATCH] drm/amdgpu: only use kernel zone if need_dma32 is not required

2019-06-13 Thread Yang, Philip

On 2019-06-13 4:54 a.m., Koenig, Christian wrote:
> Am 12.06.19 um 23:13 schrieb Yang, Philip:
>> On 2019-06-12 3:28 p.m., Christian König wrote:
>>> Am 12.06.19 um 17:13 schrieb Yang, Philip:
>>>> TTM create two zones, kernel zone and dma32 zone for system memory. If
>>>> system memory address allocated is below 4GB, this account to dma32 zone
>>>> and will exhaust dma32 zone and trigger unnesssary TTM eviction.
>>>>
>>>> Patch "drm/ttm: Account for kernel allocations in kernel zone only" only
>>>> handle the allocation for acc_size, the system memory page allocation is
>>>> through ttm_mem_global_alloc_page which still account to dma32 zone if
>>>> page is below 4GB.
>>> NAK, as the name says the mem_glob is global for all devices in the system.
>>>
>>> So this will break if you mix DMA32 and non DMA32 in the same system
>>> which is exactly the configuration my laptop here has :(
>>>
>> I didn't find path use dma32 zone, but I may missed something.
> 
> Well the point is there is non in our driver, but many drivers in the
> system still need DMA32 memory.
> 
>> There is
>> an issue found by KFDTest.BigBufStressTest, it allocates buffers up to
>> 3/8 of total 256GB system memory, each buffer size is 128MB, then use
>> queue to write to the buffers. If ttm_mem_global_alloc_page get page pfn
>> is below 4GB, it account to dma32 zone and will exhaust 2GB limit, then
>> ttm_check_swapping will schedule ttm_shrink_work to start eviction. It
>> takes minutes to finish restore (retry many times if busy), the test
>> failed because queue timeout. This eviction is unnecessary because we
>> still have enough free system memory.
> 
> No that is definitely necessary. For example on my Laptop it's the sound
> system which needs DMA32.
> 
> Without this when an application uses a lot of memory we run into the
> OOM killer as soon as some audio starts playing.
>
I did not realize TTM is used by other drivers. I agree we cannot remove 
dma32 zone, this will break other device drivers which depends on dma32 
zone.

>> It's random case, happens about 1/5. I can change test to increase the
>> timeout value to workaround this, but this seems TTM bug. This will slow
>> application performance a lot if this random issue happens.
> 
> One thing we could try is to dig into why the kernel gives us DMA32
> pages when there are still other pages available. Please take a look at
> /proc/buddyinfo on that box for this.
>
Thanks for the advise, from buddyinfo, the machine has 4 nodes, each 
node has 64GB memory, and dma32 zone is on node 0. BigBufStressTest 
allocate 96GB. If I force the test on node 1, "numactl --cpunodebind=1 
./kfdtest", no eviction at all. If I force the test on node 0, it always 
has eviction and restore because it used up all memory including dma32 
zone from node 0. I will change test app to avoid running on node 0 to 
workaround this.

Thanks,
Philip

> The next thing coming to mind is that we can most likely completely skip
> this if IOMMU is active.
> 
> The last thing of hand coming to my mind is to improve TTM to actually
> only evict BOs which use DMA32 memory, cause currently we just evict
> stuff randomly and not check if its DMA32 or other memory.
> 
> Regards,
> Christian.
> 
>>
>> Thanks,
>> Philip
>>
>>
>>> Christian.
>>>
>>>> Change-Id: I289b85d891b8f64a1422c42b1eab398098ab7ef7
>>>> Signed-off-by: Philip Yang 
>>>> ---
>>>>     drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 
>>>>     1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> index 2778ff63d97d..79bb9dfe617b 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>>>> @@ -1686,6 +1686,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>>>     }
>>>>     adev->mman.initialized = true;
>>>> +    /* Only kernel zone (no dma32 zone) if device does not require
>>>> dma32 */
>>>> +    if (!adev->need_dma32)
>>>> +    adev->mman.bdev.glob->mem_glob->num_zones = 1;
>>>> +
>>>>     /* We opt to avoid OOM on system pages allocations */
>>>>     adev->mman.bdev.no_retry = true;
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH v2 hmm 00/11] Various revisions from a locking/code review

2019-06-12 Thread Yang, Philip
Rebase to https://github.com/jgunthorpe/linux.git hmm branch, need some 
changes because of interface hmm_range_register change. Then run a quick 
amdgpu_test. Test is finished, result is ok. But there is below kernel 
BUG message, seems hmm_free_rcu calls down_write.

[ 1171.919921] BUG: sleeping function called from invalid context at 
/home/yangp/git/compute_staging/kernel/kernel/locking/rwsem.c:65
[ 1171.919933] in_atomic(): 1, irqs_disabled(): 0, pid: 53, name: 
kworker/1:1
[ 1171.919938] 2 locks held by kworker/1:1/53:
[ 1171.919940]  #0: 1c7c19d4 ((wq_completion)rcu_gp){+.+.}, at: 
process_one_work+0x20e/0x630
[ 1171.919951]  #1: 923f2cfa 
((work_completion)(>work)){+.+.}, at: process_one_work+0x20e/0x630
[ 1171.919959] CPU: 1 PID: 53 Comm: kworker/1:1 Tainted: GW 
5.2.0-rc1-kfd-yangp #196
[ 1171.919961] Hardware name: ASUS All Series/Z97-PRO(Wi-Fi ac)/USB 3.1, 
BIOS 9001 03/07/2016
[ 1171.919965] Workqueue: rcu_gp srcu_invoke_callbacks
[ 1171.919968] Call Trace:
[ 1171.919974]  dump_stack+0x67/0x9b
[ 1171.919980]  ___might_sleep+0x149/0x230
[ 1171.919985]  down_write+0x1c/0x70
[ 1171.919989]  hmm_free_rcu+0x24/0x80
[ 1171.919993]  srcu_invoke_callbacks+0xc9/0x150
[ 1171.92]  process_one_work+0x28e/0x630
[ 1171.920008]  worker_thread+0x39/0x3f0
[ 1171.920014]  ? process_one_work+0x630/0x630
[ 1171.920017]  kthread+0x11c/0x140
[ 1171.920021]  ? kthread_park+0x90/0x90
[ 1171.920026]  ret_from_fork+0x24/0x30

Philip

On 2019-06-12 1:54 p.m., Kuehling, Felix wrote:
> [+Philip]
> 
> Hi Jason,
> 
> I'm out of the office this week.
> 
> Hi Philip, can you give this a go? Not sure how much you've been
> following this patch series review. Message or call me on Skype to
> discuss any questions.
> 
> Thanks,
>     Felix
> 
> On 2019-06-11 12:48, Jason Gunthorpe wrote:
>> On Thu, Jun 06, 2019 at 03:44:27PM -0300, Jason Gunthorpe wrote:
>>> From: Jason Gunthorpe 
>>>
>>> For hmm.git:
>>>
>>> This patch series arised out of discussions with Jerome when looking at the
>>> ODP changes, particularly informed by use after free races we have already
>>> found and fixed in the ODP code (thanks to syzkaller) working with mmu
>>> notifiers, and the discussion with Ralph on how to resolve the lifetime 
>>> model.
>>>
>>> Overall this brings in a simplified locking scheme and easy to explain
>>> lifetime model:
>>>
>>>If a hmm_range is valid, then the hmm is valid, if a hmm is valid then 
>>> the mm
>>>is allocated memory.
>>>
>>>If the mm needs to still be alive (ie to lock the mmap_sem, find a vma, 
>>> etc)
>>>then the mmget must be obtained via mmget_not_zero().
>>>
>>> Locking of mm->hmm is shifted to use the mmap_sem consistently for all
>>> read/write and unlocked accesses are removed.
>>>
>>> The use unlocked reads on 'hmm->dead' are also eliminated in favour of using
>>> standard mmget() locking to prevent the mm from being released. Many of the
>>> debugging checks of !range->hmm and !hmm->mm are dropped in favour of 
>>> poison -
>>> which is much clearer as to the lifetime intent.
>>>
>>> The trailing patches are just some random cleanups I noticed when reviewing
>>> this code.
>>>
>>> This v2 incorporates alot of the good off list changes & feedback Jerome 
>>> had,
>>> and all the on-list comments too. However, now that we have the shared git I
>>> have kept the one line change to nouveau_svm.c rather than the compat
>>> funtions.
>>>
>>> I believe we can resolve this merge in the DRM tree now and keep the core
>>> mm/hmm.c clean. DRM maintainers, please correct me if I'm wrong.
>>>
>>> It is on top of hmm.git, and I have a git tree of this series to ease 
>>> testing
>>> here:
>>>
>>> https://github.com/jgunthorpe/linux/tree/hmm
>>>
>>> There are still some open locking issues, as I think this remains 
>>> unaddressed:
>>>
>>> https://lore.kernel.org/linux-mm/20190527195829.gb18...@mellanox.com/
>>>
>>> I'm looking for some more acks, reviews and tests so this can move ahead to
>>> hmm.git.
>> AMD Folks, this is looking pretty good now, can you please give at
>> least a Tested-by for the new driver code using this that I see in
>> linux-next?
>>
>> Thanks,
>> Jason
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: only use kernel zone if need_dma32 is not required

2019-06-12 Thread Yang, Philip

On 2019-06-12 3:28 p.m., Christian König wrote:
> Am 12.06.19 um 17:13 schrieb Yang, Philip:
>> TTM create two zones, kernel zone and dma32 zone for system memory. If
>> system memory address allocated is below 4GB, this account to dma32 zone
>> and will exhaust dma32 zone and trigger unnesssary TTM eviction.
>>
>> Patch "drm/ttm: Account for kernel allocations in kernel zone only" only
>> handle the allocation for acc_size, the system memory page allocation is
>> through ttm_mem_global_alloc_page which still account to dma32 zone if
>> page is below 4GB.
> 
> NAK, as the name says the mem_glob is global for all devices in the system.
> 
> So this will break if you mix DMA32 and non DMA32 in the same system 
> which is exactly the configuration my laptop here has :(
>
I didn't find path use dma32 zone, but I may missed something. There is 
an issue found by KFDTest.BigBufStressTest, it allocates buffers up to 
3/8 of total 256GB system memory, each buffer size is 128MB, then use 
queue to write to the buffers. If ttm_mem_global_alloc_page get page pfn 
is below 4GB, it account to dma32 zone and will exhaust 2GB limit, then 
ttm_check_swapping will schedule ttm_shrink_work to start eviction. It 
takes minutes to finish restore (retry many times if busy), the test 
failed because queue timeout. This eviction is unnecessary because we 
still have enough free system memory.

It's random case, happens about 1/5. I can change test to increase the 
timeout value to workaround this, but this seems TTM bug. This will slow 
application performance a lot if this random issue happens.

Thanks,
Philip


> Christian.
> 
>>
>> Change-Id: I289b85d891b8f64a1422c42b1eab398098ab7ef7
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 2778ff63d97d..79bb9dfe617b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1686,6 +1686,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>   }
>>   adev->mman.initialized = true;
>> +    /* Only kernel zone (no dma32 zone) if device does not require 
>> dma32 */
>> +    if (!adev->need_dma32)
>> +    adev->mman.bdev.glob->mem_glob->num_zones = 1;
>> +
>>   /* We opt to avoid OOM on system pages allocations */
>>   adev->mman.bdev.no_retry = true;
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH] drm/amdgpu: only use kernel zone if need_dma32 is not required

2019-06-12 Thread Yang, Philip
That's kind of hack because dma32 zone is not needed, it has bad effect 
to trigger unnecessary eviction for KFDTest.BigBufStressTest. But 
ttm_bo_global_init->ttm_mem_global_init always create dma32 zone without 
accepting any parameter.

To avoid ttm_mem_global_alloc_page account to dma32 zone, another option 
is to add a new flag to ttm_operation_ctx->flags, that looks not good 
either.

Thanks,
Philip

On 2019-06-12 1:23 p.m., Kuehling, Felix wrote:
> TTM itself has some logic for need_dma32 and TTM_PAGE_FLAG_DMA32. I
> believe that should already handle this. need_dma32 is passed from
> amdgpu to ttm_bo_device_init to bdev->need_dma32. ttm_tt_create
> translates that to page_flags |= TTM_PAGE_FLAG_DMA32 and passes that to
> bdev->driver->ttm_tt_create. The two page allocators in ttm_page_alloc.c
> and ttm_page_alloc_dma.c check ttm->page_flags. Is that chain broken
> somewhere? Overriding glob->mem_glob->num_zones from amdgpu seems to be
> a bit of a hack.
> 
> Regards,
>     Felix
> 
> On 2019-06-12 8:13, Yang, Philip wrote:
>> TTM create two zones, kernel zone and dma32 zone for system memory. If
>> system memory address allocated is below 4GB, this account to dma32 zone
>> and will exhaust dma32 zone and trigger unnesssary TTM eviction.
>>
>> Patch "drm/ttm: Account for kernel allocations in kernel zone only" only
>> handle the allocation for acc_size, the system memory page allocation is
>> through ttm_mem_global_alloc_page which still account to dma32 zone if
>> page is below 4GB.
>>
>> Change-Id: I289b85d891b8f64a1422c42b1eab398098ab7ef7
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 
>>1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 2778ff63d97d..79bb9dfe617b 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -1686,6 +1686,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
>>  }
>>  adev->mman.initialized = true;
>>
>> +/* Only kernel zone (no dma32 zone) if device does not require dma32 */
>> +if (!adev->need_dma32)
>> +adev->mman.bdev.glob->mem_glob->num_zones = 1;
>> +
>>  /* We opt to avoid OOM on system pages allocations */
>>  adev->mman.bdev.no_retry = true;
>>
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdgpu: only use kernel zone if need_dma32 is not required

2019-06-12 Thread Yang, Philip
TTM create two zones, kernel zone and dma32 zone for system memory. If
system memory address allocated is below 4GB, this account to dma32 zone
and will exhaust dma32 zone and trigger unnesssary TTM eviction.

Patch "drm/ttm: Account for kernel allocations in kernel zone only" only
handle the allocation for acc_size, the system memory page allocation is
through ttm_mem_global_alloc_page which still account to dma32 zone if
page is below 4GB.

Change-Id: I289b85d891b8f64a1422c42b1eab398098ab7ef7
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 2778ff63d97d..79bb9dfe617b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1686,6 +1686,10 @@ int amdgpu_ttm_init(struct amdgpu_device *adev)
}
adev->mman.initialized = true;
 
+   /* Only kernel zone (no dma32 zone) if device does not require dma32 */
+   if (!adev->need_dma32)
+   adev->mman.bdev.glob->mem_glob->num_zones = 1;
+
/* We opt to avoid OOM on system pages allocations */
adev->mman.bdev.no_retry = true;
 
-- 
2.17.1

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

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

2019-06-04 Thread Yang, Philip
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 
---
 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_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 (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 : range->flags[HMM_PFN_WRITE];
+   range->pfn_flags_mask = 0;
+   range->pfns = pfns;
+   hmm_range_register(range, mm, start,
+  start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
 
-   f = 

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;
>

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

2019-06-03 Thread Yang, Philip
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

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 (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);
+   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 = pfns;
+   hmm_range_register(range, mm, start,
+  start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
 
-   f = ranges[0].flags[HMM_PFN_VALID];
-   f |= 

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-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

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

2019-05-31 Thread Yang, Philip
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 : range->flags[HMM_PFN_WRITE];
+   range->pfn_flags_mask = 0;
+   range->pfns = pfns;
+   hmm_range_register(range, mm, start,
+  start + ttm->num_pages * 

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

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

2019-05-30 Thread Yang, Philip
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);
+   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 = pfns;
+   hmm_range_register(range, mm, start,
+  start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
 
-   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);
-
-   for (nr_pages = 0, i 

Re: [PATCH 1/1] drm/amdgpu: Improve error handling for HMM

2019-05-09 Thread Yang, Philip
On 2019-05-07 5:52 p.m., Kuehling, Felix wrote:
> Use unsigned long for number of pages.
> 
> Check that pfns are valid after hmm_vma_fault. If they are not,
> return an error instead of continuing with invalid page pointers and
> PTEs.
> 
> Signed-off-by: Felix Kuehling 

Reviewed-by: Philip Yang 

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 22 ++
>   1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index c14198737dcd..38ce11e338e0 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -734,10 +734,11 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   struct mm_struct *mm = gtt->usertask->mm;
>   unsigned long start = gtt->userptr;
>   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
> - struct hmm_range *ranges;
>   struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
> + struct hmm_range *ranges;
> + unsigned long nr_pages, i;
>   uint64_t *pfns, f;
> - int r = 0, i, nr_pages;
> + int r = 0;
>   
>   if (!mm) /* Happens during process shutdown */
>   return -ESRCH;
> @@ -813,8 +814,14 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   
>   up_read(>mmap_sem);
>   
> - for (i = 0; i < ttm->num_pages; i++)
> + for (i = 0; i < ttm->num_pages; i++) {
>   pages[i] = hmm_pfn_to_page([0], pfns[i]);
> + if (!pages[i]) {
> + pr_err("Page fault failed for pfn[%lu] = 0x%llx\n",
> +i, pfns[i]);
> + goto out_invalid_pfn;
> + }
> + }
>   gtt->ranges = ranges;
>   
>   return 0;
> @@ -827,6 +834,13 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, 
> struct page **pages)
>   up_read(>mmap_sem);
>   
>   return r;
> +
> +out_invalid_pfn:
> + for (i = 0; i < gtt->nr_ranges; i++)
> + hmm_vma_range_done([i]);
> + kvfree(pfns);
> + kvfree(ranges);
> + return -ENOMEM;
>   }
>   
>   /**
> @@ -871,7 +885,7 @@ bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
>*/
>   void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages)
>   {
> - unsigned i;
> + unsigned long i;
>   
>   for (i = 0; i < ttm->num_pages; ++i)
>   ttm->pages[i] = pages ? pages[i] : NULL;
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm: increase drm mmap_range size to 1TB

2019-04-17 Thread Yang, Philip
After patch "drm: Use the same mmap-range offset and size for GEM and
TTM", application failed to create bo of system memory because drm
mmap_range size decrease to 64GB from original 1TB. This is not big
enough for applications. Increase the drm mmap_range size to 1TB.

Change-Id: Id482af261f56f3289e8873f5985078da599a0998
Signed-off-by: Philip Yang 
---
 include/drm/drm_vma_manager.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
index f4f8ff1cdeec..76ac5e97a559 100644
--- a/include/drm/drm_vma_manager.h
+++ b/include/drm/drm_vma_manager.h
@@ -35,7 +35,7 @@
  */
 #if BITS_PER_LONG == 64
 #define DRM_FILE_PAGE_OFFSET_START ((0xUL >> PAGE_SHIFT) + 1)
-#define DRM_FILE_PAGE_OFFSET_SIZE ((0xUL >> PAGE_SHIFT) * 16)
+#define DRM_FILE_PAGE_OFFSET_SIZE ((0xUL >> PAGE_SHIFT) * 256)
 #else
 #define DRM_FILE_PAGE_OFFSET_START ((0xFFFUL >> PAGE_SHIFT) + 1)
 #define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFUL >> PAGE_SHIFT) * 16)
-- 
2.17.1

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

Re: Userptr broken with the latest amdgpu driver

2019-04-08 Thread Yang, Philip
Hi Marek,

I guess you are using old kernel config with 5.x kernel, and the kernel 
config option CONFIG_HMM is missing because the dependency option 
CONFIG_ZONE_DEVICE is missing in old config file. Please update your 
kernel config file to enable option CONFIG_ZONE_DEVICE.

You should have this message in dmesg log:

"HMM_MIRROR kernel config option is not enabled, "
"add CONFIG_ZONE_DEVICE=y in config file to fix

Philip


On 2019-04-08 4:46 p.m., Marek Olšák wrote:
> Hi,
> 
> amdgpu_mn_register fails with -ENODEV in amdgpu_gem_userptr_ioctl.
> 
> The regression happened within the last 1-2 months.
> 
> Marek
> 
> ___
> 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: kernel errors with HMM enabled

2019-03-14 Thread Yang, Philip
Hi Tom,

Yes, we are missing some HMM fixes/changes from 5.1, but the crash log 
seems not related to those fixes/changes in 5.1.

I did see the similar crash log in __mmu_notifier_release path that 
should be fixed by the patch "use reference counting for HMM struct" as 
Alex mentioned. Since you have applied that patch, this could be another 
new issue.

May you provide steps how to reproduce the issue while running piglit?

Regards,
Philip

On 2019-03-14 1:18 p.m., Michel Dänzer wrote:
> On 2019-03-14 6:10 p.m., StDenis, Tom wrote:
>> On 2019-03-14 12:37 p.m., Alex Deucher wrote:
>>> Make sure you have this patch:
>>> https://cgit.freedesktop.org/~agd5f/linux/commit/?h=drm-next-5.2-wip=e811b0a799981eaa6fef1809278367471f14ba13
>>
>> Hi Alex,
>>
>> The tip of our amd-staging-drm-next includes this patch (about 126 down
>> from the tip).
> 
> amd-staging-drm-next might be missing more HMM fixes from 5.1, probably
> better to wait until we've rebased on that before spending too much more
> effort on this.
> 
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/3] drm/amdgpu: support userptr cross VMAs case with HMM v2

2019-03-12 Thread Yang, Philip
Hi Felix,

Submitted v3 to fix the potential problems with invalid userptr.

Philip

On 2019-03-12 3:30 p.m., Kuehling, Felix wrote:
> See one comment inline. There are still some potential problems that
> you're not catching.
> 
> On 2019-03-06 9:42 p.m., Yang, Philip wrote:
>> userptr may cross two VMAs if the forked child process (not call exec
>> after fork) malloc buffer, then free it, and then malloc larger size
>> buf, kerenl will create new VMA adjacent to old VMA which was cloned
>> from parent process, some pages of userptr are in the first VMA, the
>> rest pages are in the second VMA.
>>
>> HMM expects range only have one VMA, loop over all VMAs in the address
>> range, create multiple ranges to handle this case. See
>> is_mergeable_anon_vma in mm/mmap.c for details.
>>
>> Change-Id: I0ca8c77e28deabccc139906f9ffee04b7e383314
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 123 +---
>>1 file changed, 88 insertions(+), 35 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index 7cc0ba24369d..802bec7ef917 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -711,7 +711,8 @@ struct amdgpu_ttm_tt {
>>  struct task_struct  *usertask;
>>  uint32_tuserflags;
>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>> -struct hmm_rangerange;
>> +struct hmm_range*ranges;
>> +int nr_ranges;
>>#endif
>>};
>>
>> @@ -723,62 +724,105 @@ struct amdgpu_ttm_tt {
>> * once afterwards to stop HMM tracking
>> */
>>#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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
>> -struct hmm_range *range = >range;
>> -int r = 0, i;
>> +unsigned long start = gtt->userptr;
>> +unsigned long end = start + ttm->num_pages * PAGE_SIZE;
>> +struct hmm_range *ranges;
>> +struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
>> +uint64_t *pfns, f;
>> +int r = 0, i, nr_pages;
>>
>>  if (!mm) /* Happens during process shutdown */
>>  return -ESRCH;
>>
>> -amdgpu_hmm_init_range(range);
>> -
>>  down_read(>mmap_sem);
>>
>> -range->vma = find_vma(mm, gtt->userptr);
>> -if (!range_in_vma(range->vma, gtt->userptr, end))
>> -r = -EFAULT;
>> -else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
>> -range->vma->vm_file)
>> +/* user pages may cross multiple VMAs */
>> +gtt->nr_ranges = 0;
>> +do {
>> +if (gtt->nr_ranges >= MAX_NR_VMAS) {
>> +DRM_ERROR("Too many VMAs in userptr range\n");
>> +r = -EFAULT;
>> +goto out;
>> +}
>> +
>> +vma = find_vma(mm, vma ? vma->vm_end : start);
> 
> You need a check here that vma->vm_start <= the requested start address.
> Otherwise you can end up with gaps in your userptr mapping that don't
> have valid pages.
> 
> Regards,
>     Felix
> 
> 
>> +if (unlikely(!vma)) {
>> +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);
>> +
>> +if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
>> +vmas[0]->vm_file)) {
>>  r = -EPERM;
>> -if (r)
>>  goto out;
>> +}
>>
>> -range->pfns = kvmalloc_array(ttm->num_pages, sizeof(uint64_t),
>> - GFP_KERNEL);
>> -if (range->pfns == NULL) {
>> +ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
>> +if (unlikely(!ranges)) {
>>   

[PATCH 2/3] drm/amdgpu: support userptr cross VMAs case with HMM v3

2019-03-12 Thread Yang, Philip
userptr may cross two VMAs if the forked child process (not call exec
after fork) malloc buffer, then free it, and then malloc larger size
buf, kerenl will create new VMA adjacent to old VMA which was cloned
from parent process, some pages of userptr are in the first VMA, the
rest pages are in the second VMA.

HMM expects range only have one VMA, loop over all VMAs in the address
range, create multiple ranges to handle this case. See
is_mergeable_anon_vma in mm/mmap.c for details.

Change-Id: I0ca8c77e28deabccc139906f9ffee04b7e383314
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 126 +---
 1 file changed, 91 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index c1240bf243ba..c14198737dcd 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -711,7 +711,8 @@ struct amdgpu_ttm_tt {
struct task_struct  *usertask;
uint32_tuserflags;
 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-   struct hmm_rangerange;
+   struct hmm_range*ranges;
+   int nr_ranges;
 #endif
 };
 
@@ -723,62 +724,108 @@ struct amdgpu_ttm_tt {
  * once afterwards to stop HMM tracking
  */
 #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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
-   struct hmm_range *range = >range;
-   int r = 0, i;
+   unsigned long start = gtt->userptr;
+   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
+   struct hmm_range *ranges;
+   struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
+   uint64_t *pfns, f;
+   int r = 0, i, nr_pages;
 
if (!mm) /* Happens during process shutdown */
return -ESRCH;
 
-   amdgpu_hmm_init_range(range);
-
down_read(>mmap_sem);
 
-   range->vma = find_vma(mm, gtt->userptr);
-   if (!range_in_vma(range->vma, gtt->userptr, end))
-   r = -EFAULT;
-   else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
-   range->vma->vm_file)
+   /* 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);
+
+   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
+   vmas[0]->vm_file)) {
r = -EPERM;
-   if (r)
goto out;
+   }
 
-   range->pfns = kvmalloc_array(ttm->num_pages, sizeof(uint64_t),
-GFP_KERNEL);
-   if (range->pfns == NULL) {
+   ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
+   if (unlikely(!ranges)) {
r = -ENOMEM;
goto out;
}
-   range->start = gtt->userptr;
-   range->end = end;
 
-   range->pfns[0] = range->flags[HMM_PFN_VALID];
-   range->pfns[0] |= amdgpu_ttm_tt_is_readonly(ttm) ?
-   0 : range->flags[HMM_PFN_WRITE];
-   for (i = 1; i < ttm->num_pages; i++)
-   range->pfns[i] = range->pfns[0];
+   pfns = kvmalloc_array(ttm->num_pages, sizeof(*pfns), GFP_KERNEL);
+   if (unlikely(!pfns)) {
+   r = -ENOMEM;
+   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);
+
+   for (nr_pages = 0, i = 0; i < gtt->nr_ranges; i++) {
+   ranges[i].vma = vmas[i];
+   ranges[i].start = max(start, vmas[i]->vm_start);
+   ranges[i].end = min(end, vmas[i]->vm_end);
+   ranges[i].pfns = pfns + nr_pages;
+   nr_pages += (ranges[i].end - ranges[i].start) / PAGE_SIZE;
+
+   r = hmm_vma_fault([i], true);
+   if 

Re: [PATCH 3/6] drm/amdgpu: allocate VM PDs/PTs on demand

2019-03-12 Thread Yang, Philip
vm fault happens about 1/10 for KFDCWSRTest.BasicTest for me. I am using 
SDMA for page table update. I don't try CPU page table update.

Philip

On 2019-03-12 11:12 a.m., Russell, Kent wrote:
> Peculiar, I hit it immediately when I ran it . Can you try use 
> --gtest_filter=KFDCWSRTest.BasicTest  . That one hung every time for me.
> 
>   Kent
> 
>> -Original Message-
>> From: Christian König 
>> Sent: Tuesday, March 12, 2019 11:09 AM
>> To: Russell, Kent ; Koenig, Christian
>> ; Kuehling, Felix ;
>> amd-gfx@lists.freedesktop.org
>> Subject: Re: [PATCH 3/6] drm/amdgpu: allocate VM PDs/PTs on demand
>>
>> Yeah, same problem here.
>>
>> I removed libhsakmt package and installed it manually and now it seems to
>> work.
>>
>> Doing some testing now, but at least of hand I can't seem to reproduce the
>> VM fault on a Vega10.
>>
>> Christian.
>>
>> Am 12.03.19 um 16:01 schrieb Russell, Kent:
>>> Oh right, I remember that issue. I had that happen to me once, where my
>> installed libhsakmt didn't match up with the latest source code, so I ended 
>> up
>> having to remove the libhsakmt package and pointing it to the folders
>> instead.
>>>
>>>Kent
>>>
 -Original Message-
 From: Koenig, Christian
 Sent: Tuesday, March 12, 2019 10:49 AM
 To: Russell, Kent ; Kuehling, Felix
 ; amd-gfx@lists.freedesktop.org
 Subject: Re: [PATCH 3/6] drm/amdgpu: allocate VM PDs/PTs on demand

 Yeah, the problem is I do have the libhsakmt installed.

 Going to give it a try to specify the directory directly.

 Christian.

 Am 12.03.19 um 15:47 schrieb Russell, Kent:
> The README.txt file inside the tests/kfdtest folder has instructions
> on how
 to do it if you don't have the libhsakmt package installed on your system:
> export LIBHSAKMT_PATH=/*your local libhsakmt folder*/ With that, the
> headers and libraries are searched under LIBHSAKMT_PATH/include and
> LIBHSAKMT_PATH/lib respectively.
>
> So if you try export LIBHSAKMT_PATH as the root ROCT folder (the one
 containing include, src, tests, etc), then that should cover it.
> Kent
>
>
>> -Original Message-
>> From: Christian König 
>> Sent: Tuesday, March 12, 2019 9:13 AM
>> To: Russell, Kent ; Kuehling, Felix
>> ; Koenig, Christian
>> ; amd-gfx@lists.freedesktop.org
>> Subject: Re: [PATCH 3/6] drm/amdgpu: allocate VM PDs/PTs on
>> demand
>>
>> Hi guys,
>>
>> so found a few minutes today to compile kfdtest.
>>
>> Problem is that during the compile I get a lots of this:
>>> CMakeFiles/kfdtest.dir/src/BaseQueue.cpp.o: In Funktion
>>> »BaseQueue::Create(unsigned int, unsigned int, unsigned long*)«:
>>> /usr/src/ROCT-Thunk-Interface/tests/kfdtest/src/BaseQueue.cpp:57:
>>> Warnung: undefinierter Verweis auf »hsaKmtCreateQueue«
>> Any idea?
>>
>> Christian.
>>
>> Am 11.03.19 um 17:55 schrieb Christian König:
>>> Hi guys,
>>>
>>> well it's most likely some missing handling in the KFD, so I'm
>>> rather reluctant to revert the change immediately.
>>>
>>> Problem is that I don't have time right now to look into it
>>> immediately. So Kent can you continue to take a look?
>>>
>>> Sounds like its crashing immediately, so it should be something
>> obvious.
>>>
>>> Christian.
>>>
>>> Am 11.03.19 um 10:49 schrieb Russell, Kent:
 From what I've been able to dig through, the VM Fault seems to
 occur right after a doorbell mmap, but that's as far as I got. I
 can try to revert it in today's merge and see how things go.

  Kent

> -Original Message-
> From: Kuehling, Felix
> Sent: Friday, March 08, 2019 11:16 PM
> To: Koenig, Christian ; Russell, Kent
> ; amd-gfx@lists.freedesktop.org
> Subject: RE: [PATCH 3/6] drm/amdgpu: allocate VM PDs/PTs on
 demand
> My concerns were related to eviction fence handing. It would
> manifest by unnecessary eviction callbacks into KFD that aren't
> cause by real evictions. I addressed that with a previous patch
> series that removed the need to remove eviction fences and add
> them back around page table updates in
>> amdgpu_amdkfd_gpuvm.c.
>
> I don't know what's going on here. I can probably take a look on
> Monday. I haven't considered what changed with respect to PD
> updates.
>
> Kent, can we temporarily revert the offending change in
> amd-kfd-staging just to unblock the merge?
>
> Christian, I think KFD is currently broken on amd-staging-drm-next.
> If we're
> serious about supporting KFD upstream, you may also want to
> consider reverting your change there for now. Also consider
> building the Thunk and kfdtest so you can do quick 

[PATCH 2/3] drm/amdgpu: support userptr cross VMAs case with HMM v2

2019-03-06 Thread Yang, Philip
userptr may cross two VMAs if the forked child process (not call exec
after fork) malloc buffer, then free it, and then malloc larger size
buf, kerenl will create new VMA adjacent to old VMA which was cloned
from parent process, some pages of userptr are in the first VMA, the
rest pages are in the second VMA.

HMM expects range only have one VMA, loop over all VMAs in the address
range, create multiple ranges to handle this case. See
is_mergeable_anon_vma in mm/mmap.c for details.

Change-Id: I0ca8c77e28deabccc139906f9ffee04b7e383314
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 123 +---
 1 file changed, 88 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 7cc0ba24369d..802bec7ef917 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -711,7 +711,8 @@ struct amdgpu_ttm_tt {
struct task_struct  *usertask;
uint32_tuserflags;
 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-   struct hmm_rangerange;
+   struct hmm_range*ranges;
+   int nr_ranges;
 #endif
 };
 
@@ -723,62 +724,105 @@ struct amdgpu_ttm_tt {
  * once afterwards to stop HMM tracking
  */
 #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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
-   struct hmm_range *range = >range;
-   int r = 0, i;
+   unsigned long start = gtt->userptr;
+   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
+   struct hmm_range *ranges;
+   struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
+   uint64_t *pfns, f;
+   int r = 0, i, nr_pages;
 
if (!mm) /* Happens during process shutdown */
return -ESRCH;
 
-   amdgpu_hmm_init_range(range);
-
down_read(>mmap_sem);
 
-   range->vma = find_vma(mm, gtt->userptr);
-   if (!range_in_vma(range->vma, gtt->userptr, end))
-   r = -EFAULT;
-   else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
-   range->vma->vm_file)
+   /* user pages may cross multiple VMAs */
+   gtt->nr_ranges = 0;
+   do {
+   if (gtt->nr_ranges >= MAX_NR_VMAS) {
+   DRM_ERROR("Too many VMAs in userptr range\n");
+   r = -EFAULT;
+   goto out;
+   }
+
+   vma = find_vma(mm, vma ? vma->vm_end : start);
+   if (unlikely(!vma)) {
+   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);
+
+   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
+   vmas[0]->vm_file)) {
r = -EPERM;
-   if (r)
goto out;
+   }
 
-   range->pfns = kvmalloc_array(ttm->num_pages, sizeof(uint64_t),
-GFP_KERNEL);
-   if (range->pfns == NULL) {
+   ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
+   if (unlikely(!ranges)) {
r = -ENOMEM;
goto out;
}
-   range->start = gtt->userptr;
-   range->end = end;
 
-   range->pfns[0] = range->flags[HMM_PFN_VALID];
-   range->pfns[0] |= amdgpu_ttm_tt_is_readonly(ttm) ?
-   0 : range->flags[HMM_PFN_WRITE];
-   for (i = 1; i < ttm->num_pages; i++)
-   range->pfns[i] = range->pfns[0];
+   pfns = kvmalloc_array(ttm->num_pages, sizeof(*pfns), GFP_KERNEL);
+   if (unlikely(!pfns)) {
+   r = -ENOMEM;
+   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);
+
+   for (nr_pages = 0, i = 0; i < gtt->nr_ranges; i++) {
+   ranges[i].vma = vmas[i];
+   ranges[i].start = max(start, vmas[i]->vm_start);
+   ranges[i].end = min(end, vmas[i]->vm_end);
+   ranges[i].pfns = pfns + nr_pages;
+   nr_pages += (ranges[i].end - ranges[i].start) / PAGE_SIZE;
+
+   r = hmm_vma_fault([i], true);
+   if (unlikely(r))
+   break;
+   }
+   if (unlikely(r)) {
+   while (i--)
+ 

[PATCH 1/3] drm/amdkfd: support concurrent userptr update for HMM v2

2019-03-06 Thread Yang, Philip
Userptr restore may have concurrent userptr invalidation after
hmm_vma_fault adds the range to the hmm->ranges list, needs call
hmm_vma_range_done to remove the range from hmm->ranges list first,
then reschedule the restore worker. Otherwise hmm_vma_fault will add
same range to the list, this will cause loop in the list because
range->next point to range itself.

Add function untrack_invalid_user_pages to reduce code duplication.

Change-Id: I31407739dc10554f8e418c7a0e0415d3d95552f1
Signed-off-by: Philip Yang 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 25 ++-
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d2e315f42dad..60d53b0b497a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1935,6 +1935,23 @@ static int update_invalid_user_pages(struct 
amdkfd_process_info *process_info,
return 0;
 }
 
+/* Remove invalid userptr BOs from hmm track list
+ *
+ * Stop HMM track the userptr update
+ */
+static void untrack_invalid_user_pages(struct amdkfd_process_info 
*process_info)
+{
+   struct kgd_mem *mem, *tmp_mem;
+   struct amdgpu_bo *bo;
+
+   list_for_each_entry_safe(mem, tmp_mem,
+_info->userptr_inval_list,
+validate_list.head) {
+   bo = mem->bo;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+   }
+}
+
 /* Validate invalid userptr BOs
  *
  * Validates BOs on the userptr_inval_list, and moves them back to the
@@ -2052,12 +2069,6 @@ static int validate_invalid_user_pages(struct 
amdkfd_process_info *process_info)
 out_free:
kfree(pd_bo_list_entries);
 out_no_mem:
-   list_for_each_entry_safe(mem, tmp_mem,
-_info->userptr_inval_list,
-validate_list.head) {
-   bo = mem->bo;
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-   }
 
return ret;
 }
@@ -2122,7 +2133,9 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct 
work_struct *work)
 * hanging. No point trying again.
 */
}
+
 unlock_out:
+   untrack_invalid_user_pages(process_info);
mutex_unlock(_info->lock);
mmput(mm);
put_task_struct(usertask);
-- 
2.17.1

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

Re: [PATCH 2/3] drm/amdgpu: support userptr cross VMAs case with HMM

2019-03-06 Thread Yang, Philip
I will submit v2 to fix those issues. Some comments inline...

On 2019-03-06 3:11 p.m., Kuehling, Felix wrote:
> Some comments inline ...
> 
> On 3/5/2019 1:09 PM, Yang, Philip wrote:
>> userptr may cross two VMAs if the forked child process (not call exec
>> after fork) malloc buffer, then free it, and then malloc larger size
>> buf, kerenl will create new VMA adjacent to old VMA which was cloned
>> from parent process, some pages of userptr are in the first VMA, the
>> rest pages are in the second VMA.
>>
>> HMM expects range only have one VMA, loop over all VMAs in the address
>> range, create multiple ranges to handle this case. See
>> is_mergeable_anon_vma in mm/mmap.c for details.
>>
>> Change-Id: I0ca8c77e28deabccc139906f9ffee04b7e383314
>> Signed-off-by: Philip Yang 
>> ---
>>drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 122 +---
>>1 file changed, 87 insertions(+), 35 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> index cd0ccfbbcb84..173bf4db5994 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
>> @@ -711,7 +711,8 @@ struct amdgpu_ttm_tt {
>>  struct task_struct  *usertask;
>>  uint32_tuserflags;
>>#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
>> -struct hmm_rangerange;
>> +struct hmm_range*ranges;
>> +int nr_ranges;
>>#endif
>>};
>>
>> @@ -723,62 +724,104 @@ struct amdgpu_ttm_tt {
>> * once afterwards to stop HMM tracking
>> */
>>#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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
>> -struct hmm_range *range = >range;
>> -int r = 0, i;
>> +unsigned long start = gtt->userptr;
>> +unsigned long end = start + ttm->num_pages * PAGE_SIZE;
>> +struct hmm_range *ranges;
>> +struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
>> +uint64_t *pfns, f;
>> +int r = 0, i, nr_pages;
>>
>>  if (!mm) /* Happens during process shutdown */
>>  return -ESRCH;
>>
>> -amdgpu_hmm_init_range(range);
>> -
>>  down_read(>mmap_sem);
>>
>> -range->vma = find_vma(mm, gtt->userptr);
>> -if (!range_in_vma(range->vma, gtt->userptr, end))
>> -r = -EFAULT;
>> -else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
>> -range->vma->vm_file)
>> +/* user pages may cross multiple VMAs */
>> +gtt->nr_ranges = 0;
>> +do {
>> +vma = find_vma(mm, vma ? vma->vm_end : start);
>> +if (unlikely(!vma)) {
>> +r = -EFAULT;
>> +goto out;
>> +}
>> +vmas[gtt->nr_ranges++] = vma;
>> +if (gtt->nr_ranges >= MAX_NR_VMAS) {
> 
> This will lead to a failure when you have exactly 16 VMAs. If you move
> the check to the start of the loop, it will only trigger when you exceed
> the limit not just after you reach it.
> 
Ok
> 
>> +DRM_ERROR("invalid userptr range\n");
> 
> The userptr range is not really invalid. It only exceeds some artificial
> limitation in this code. A message like "Too many VMAs in userptr range"
> would be more appropriate.
> 
Ok
> 
>> +r = -EFAULT;
>> +goto out;
>> +}
>> +} while (end > vma->vm_end);
>> +
>> +DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
>> +start, gtt->nr_ranges, ttm->num_pages);
>> +
>> +if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
>> +vmas[0]->vm_file)) {
>>  r = -EPERM;
>> -if (r)
>>  goto out;
>> +}
>>
>> -range->pfns = kvmalloc_array(ttm->num_pages, sizeof(uint64_t),
>> - GFP_KERNEL);
>> -if (range->pfns == NULL) {
>> +ranges = kvmalloc_array(gtt->nr_ranges, s

Re: [PATCH 1/3] drm/amdkfd: support concurrent userptr update for HMM

2019-03-06 Thread Yang, Philip
Hi Felix,

Thanks, there are other corner cases, call untrack at end of restore 
userptr worker is better place to cleanup. I will submit v2 patch, to 
fix this issue completely.

Philip

On 2019-03-06 3:01 p.m., Kuehling, Felix wrote:
> Hmm, I'm not sure. This change probably fixes this issue, but there may
> be other similar corner cases in other situations where the restore
> worker fails and needs to retry. The better place to call untrack in
> amdgpu_amdkfd_restore_userptr_worker would be at the very end. Anything
> that's left in the userptr_inval_list at that point needs to be untracked.
> 
> For now as a quick fix for an urgent bug, this change is Reviewed-by:
> Felix Kuehling . But please revisit this and
> check if there are similar corner cases as I explained above.
> 
> Regards,
>     Felix
> 
> On 3/5/2019 1:09 PM, Yang, Philip wrote:
>> Userptr restore may have concurrent userptr invalidation after
>> hmm_vma_fault adds the range to the hmm->ranges list, needs call
>> hmm_vma_range_done to remove the range from hmm->ranges list first,
>> then reschedule the restore worker. Otherwise hmm_vma_fault will add
>> same range to the list, this will cause loop in the list because
>> range->next point to range itself.
>>
>> Add function untrack_invalid_user_pages to reduce code duplication.
>>
>> Change-Id: I31407739dc10554f8e418c7a0e0415d3d95552f1
>> Signed-off-by: Philip Yang 
>> ---
>>.../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 28 ++-
>>1 file changed, 21 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> index 314c048fcac6..783d760ccfe3 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> @@ -1731,6 +1731,23 @@ static int update_invalid_user_pages(struct 
>> amdkfd_process_info *process_info,
>>  return 0;
>>}
>>
>> +/* Remove invalid userptr BOs from hmm track list
>> + *
>> + * Stop HMM track the userptr update
>> + */
>> +static void untrack_invalid_user_pages(struct amdkfd_process_info 
>> *process_info)
>> +{
>> +struct kgd_mem *mem, *tmp_mem;
>> +struct amdgpu_bo *bo;
>> +
>> +list_for_each_entry_safe(mem, tmp_mem,
>> + _info->userptr_inval_list,
>> + validate_list.head) {
>> +bo = mem->bo;
>> +amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>> +}
>> +}
>> +
>>/* Validate invalid userptr BOs
>> *
>> * Validates BOs on the userptr_inval_list, and moves them back to the
>> @@ -1848,12 +1865,7 @@ static int validate_invalid_user_pages(struct 
>> amdkfd_process_info *process_info)
>>out_free:
>>  kfree(pd_bo_list_entries);
>>out_no_mem:
>> -list_for_each_entry_safe(mem, tmp_mem,
>> - _info->userptr_inval_list,
>> - validate_list.head) {
>> -bo = mem->bo;
>> -amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>> -}
>> +untrack_invalid_user_pages(process_info);
>>
>>  return ret;
>>}
>> @@ -1897,8 +1909,10 @@ static void 
>> amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
>>   * and we can just restart the queues.
>>   */
>>  if (!list_empty(_info->userptr_inval_list)) {
>> -if (atomic_read(_info->evicted_bos) != evicted_bos)
>> +if (atomic_read(_info->evicted_bos) != evicted_bos) {
>> +untrack_invalid_user_pages(process_info);
>>  goto unlock_out; /* Concurrent eviction, try again */
>> +}
>>
>>  if (validate_invalid_user_pages(process_info))
>>  goto unlock_out;
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 3/3] drm/amdgpu: more descriptive message if HMM not enabled v3

2019-03-06 Thread Yang, Philip
If using old kernel config file, CONFIG_ZONE_DEVICE is not selected,
so CONFIG_HMM and CONFIG_HMM_MIRROR is not enabled, the current driver
error message "Failed to register MMU notifier" is not clear. Inform
user with more descriptive message on how to fix the missing kernel
config option.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109808

Change-Id: Idfebaeababa4c37c1ef093c2b91a26910a167585
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
index 4803e216e174..ee5541b49604 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
@@ -53,6 +53,8 @@ static inline struct amdgpu_mn *amdgpu_mn_get(struct 
amdgpu_device *adev,
 }
 static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
 {
+   DRM_WARN_ONCE("HMM_MIRROR kernel config option is not enabled, "
+   "add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
return -ENODEV;
 }
 static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
-- 
2.17.1

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

Re: [PATCH 3/3] drm/amdgpu: more descriptive message if HMM not enabled v2

2019-03-06 Thread Yang, Philip


On 2019-03-06 10:04 a.m., Christian König wrote:
> Am 06.03.19 um 16:02 schrieb Yang, Philip:
>> If using old kernel config file, CONFIG_ZONE_DEVICE is not selected,
>> so CONFIG_HMM and CONFIG_HMM_MIRROR is not enabled, the current driver
>> error message "Failed to register MMU notifier" is not clear. Inform
>> user with more descriptive message on how to fix the missing kernel
>> config option.
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109808
>>
>> Change-Id: Idfebaeababa4c37c1ef093c2b91a26910a167585
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> index 4803e216e174..a5fd73fc24bf 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> @@ -53,6 +53,8 @@ static inline struct amdgpu_mn *amdgpu_mn_get(struct 
>> amdgpu_device *adev,
>>   }
>>   static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned 
>> long addr)
>>   {
>> +    DRM_WARN_ONCE("HMM_MIRROR kernel config option is not enabled\n");
>> +    DRM_WARN_ONCE("add CONFIG_ZONE_DEVICE=y in config file to fix 
>> this\n");
> 
> One message please, apart from that looks good to me.
> 
> Christian.
> 
Do you mean use multiple line string with one DRM_WARN_ONCE call? That 
will get checkpatch warning "WARNING: quoted string split across lines".
Can I just ignore that checkpatch warning?

Philip
>>   return -ENODEV;
>>   }
>>   static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 3/3] drm/amdgpu: more descriptive message if HMM not enabled v2

2019-03-06 Thread Yang, Philip
If using old kernel config file, CONFIG_ZONE_DEVICE is not selected,
so CONFIG_HMM and CONFIG_HMM_MIRROR is not enabled, the current driver
error message "Failed to register MMU notifier" is not clear. Inform
user with more descriptive message on how to fix the missing kernel
config option.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109808

Change-Id: Idfebaeababa4c37c1ef093c2b91a26910a167585
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
index 4803e216e174..a5fd73fc24bf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
@@ -53,6 +53,8 @@ static inline struct amdgpu_mn *amdgpu_mn_get(struct 
amdgpu_device *adev,
 }
 static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
 {
+   DRM_WARN_ONCE("HMM_MIRROR kernel config option is not enabled\n");
+   DRM_WARN_ONCE("add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
return -ENODEV;
 }
 static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
-- 
2.17.1

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

Re: [PATCH 3/3] drm/amdgpu: more descriptive message if HMM not enabled

2019-03-06 Thread Yang, Philip


On 2019-03-06 4:05 a.m., Michel Dänzer wrote:
> On 2019-03-05 7:09 p.m., Yang, Philip wrote:
>> If using old kernel config file, CONFIG_ZONE_DEVICE is not selected,
>> so CONFIG_HMM and CONFIG_HMM_MIRROR is not enabled, the current driver
>> error message "Failed to register MMU notifier" is not clear. Inform
>> user with more descriptive message on how to fix the missing kernel
>> config option.
>>
>> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109808
>>
>> Change-Id: Idfebaeababa4c37c1ef093c2b91a26910a167585
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> index 4803e216e174..b155cac52aca 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
>> @@ -53,6 +53,8 @@ static inline struct amdgpu_mn *amdgpu_mn_get(struct 
>> amdgpu_device *adev,
>>   }
>>   static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long 
>> addr)
>>   {
>> +DRM_ERROR("HMM_MIRROR kernel config option is not enabled\n");
>> +DRM_ERROR("add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
>>  return -ENODEV;
>>   }
>>   static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
>>
> 
> amdgpu_gem_userptr_ioctl calls amdgpu_mn_register if userspace sets the
> AMDGPU_GEM_USERPTR_REGISTER flag, so buggy/malicious userspace could
> spam dmesg with these errors. I'm afraid a different solution is needed.
> 
> The error message is inside dummy function amdgpu_mn_register, it only 
shows if kernel config option HMM is not enabled. Driver does need HMM 
kernel option to support userptr. We want to provide obvious message to 
users to update kernel config file from old kernel, otherwise all 
userptr related functions are broken. I will change this to WARN_ONCE to 
avoid spam dmesg.

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

[PATCH 2/3] drm/amdgpu: support userptr cross VMAs case with HMM

2019-03-05 Thread Yang, Philip
userptr may cross two VMAs if the forked child process (not call exec
after fork) malloc buffer, then free it, and then malloc larger size
buf, kerenl will create new VMA adjacent to old VMA which was cloned
from parent process, some pages of userptr are in the first VMA, the
rest pages are in the second VMA.

HMM expects range only have one VMA, loop over all VMAs in the address
range, create multiple ranges to handle this case. See
is_mergeable_anon_vma in mm/mmap.c for details.

Change-Id: I0ca8c77e28deabccc139906f9ffee04b7e383314
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 122 +---
 1 file changed, 87 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index cd0ccfbbcb84..173bf4db5994 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -711,7 +711,8 @@ struct amdgpu_ttm_tt {
struct task_struct  *usertask;
uint32_tuserflags;
 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-   struct hmm_rangerange;
+   struct hmm_range*ranges;
+   int nr_ranges;
 #endif
 };
 
@@ -723,62 +724,104 @@ struct amdgpu_ttm_tt {
  * once afterwards to stop HMM tracking
  */
 #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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
-   struct hmm_range *range = >range;
-   int r = 0, i;
+   unsigned long start = gtt->userptr;
+   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
+   struct hmm_range *ranges;
+   struct vm_area_struct *vma = NULL, *vmas[MAX_NR_VMAS];
+   uint64_t *pfns, f;
+   int r = 0, i, nr_pages;
 
if (!mm) /* Happens during process shutdown */
return -ESRCH;
 
-   amdgpu_hmm_init_range(range);
-
down_read(>mmap_sem);
 
-   range->vma = find_vma(mm, gtt->userptr);
-   if (!range_in_vma(range->vma, gtt->userptr, end))
-   r = -EFAULT;
-   else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
-   range->vma->vm_file)
+   /* user pages may cross multiple VMAs */
+   gtt->nr_ranges = 0;
+   do {
+   vma = find_vma(mm, vma ? vma->vm_end : start);
+   if (unlikely(!vma)) {
+   r = -EFAULT;
+   goto out;
+   }
+   vmas[gtt->nr_ranges++] = vma;
+   if (gtt->nr_ranges >= MAX_NR_VMAS) {
+   DRM_ERROR("invalid userptr range\n");
+   r = -EFAULT;
+   goto out;
+   }
+   } while (end > vma->vm_end);
+
+   DRM_DEBUG_DRIVER("0x%lx nr_ranges %d pages 0x%lx\n",
+   start, gtt->nr_ranges, ttm->num_pages);
+
+   if (unlikely((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
+   vmas[0]->vm_file)) {
r = -EPERM;
-   if (r)
goto out;
+   }
 
-   range->pfns = kvmalloc_array(ttm->num_pages, sizeof(uint64_t),
-GFP_KERNEL);
-   if (range->pfns == NULL) {
+   ranges = kvmalloc_array(gtt->nr_ranges, sizeof(*ranges), GFP_KERNEL);
+   if (unlikely(!ranges)) {
r = -ENOMEM;
goto out;
}
-   range->start = gtt->userptr;
-   range->end = end;
 
-   range->pfns[0] = range->flags[HMM_PFN_VALID];
-   range->pfns[0] |= amdgpu_ttm_tt_is_readonly(ttm) ?
-   0 : range->flags[HMM_PFN_WRITE];
-   for (i = 1; i < ttm->num_pages; i++)
-   range->pfns[i] = range->pfns[0];
+   pfns = kvmalloc_array(ttm->num_pages, sizeof(*pfns), GFP_KERNEL);
+   if (unlikely(!pfns)) {
+   r = -ENOMEM;
+   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);
+
+   for (nr_pages = 0, i = 0; i < gtt->nr_ranges; i++) {
+   ranges[i].vma = vmas[i];
+   ranges[i].start = max(start, vmas[i]->vm_start);
+   ranges[i].end = min(end, vmas[i]->vm_end);
+   ranges[i].pfns = pfns + nr_pages;
+   nr_pages += (ranges[i].end - ranges[i].start) / PAGE_SIZE;
+
+   r = hmm_vma_fault([i], true);
+   if (unlikely(r))
+   break;
+   }
+   if (unlikely(r)) {
+   while (i--)
+

[PATCH 1/3] drm/amdkfd: support concurrent userptr update for HMM

2019-03-05 Thread Yang, Philip
Userptr restore may have concurrent userptr invalidation after
hmm_vma_fault adds the range to the hmm->ranges list, needs call
hmm_vma_range_done to remove the range from hmm->ranges list first,
then reschedule the restore worker. Otherwise hmm_vma_fault will add
same range to the list, this will cause loop in the list because
range->next point to range itself.

Add function untrack_invalid_user_pages to reduce code duplication.

Change-Id: I31407739dc10554f8e418c7a0e0415d3d95552f1
Signed-off-by: Philip Yang 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 28 ++-
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 314c048fcac6..783d760ccfe3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1731,6 +1731,23 @@ static int update_invalid_user_pages(struct 
amdkfd_process_info *process_info,
return 0;
 }
 
+/* Remove invalid userptr BOs from hmm track list
+ *
+ * Stop HMM track the userptr update
+ */
+static void untrack_invalid_user_pages(struct amdkfd_process_info 
*process_info)
+{
+   struct kgd_mem *mem, *tmp_mem;
+   struct amdgpu_bo *bo;
+
+   list_for_each_entry_safe(mem, tmp_mem,
+_info->userptr_inval_list,
+validate_list.head) {
+   bo = mem->bo;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+   }
+}
+
 /* Validate invalid userptr BOs
  *
  * Validates BOs on the userptr_inval_list, and moves them back to the
@@ -1848,12 +1865,7 @@ static int validate_invalid_user_pages(struct 
amdkfd_process_info *process_info)
 out_free:
kfree(pd_bo_list_entries);
 out_no_mem:
-   list_for_each_entry_safe(mem, tmp_mem,
-_info->userptr_inval_list,
-validate_list.head) {
-   bo = mem->bo;
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-   }
+   untrack_invalid_user_pages(process_info);
 
return ret;
 }
@@ -1897,8 +1909,10 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct 
work_struct *work)
 * and we can just restart the queues.
 */
if (!list_empty(_info->userptr_inval_list)) {
-   if (atomic_read(_info->evicted_bos) != evicted_bos)
+   if (atomic_read(_info->evicted_bos) != evicted_bos) {
+   untrack_invalid_user_pages(process_info);
goto unlock_out; /* Concurrent eviction, try again */
+   }
 
if (validate_invalid_user_pages(process_info))
goto unlock_out;
-- 
2.17.1

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

[PATCH 0/3] handle userptr corner cases with HMM path

2019-03-05 Thread Yang, Philip
Those corner cases are found by kfdtest.KFDIPCTest.

Philip Yang (3):
  drm/amdkfd: support concurrent userptr update for HMM
  drm/amdgpu: support userptr cross VMAs case with HMM
  drm/amdgpu: more descriptive message if HMM not enabled

 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  28 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 122 +-
 3 files changed, 110 insertions(+), 42 deletions(-)

-- 
2.17.1

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

[PATCH 3/3] drm/amdgpu: more descriptive message if HMM not enabled

2019-03-05 Thread Yang, Philip
If using old kernel config file, CONFIG_ZONE_DEVICE is not selected,
so CONFIG_HMM and CONFIG_HMM_MIRROR is not enabled, the current driver
error message "Failed to register MMU notifier" is not clear. Inform
user with more descriptive message on how to fix the missing kernel
config option.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109808

Change-Id: Idfebaeababa4c37c1ef093c2b91a26910a167585
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
index 4803e216e174..b155cac52aca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h
@@ -53,6 +53,8 @@ static inline struct amdgpu_mn *amdgpu_mn_get(struct 
amdgpu_device *adev,
 }
 static inline int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
 {
+   DRM_ERROR("HMM_MIRROR kernel config option is not enabled\n");
+   DRM_ERROR("add CONFIG_ZONE_DEVICE=y in config file to fix this\n");
return -ENODEV;
 }
 static inline void amdgpu_mn_unregister(struct amdgpu_bo *bo) {}
-- 
2.17.1

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

Re: [PATCH] drm/amdgpu: handle userptr corner cases with HMM path

2019-03-04 Thread Yang, Philip
Hi Felix,

I will split this and submit two patches for review.

I didn't realize mprotect can have userptr with more than 2 vmas. For 
malloc, it will always be one or two vmas. I will loop over all VMAs to 
call hmm_vma_fault to get userptr pages.

Thanks,
Philip

On 2019-03-01 7:46 p.m., Kuehling, Felix wrote:
> Since you're addressing two distinct bugs, please split this into two patches.
> 
> For the multiple VMAs, should we generalize that to handle any number of 
> VMAs? It's not a typical case, but you could easily construct situations with 
> mprotect where different parts of the same buffer have different VMAs and 
> then register that as a single user pointer. Or you could user MAP_FIXED to 
> map multiple files to adjacent virtual addresses.
> 
> There may be two ways to handle this:
> 1. If the userptr address range spans more than one VMA, fail
> 2. Loop over all the VMAs in the address range
> 
> Thanks,
>Felix
> 
> -Original Message-----
> From: amd-gfx  On Behalf Of Yang, 
> Philip
> Sent: Friday, March 01, 2019 12:30 PM
> To: amd-gfx@lists.freedesktop.org
> Cc: Yang, Philip 
> Subject: [PATCH] drm/amdgpu: handle userptr corner cases with HMM path
> 
> Those corner cases are found by kfdtest.KFDIPCTest.
> 
> userptr may cross two vmas if the forked child process (not call exec
> after fork) malloc buffer, then free it, and then malloc larger size
> buf, kerenl will create new vma adjacent to old vma which was cloned
> from parent process, some pages of userptr are in the first vma, the
> rest pages are in the second vma. HMM expects range only have one vma,
> we have to use two ranges to handle this case. See is_mergeable_anon_vma
> in mm/mmap.c for details.
> 
> kfd userptr restore may have concurrent userptr invalidation, reschedule
> to restore and then needs call hmm_vma_range_done to remove range from
> hmm->ranges list, otherwise hmm_vma_fault add same range to the list
> will cause loop in the list because range->next point to range itself.
> 
> Change-Id: I641ba7406c32bd8b7ae715f52bd896d53fe56801
> Signed-off-by: Philip Yang 
> ---
>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 28 +--
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 73 +--
>   2 files changed, 71 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index f8104760f1e6..179af9d3ab19 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -1738,6 +1738,23 @@ static int update_invalid_user_pages(struct 
> amdkfd_process_info *process_info,
>   return 0;
>   }
>   
> +/* Untrack invalid userptr BOs
> + *
> + * Stop HMM track the userptr update
> + */
> +static void untrack_invalid_user_pages(struct amdkfd_process_info 
> *process_info)
> +{
> + struct kgd_mem *mem, *tmp_mem;
> + struct amdgpu_bo *bo;
> +
> + list_for_each_entry_safe(mem, tmp_mem,
> +  _info->userptr_inval_list,
> +  validate_list.head) {
> + bo = mem->bo;
> + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
> + }
> +}
> +
>   /* Validate invalid userptr BOs
>*
>* Validates BOs on the userptr_inval_list, and moves them back to the
> @@ -1855,12 +1872,7 @@ static int validate_invalid_user_pages(struct 
> amdkfd_process_info *process_info)
>   out_free:
>   kfree(pd_bo_list_entries);
>   out_no_mem:
> - list_for_each_entry_safe(mem, tmp_mem,
> -  _info->userptr_inval_list,
> -  validate_list.head) {
> - bo = mem->bo;
> - amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
> - }
> + untrack_invalid_user_pages(process_info);
>   
>   return ret;
>   }
> @@ -1904,8 +1916,10 @@ static void 
> amdgpu_amdkfd_restore_userptr_worker(struct work_struct *work)
>* and we can just restart the queues.
>*/
>   if (!list_empty(_info->userptr_inval_list)) {
> - if (atomic_read(_info->evicted_bos) != evicted_bos)
> + if (atomic_read(_info->evicted_bos) != evicted_bos) {
> + untrack_invalid_user_pages(process_info);
>   goto unlock_out; /* Concurrent eviction, try again */
> + }
>   
>   if (validate_invalid_user_pages(process_info))
>   goto unlock_out;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index cd0ccfbbcb84..e5736225f513 100644
>

[PATCH] drm/amdgpu: handle userptr corner cases with HMM path

2019-03-01 Thread Yang, Philip
Those corner cases are found by kfdtest.KFDIPCTest.

userptr may cross two vmas if the forked child process (not call exec
after fork) malloc buffer, then free it, and then malloc larger size
buf, kerenl will create new vma adjacent to old vma which was cloned
from parent process, some pages of userptr are in the first vma, the
rest pages are in the second vma. HMM expects range only have one vma,
we have to use two ranges to handle this case. See is_mergeable_anon_vma
in mm/mmap.c for details.

kfd userptr restore may have concurrent userptr invalidation, reschedule
to restore and then needs call hmm_vma_range_done to remove range from
hmm->ranges list, otherwise hmm_vma_fault add same range to the list
will cause loop in the list because range->next point to range itself.

Change-Id: I641ba7406c32bd8b7ae715f52bd896d53fe56801
Signed-off-by: Philip Yang 
---
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  | 28 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 73 +--
 2 files changed, 71 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index f8104760f1e6..179af9d3ab19 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -1738,6 +1738,23 @@ static int update_invalid_user_pages(struct 
amdkfd_process_info *process_info,
return 0;
 }
 
+/* Untrack invalid userptr BOs
+ *
+ * Stop HMM track the userptr update
+ */
+static void untrack_invalid_user_pages(struct amdkfd_process_info 
*process_info)
+{
+   struct kgd_mem *mem, *tmp_mem;
+   struct amdgpu_bo *bo;
+
+   list_for_each_entry_safe(mem, tmp_mem,
+_info->userptr_inval_list,
+validate_list.head) {
+   bo = mem->bo;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
+   }
+}
+
 /* Validate invalid userptr BOs
  *
  * Validates BOs on the userptr_inval_list, and moves them back to the
@@ -1855,12 +1872,7 @@ static int validate_invalid_user_pages(struct 
amdkfd_process_info *process_info)
 out_free:
kfree(pd_bo_list_entries);
 out_no_mem:
-   list_for_each_entry_safe(mem, tmp_mem,
-_info->userptr_inval_list,
-validate_list.head) {
-   bo = mem->bo;
-   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
-   }
+   untrack_invalid_user_pages(process_info);
 
return ret;
 }
@@ -1904,8 +1916,10 @@ static void amdgpu_amdkfd_restore_userptr_worker(struct 
work_struct *work)
 * and we can just restart the queues.
 */
if (!list_empty(_info->userptr_inval_list)) {
-   if (atomic_read(_info->evicted_bos) != evicted_bos)
+   if (atomic_read(_info->evicted_bos) != evicted_bos) {
+   untrack_invalid_user_pages(process_info);
goto unlock_out; /* Concurrent eviction, try again */
+   }
 
if (validate_invalid_user_pages(process_info))
goto unlock_out;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index cd0ccfbbcb84..e5736225f513 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -711,7 +711,7 @@ struct amdgpu_ttm_tt {
struct task_struct  *usertask;
uint32_tuserflags;
 #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
-   struct hmm_rangerange;
+   struct hmm_rangerange, range2;
 #endif
 };
 
@@ -727,58 +727,81 @@ 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 end = gtt->userptr + ttm->num_pages * PAGE_SIZE;
+   unsigned long start = gtt->userptr;
+   unsigned long end = start + ttm->num_pages * PAGE_SIZE;
struct hmm_range *range = >range;
+   struct hmm_range *range2 = >range2;
+   struct vm_area_struct *vma, *vma_next = NULL;
+   uint64_t *pfns, f;
int r = 0, i;
 
if (!mm) /* Happens during process shutdown */
return -ESRCH;
 
-   amdgpu_hmm_init_range(range);
-
down_read(>mmap_sem);
 
-   range->vma = find_vma(mm, gtt->userptr);
-   if (!range_in_vma(range->vma, gtt->userptr, end))
-   r = -EFAULT;
-   else if ((gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) &&
-   range->vma->vm_file)
+   /* user pages may cross vma bound */
+   vma = find_vma(mm, start);
+   if (unlikely(!range_in_vma(vma, start, end))) {
+   vma_next = find_extend_vma(mm, end);
+   if (unlikely(!vma_next)) {
+   r = -EFAULT;
+   goto out;
+   }
+   

Re: KASAN caught amdgpu / HMM use-after-free

2019-02-28 Thread Yang, Philip
Hi Alex,

May you help take a look? It is not merged into amd-staging-drm-next 
yet, maybe missing code-review+2, it was done automatically after code 
review for other patch.

http://git.amd.com:8080/c/brahma/ec/linux/+/206711

Regards,
Philip

On 2019-02-28 6:51 a.m., Michel Dänzer wrote:
> 
> [ Dropping Jérôme and the linux-mm list ]
> 
> On 2019-02-27 7:48 p.m., Yang, Philip wrote:
>> Hi Alex,
>>
>> Pushed, thanks.
>>
>> mm/hmm: use reference counting for HMM struct
> 
> Thanks, but I'm not seeing it yet. Maybe it needs some special
> treatment, because it's not a DRM code change?
> 
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: KASAN caught amdgpu / HMM use-after-free

2019-02-27 Thread Yang, Philip
Hi Alex,

Pushed, thanks.

mm/hmm: use reference counting for HMM struct

Philip

On 2019-02-27 1:32 p.m., Deucher, Alexander wrote:
> Go ahead an apply it to amd-staging-drm-next.  It'll naturally fall out 
> when I rebase it.
> 
> Alex
> 
> *From:* amd-gfx  on behalf of 
> Yang, Philip 
> *Sent:* Wednesday, February 27, 2019 1:05 PM
> *To:* Michel Dänzer; Jérôme Glisse
> *Cc:* linux...@kvack.org; amd-gfx@lists.freedesktop.org
> *Subject:* Re: KASAN caught amdgpu / HMM use-after-free
> amd-staging-drm-next will rebase to kernel 5.1 to pickup this fix
> automatically. As a short-term workaround, please cherry-pick this fix
> into your local repository.
> 
> Regards,
> Philip
> 
> On 2019-02-27 12:33 p.m., Michel Dänzer wrote:
>> On 2019-02-27 6:14 p.m., Yang, Philip wrote:
>>> Hi Michel,
>>>
>>> Yes, I found the same issue and the bug has been fixed by Jerome:
>>>
>>> 876b462120aa mm/hmm: use reference counting for HMM struct
>>>
>>> The fix is on hmm-for-5.1 branch, I cherry-pick it into my local branch
>>> to workaround the issue.
>> 
>> Please push it to amd-staging-drm-next, so that others don't run into
>> the issue as well.
>> 
>> 
> ___
> 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: KASAN caught amdgpu / HMM use-after-free

2019-02-27 Thread Yang, Philip
amd-staging-drm-next will rebase to kernel 5.1 to pickup this fix 
automatically. As a short-term workaround, please cherry-pick this fix 
into your local repository.

Regards,
Philip

On 2019-02-27 12:33 p.m., Michel Dänzer wrote:
> On 2019-02-27 6:14 p.m., Yang, Philip wrote:
>> Hi Michel,
>>
>> Yes, I found the same issue and the bug has been fixed by Jerome:
>>
>> 876b462120aa mm/hmm: use reference counting for HMM struct
>>
>> The fix is on hmm-for-5.1 branch, I cherry-pick it into my local branch
>> to workaround the issue.
> 
> Please push it to amd-staging-drm-next, so that others don't run into
> the issue as well.
> 
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: KASAN caught amdgpu / HMM use-after-free

2019-02-27 Thread Yang, Philip
Hi Michel,

Yes, I found the same issue and the bug has been fixed by Jerome:

876b462120aa mm/hmm: use reference counting for HMM struct

The fix is on hmm-for-5.1 branch, I cherry-pick it into my local branch 
to workaround the issue.

Regards,
Philip

On 2019-02-27 12:02 p.m., Michel Dänzer wrote:
> 
> See the attached dmesg excerpt. I've hit this a few times running piglit
> with amd-staging-drm-next, first on February 22nd.
> 
> The memory was freed after calling hmm_mirror_unregister in
> amdgpu_mn_destroy.
> 
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdgpu: fix HMM config dependency issue

2019-02-21 Thread Yang, Philip
Only select HMM_MIRROR will get kernel config dependency warnings
if CONFIG_HMM is missing in the config. Add depends on HMM will
solve the issue.

Add conditional compilation to fix compilation errors if HMM_MIRROR
is not enabled as HMM config is not enabled.

Change-Id: I1b44a0b5285bbef5e98bfb045d1d82c167af1cb8
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig  |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |  6 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 12 
 3 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 960a63355705..67553effb649 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,6 +26,7 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
+   depends on ARCH_HAS_HMM
select HMM_MIRROR
help
  This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 1e675048f790..c1dbca14dce5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -712,7 +712,9 @@ struct amdgpu_ttm_tt {
uint64_tuserptr;
struct task_struct  *usertask;
uint32_tuserflags;
+#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
struct hmm_rangerange;
+#endif
 };
 
 /**
@@ -722,6 +724,7 @@ struct amdgpu_ttm_tt {
  * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only
  * once afterwards to stop HMM tracking
  */
+#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
 int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
 {
struct amdgpu_ttm_tt *gtt = (void *)ttm;
@@ -804,6 +807,7 @@ bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
 
return r;
 }
+#endif
 
 /**
  * amdgpu_ttm_tt_set_user_pages - Copy pages in, putting old pages as 
necessary.
@@ -904,9 +908,11 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 
sg_free_table(ttm->sg);
 
+#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
if (gtt->range.pfns &&
ttm->pages[0] == hmm_pfn_to_page(>range, gtt->range.pfns[0]))
WARN_ONCE(1, "Missing get_user_page_done\n");
+#endif
 }
 
 int amdgpu_ttm_gart_bind(struct amdgpu_device *adev,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
index 8988c87fff9d..c9d87271a4cb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -101,8 +101,20 @@ int amdgpu_mmap(struct file *filp, struct vm_area_struct 
*vma);
 int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo);
 int amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo);
 
+#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR)
 int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages);
 bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm);
+#else
+static inline int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page 
**pages)
+{
+   return -EPERM;
+}
+static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm)
+{
+   return false;
+}
+#endif
+
 void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);
 void amdgpu_ttm_tt_mark_user_pages(struct ttm_tt *ttm);
 int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,
-- 
2.17.1

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

Re: [PATCH] drm/amdgpu: select ARCH_HAS_HMM and ZONE_DEVICE option

2019-02-21 Thread Yang, Philip
Thanks Jerome for the the correct HMM config option, only select 
HMM_MIRROR is not good enough because CONFIG_HMM option maybe missing, 
add depends on ARCH_HAS_HMM will solve the issue.

I will submit new patch to fix the compilation error if HMM_MIRROR 
config is missing and the HMM config dependency issue.

Philip

On 2019-02-20 7:25 p.m., Jerome Glisse wrote:
> On Thu, Feb 21, 2019 at 12:17:33AM +, Kuehling, Felix wrote:
>> On 2019-02-20 6:34 p.m., Jerome Glisse wrote:
>>> On Wed, Feb 20, 2019 at 10:39:49PM +, Kuehling, Felix wrote:
 On 2019-02-20 5:12 p.m., Jerome Glisse wrote:
> On Wed, Feb 20, 2019 at 07:18:17PM +, Kuehling, Felix wrote:
>> [+Jerome]
>>
>> Why to we need ZONE_DEVICE. I didn't think this was needed for mirroring
>> CPU page tables to device page tables.
>>
>> ARCH_HAS_HMM depends on (X86_64 || PPC64). Do we have some alternative
>> for ARM support?
>>
>> Also, the name ARCH_HAS_HMM looks like it's meant to be selected by the
>> CPU architecture rather than any driver. Jerome, do you have any advice?
> This patch is wrong you need to depend on ARCH_HAS_HMM and
 Who selects ARCH_HAS_HMM? Currently I don't see this selected anywhere.
 So any config option that depends on it will be invisible in menuconfig.
 Do we need ARCH_HAS_HMM somewhere in the arch/x86/Kconfig and
 arch/powerpc/Kconfig?

 Also, ARCH_HAS_HMM does not currently support ARM. Does that mean we
 can't have ARM support in AMDGPU if we start using HMM?
>>> ARCH_HAS_HMM is defined by architecture that support HMM. So par x86
>>> and PPC. It should not be hard to add it to ARM (i can not remember if
>>> ARM has DAX yet or not, if ARM does not have DAX then you need to add
>>> that first).
>>
>> Not having ARM support is a bummer. I just enabled KFD on ARM a few
>> weeks ago. Now depending on HMM makes KFD unusable on ARM. [+Mark FYI] I
>> hope this is only a temporary setback.
> 
> It should not be hard to add in fact all it might need is a Kconfig
> patch. I have no easy access to ARM with PCIE so i have not tackle
> this yet.
> 
>>
>>
 Finally, ARCH_HAS_HMM has a bunch of dependencies. If they are not met,
 I guess it can't be enabled. Should those be "select"s instead?
>>> No they should not be selected, people configuring their system need
>>> to have the freedom of doing so. All those option are selected in all
>>> the big distribution.
>> As far as I can tell, the arch/x86/Kconfig doesn't select ARCH_HAS_HMM.
>> Its default is "y", so it should be enabled on anything that meets the
>> dependencies. But ZONE_DEVICE was not enabled by default. I think that's
>> what broke our kernel configs.
>>
>> We'll fix our own kernel configs to enable ZONE_DEVICE and ARCH_HAS_HMM
>> to get our internal builds to work again.
> 
> You seem to be doing weird thing with your kconfig ...
> 
>>
>> I suspect other users with their own kernel configs will stumble over
>> this and wonder why KFD and userptr support are disabled in their builds.
> 
> Patch to improve kconfig are welcome but they should not force select
> thing. Configuration is there to give user freedom to select fewature
> they want to give up.
> 
> Maybe following would help:
> ARCH_HAS_HMM
> - bool
> - default y
> + def_bool y
> 
> Cheers,
> Jérôme
> 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH] drm/amdgpu: select ARCH_HAS_HMM and ZONE_DEVICE option

2019-02-20 Thread Yang, Philip
Those options are needed to support HMM

Change-Id: Ieb7bb3bcec07245d79a02793e6728228decc400a
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 960a63355705..63f0542bc34b 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,7 +26,9 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
+   select ARCH_HAS_HMM
select HMM_MIRROR
+   select ZONE_DEVICE
help
  This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
  isn't already selected to enabled full userptr support.
-- 
2.17.1

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

[PATCH 2/3] drm/amdkfd: avoid HMM change cause circular lock dependency v2

2019-02-06 Thread Yang, Philip
There is circular lock between gfx and kfd path with HMM change:
lock(dqm) -> bo::reserve -> amdgpu_mn_lock

To avoid this, move init/unint_mqd() out of lock(dqm), to remove nested
locking between mmap_sem and bo::reserve. The locking order
is: bo::reserve -> amdgpu_mn_lock(p->mn)

Change-Id: I2ec09a47571f6b4c8eaef93f22c0a600f5f70153
Signed-off-by: Philip Yang 
Reviewed-by: Felix Kuehling 
Acked-by: Christian König 
---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++-
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 8372556b52eb..efe0d3c0215b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1156,21 +1156,17 @@ static int create_queue_cpsch(struct 
device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd_mgr;
 
-   retval = 0;
-
-   dqm_lock(dqm);
-
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
pr_warn("Can't create new usermode queue because %d queues were 
already created\n",
dqm->total_queue_count);
retval = -EPERM;
-   goto out_unlock;
+   goto out;
}
 
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
retval = allocate_sdma_queue(dqm, >sdma_id);
if (retval)
-   goto out_unlock;
+   goto out;
q->properties.sdma_queue_id =
q->sdma_id / get_num_sdma_engines(dqm);
q->properties.sdma_engine_id =
@@ -1181,6 +1177,9 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_sdma_queue;
 
+   /* Do init_mqd before dqm_lock(dqm) to avoid circular locking order:
+* lock(dqm) -> bo::reserve
+*/
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
 
@@ -1188,6 +1187,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
retval = -ENOMEM;
goto out_deallocate_doorbell;
}
+
/*
 * Eviction state logic: we only mark active queues as evicted
 * to avoid the overhead of restoring inactive queues later
@@ -1196,9 +1196,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
q->properties.is_evicted = (q->properties.queue_size > 0 &&
q->properties.queue_percent > 0 &&
q->properties.queue_address != 0);
-
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
-
q->properties.tba_addr = qpd->tba_addr;
q->properties.tma_addr = qpd->tma_addr;
retval = mqd_mgr->init_mqd(mqd_mgr, >mqd, >mqd_mem_obj,
@@ -1206,6 +1204,8 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_doorbell;
 
+   dqm_lock(dqm);
+
list_add(>list, >queues_list);
qpd->queue_count++;
if (q->properties.is_active) {
@@ -1233,9 +1233,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
 out_deallocate_sdma_queue:
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
deallocate_sdma_queue(dqm, q->sdma_id);
-out_unlock:
-   dqm_unlock(dqm);
-
+out:
return retval;
 }
 
@@ -1398,8 +1396,6 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = true;
}
 
-   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
-
/*
 * Unconditionally decrement this counter, regardless of the queue's
 * type
@@ -1410,6 +1406,9 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
 
dqm_unlock(dqm);
 
+   /* Do uninit_mqd after dqm_unlock(dqm) to avoid circular locking */
+   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+
return retval;
 
 failed:
@@ -1631,7 +1630,11 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = false;
}
 
-   /* lastly, free mqd resources */
+   dqm_unlock(dqm);
+
+   /* Lastly, free mqd resources.
+* Do uninit_mqd() after dqm_unlock to avoid circular locking.
+*/
list_for_each_entry_safe(q, next, >queues_list, list) {
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
@@ -1645,7 +1648,6 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
}
 
 out:
-   dqm_unlock(dqm);
return 

[PATCH 1/3] drm/amdgpu: use HMM mirror callback to replace mmu notifier v7

2019-02-06 Thread Yang, Philip
Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables
callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in
DRM_AMDGPU_USERPTR Kconfig.

It supports both KFD userptr and gfx userptr paths.

Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e
Signed-off-by: Philip Yang 
Reviewed-by: Felix Kuehling 
Reviewed-by: Christian König 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig |   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 154 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h |   2 +-
 4 files changed, 70 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 9221e5489069..960a63355705 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
-   select MMU_NOTIFIER
+   select HMM_MIRROR
help
- This option selects CONFIG_MMU_NOTIFIER if it isn't already
- selected to enabled full userptr support.
+ This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
+ isn't already selected to enabled full userptr support.
 
 config DRM_AMDGPU_GART_DEBUGFS
bool "Allow GART access through debugfs"
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 466da5954a68..851001ced5e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -172,7 +172,7 @@ endif
 amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
 amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
 amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
-amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
+amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
 
 include $(FULL_AMD_PATH)/powerplay/Makefile
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 3e6823fdd939..e356867d2308 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -45,7 +45,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -58,7 +58,6 @@
  *
  * @adev: amdgpu device pointer
  * @mm: process address space
- * @mn: MMU notifier structure
  * @type: type of MMU notifier
  * @work: destruction work item
  * @node: hash table node to find structure by adev and mn
@@ -66,6 +65,7 @@
  * @objects: interval tree containing amdgpu_mn_nodes
  * @read_lock: mutex for recursive locking of @lock
  * @recursion: depth of recursion
+ * @mirror: HMM mirror function support
  *
  * Data for each amdgpu device and process address space.
  */
@@ -73,7 +73,6 @@ struct amdgpu_mn {
/* constant after initialisation */
struct amdgpu_device*adev;
struct mm_struct*mm;
-   struct mmu_notifier mn;
enum amdgpu_mn_type type;
 
/* only used on destruction */
@@ -85,8 +84,9 @@ struct amdgpu_mn {
/* objects protected by lock */
struct rw_semaphore lock;
struct rb_root_cached   objects;
-   struct mutexread_lock;
-   atomic_trecursion;
+
+   /* HMM mirror */
+   struct hmm_mirror   mirror;
 };
 
 /**
@@ -103,7 +103,7 @@ struct amdgpu_mn_node {
 };
 
 /**
- * amdgpu_mn_destroy - destroy the MMU notifier
+ * amdgpu_mn_destroy - destroy the HMM mirror
  *
  * @work: previously sheduled work item
  *
@@ -129,28 +129,26 @@ static void amdgpu_mn_destroy(struct work_struct *work)
}
up_write(>lock);
mutex_unlock(>mn_lock);
-   mmu_notifier_unregister_no_release(>mn, amn->mm);
+
+   hmm_mirror_unregister(>mirror);
kfree(amn);
 }
 
 /**
- * amdgpu_mn_release - callback to notify about mm destruction
+ * amdgpu_hmm_mirror_release - callback to notify about mm destruction
  *
- * @mn: our notifier
- * @mm: the mm this callback is about
+ * @mirror: the HMM mirror (mm) this callback is about
  *
- * Shedule a work item to lazy destroy our notifier.
+ * Shedule a work item to lazy destroy HMM mirror.
  */
-static void amdgpu_mn_release(struct mmu_notifier *mn,
- struct mm_struct *mm)
+static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror)
 {
-   struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
+   struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror);
 
INIT_WORK(>work, amdgpu_mn_destroy);
schedule_work(>work);
 }
 
-
 /**
  * amdgpu_mn_lock - take the write side lock for this notifier
  *
@@ -181,14 +179,10 @@ void amdgpu_mn_unlock(struct amdgpu_mn *mn)
 static int amdgpu_mn_read_lock(struct amdgpu_mn *amn, bool blockable)
 {
if (blockable)
-   mutex_lock(>read_lock);
-   else if (!mutex_trylock(>read_lock))
+   down_read(>lock);
+   else if 

[PATCH 0/3] Use HMM to replace get_user_pages

2019-02-06 Thread Yang, Philip
Hi Christian,

Resend patch 1/3, 2/3, added Reviewed-by in comments.

Change in patch 3/3, amdgpu_cs_submit, amdgpu_cs_ioctl return -EAGAIN
to user space to retry cs_ioctl.

Regards,
Philip

Philip Yang (3):
  drm/amdgpu: use HMM mirror callback to replace mmu notifier v7
  drm/amdkfd: avoid HMM change cause circular lock dependency v2
  drm/amdgpu: replace get_user_pages with HMM address mirror helpers v8

 drivers/gpu/drm/amd/amdgpu/Kconfig|   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 138 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c| 179 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 178 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |  32 ++--
 12 files changed, 269 insertions(+), 387 deletions(-)

-- 
2.17.1

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


[PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v8

2019-02-06 Thread Yang, Philip
Use HMM helper function hmm_vma_fault() to get physical pages backing
userptr and start CPU page table update track of those pages. Then use
hmm_vma_range_done() to check if those pages are updated before
amdgpu_cs_submit for gfx or before user queues are resumed for kfd.

If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
from scratch, for kfd, restore worker is rescheduled to retry.

HMM simplify the CPU page table concurrent update check, so remove
guptasklock, mmu_invalidations, last_set_pages fields from
amdgpu_ttm_tt struct.

HMM does not pin the page (increase page ref count), so remove related
operations like release_pages(), put_page(), mark_page_dirty().

Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 138 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 178 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 9 files changed, 182 insertions(+), 278 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0b31a1859023..0e1711a75b68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -61,7 +61,6 @@ struct kgd_mem {
 
atomic_t invalid;
struct amdkfd_process_info *process_info;
-   struct page **user_pages;
 
struct amdgpu_sync sync;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d7b10d79f1de..ae2d838d31ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
goto out;
}
 
-   /* If no restore worker is running concurrently, user_pages
-* should not be allocated
-*/
-   WARN(mem->user_pages, "Leaking user_pages array");
-
-   mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
-  sizeof(struct page *),
-  GFP_KERNEL | __GFP_ZERO);
-   if (!mem->user_pages) {
-   pr_err("%s: Failed to allocate pages array\n", __func__);
-   ret = -ENOMEM;
-   goto unregister_out;
-   }
-
-   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
+   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
-   goto free_out;
+   goto unregister_out;
}
 
-   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
-
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
pr_err("%s: Failed to reserve BO\n", __func__);
@@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
amdgpu_bo_unreserve(bo);
 
 release_out:
-   if (ret)
-   release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
-free_out:
-   kvfree(mem->user_pages);
-   mem->user_pages = NULL;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 unregister_out:
if (ret)
amdgpu_mn_unregister(bo);
@@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
@@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
i = 0;
@@ -1371,15 +1349,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
list_del(_list_entry->head);
mutex_unlock(_info->lock);
 
-   /* Free user pages if necessary */
-   if (mem->user_pages) {
-   pr_debug("%s: Freeing user_pages array\n", __func__);
-   if (mem->user_pages[0])
-   release_pages(mem->user_pages,
-   mem->bo->tbo.ttm->num_pages);
-   kvfree(mem->user_pages);
-   }
-
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, );
if (unlikely(ret))
return ret;
@@ -1855,25 +1824,11 @@ static int update_invalid_user_pages(struct 

Re: [PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v7

2019-02-06 Thread Yang, Philip
 >> +/* If userptr are updated after amdgpu_cs_parser_bos(), restart
 >> cs */
 >>   amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) {
 >>   struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo);
 >> -if (amdgpu_ttm_tt_userptr_needs_pages(bo->tbo.ttm)) {
 >> -r = -ERESTARTSYS;
 >> -goto error_abort;
 >> -}
 >> +r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 >
 > Just abort when you see the first one with a problem here.
 >
 > There is no value in checking all of them.
 >
No, amdgpu_ttm_tt_get_user_pages_done calls hmm_vma_range_done to stop 
HMM track and free range structure memory, this needs go through all 
userptr BOs.

 >> +
 >> +if (r == -EAGAIN) {
 >> +if (!--tries) {
 >> +DRM_ERROR("Possible deadlock? Retry too many times\n");
 >> +return -EDEADLK;
 >> +}
 >> +goto restart;
 >> +}
 >> +
 >
 > I would still say to better just return to userspace here.
 >
 > Because of the way HMM works 10 retries might not be sufficient any more.
 >
Yes, it looks better to handle retry from user space. The extra sys call 
overhead can be ignored because this does not happen all the time. I 
will submit new patch for review.

Thanks,
Philip

On 2019-02-06 4:20 a.m., Christian König wrote:
> Am 05.02.19 um 23:00 schrieb Yang, Philip:
>> Use HMM helper function hmm_vma_fault() to get physical pages backing
>> userptr and start CPU page table update track of those pages. Then use
>> hmm_vma_range_done() to check if those pages are updated before
>> amdgpu_cs_submit for gfx or before user queues are resumed for kfd.
>>
>> If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
>> from scratch, for kfd, restore worker is rescheduled to retry.
>>
>> HMM simplify the CPU page table concurrent update check, so remove
>> guptasklock, mmu_invalidations, last_set_pages fields from
>> amdgpu_ttm_tt struct.
>>
>> HMM does not pin the page (increase page ref count), so remove related
>> operations like release_pages(), put_page(), mark_page_dirty().
>>
>> Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h    |   1 -
>>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c    | 158 +++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c    |  25 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h    |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 178 +++---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
>>   9 files changed, 198 insertions(+), 282 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> index 0b31a1859023..0e1711a75b68 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> @@ -61,7 +61,6 @@ struct kgd_mem {
>>   atomic_t invalid;
>>   struct amdkfd_process_info *process_info;
>> -    struct page **user_pages;
>>   struct amdgpu_sync sync;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> index d7b10d79f1de..ae2d838d31ea 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> @@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, 
>> struct mm_struct *mm,
>>   goto out;
>>   }
>> -    /* If no restore worker is running concurrently, user_pages
>> - * should not be allocated
>> - */
>> -    WARN(mem->user_pages, "Leaking user_pages array");
>> -
>> -    mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
>> -   sizeof(struct page *),
>> -   GFP_KERNEL | __GFP_ZERO);
>> -    if (!mem->user_pages) {
>> -    pr_err("%s: Failed to allocate pages array\n", __func__);
>> -    ret = -ENOMEM;
>> -    goto unregister_out;
>> -    }
>> -
>> -    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
>> +    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
>>   if (ret) {
>>

[PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v7

2019-02-05 Thread Yang, Philip
Use HMM helper function hmm_vma_fault() to get physical pages backing
userptr and start CPU page table update track of those pages. Then use
hmm_vma_range_done() to check if those pages are updated before
amdgpu_cs_submit for gfx or before user queues are resumed for kfd.

If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
from scratch, for kfd, restore worker is rescheduled to retry.

HMM simplify the CPU page table concurrent update check, so remove
guptasklock, mmu_invalidations, last_set_pages fields from
amdgpu_ttm_tt struct.

HMM does not pin the page (increase page ref count), so remove related
operations like release_pages(), put_page(), mark_page_dirty().

Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 178 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 9 files changed, 198 insertions(+), 282 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0b31a1859023..0e1711a75b68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -61,7 +61,6 @@ struct kgd_mem {
 
atomic_t invalid;
struct amdkfd_process_info *process_info;
-   struct page **user_pages;
 
struct amdgpu_sync sync;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d7b10d79f1de..ae2d838d31ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
goto out;
}
 
-   /* If no restore worker is running concurrently, user_pages
-* should not be allocated
-*/
-   WARN(mem->user_pages, "Leaking user_pages array");
-
-   mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
-  sizeof(struct page *),
-  GFP_KERNEL | __GFP_ZERO);
-   if (!mem->user_pages) {
-   pr_err("%s: Failed to allocate pages array\n", __func__);
-   ret = -ENOMEM;
-   goto unregister_out;
-   }
-
-   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
+   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
-   goto free_out;
+   goto unregister_out;
}
 
-   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
-
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
pr_err("%s: Failed to reserve BO\n", __func__);
@@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
amdgpu_bo_unreserve(bo);
 
 release_out:
-   if (ret)
-   release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
-free_out:
-   kvfree(mem->user_pages);
-   mem->user_pages = NULL;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 unregister_out:
if (ret)
amdgpu_mn_unregister(bo);
@@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
@@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
i = 0;
@@ -1371,15 +1349,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
list_del(_list_entry->head);
mutex_unlock(_info->lock);
 
-   /* Free user pages if necessary */
-   if (mem->user_pages) {
-   pr_debug("%s: Freeing user_pages array\n", __func__);
-   if (mem->user_pages[0])
-   release_pages(mem->user_pages,
-   mem->bo->tbo.ttm->num_pages);
-   kvfree(mem->user_pages);
-   }
-
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, );
if (unlikely(ret))
return ret;
@@ -1855,25 +1824,11 @@ static int update_invalid_user_pages(struct 

Re: [PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-02-05 Thread Yang, Philip
Hi Christian,

I will submit new patch for review, my comments embedded inline below.

Thanks,
Philip

On 2019-02-05 1:09 p.m., Koenig, Christian wrote:
> Am 05.02.19 um 18:25 schrieb Yang, Philip:
>> [SNIP]+
>>>> +    if (r == -ERESTARTSYS) {
>>>> +    if (!--tries) {
>>>> +    DRM_ERROR("Possible deadlock? Retry too many times\n");
>>>> +    return -EDEADLK;
>>>> +    }
>>>> +    goto restart;
>>> You really need to restart the IOCTL to potentially handle signals.
>>>
>>> But since the calling code correctly handles this already you can just
>>> drop this change as far as I can see.
>>>
>> I agree that we should return -ERESTARTSYS to upper layer to handle signals.
>>
>> But I do not find upper layers handle -ERESTARTSYS in the entire calling
>> path, ksys_ioctl -> do_vfs_ioctl -> amdgpu_drm_ioctl -> drm->ioctl ->
>> drm_ioctl_kernel -> amdgpu_cs_ioctl. The error code returns to
>> application. I confirm it, libdrm userptr test application calling
>> amdgpu_cs_ioctl return code is -512, which is -ERESTARTSYS.
>>
>> So application should handle -ERESTARTSYS to restart the ioctl, but
>> libdrm userptr test application doesn't handle this. This causes the
>> test failed.
> 
> This is a bug in the test cases then.
> 
> -ERESTARTSYS can happen at any time during interruptible waiting and it
> is mandatory for the upper layer to handle it correctly.
> 
-ERESTARTSYS can be returned only when signal is pending, signal handler 
will translate ERESTARTSYS to EINTR, drmIoctl in libdrm does handle 
EINTR and restart the ioctl. The test cases are ok.

Driver fail path should not return ERESTARTSYS to user space. The new 
patch, I change amdgpu_cs_submit to return -EAGAIN if userptr is 
updated, and amdgpu_cs_ioctl redo the ioctl only if error code is 
-EAGAIN. ERESTARTSYS error code returns to user space for signal handle 
as before.

>>
>> Below are details of userptr path difference. For the previous path,
>> libdrm test always goes to step 2, step 3 never trigger. So it never
>> return -ERESTARTSYS, but in theory, this could happen.
>>
>> For HMM path, the test always goes to step 3, we have to handle this
>> case inside amdgpu_cs_ioctl. Maybe I can change amdgpu_cs_submit to
>> return -EBUSY, then restart the ioctl inside amdgpu_cs_ioctl. I will
>> submit new patch.
> 
> Clearly a NAK, this won't work correctly.
> 
I don't understand your concern, may you explain the reason?

> Christian.
> 
>>
>> The previous userptr path:
>> 1. gem_userptr_ioctl to register userptr
>> 2. amdgpu_cs_parser_bos, check if userptr is invalidated, then update
>> userptr
>> 3. amdgpu_cs_submit, hold p->mn lock, check if userptr is invalidated,
>> return -ERESTARTSYS
>>
>> The new HMM userptr path:
>> 1. gem_userptr_ioctl to register userptr
>> 2. amdgpu_cs_parser_bos, start HMM to track userptr update
>> 3. amdgpu_cs_submit, hold p->mn lock, check HMM if userptr is
>> invalidated, return -ERESTARTSYS
>>
>>
>>>> +    }
>>>> +
>>>>     return r;
>>>>     }
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>> index d21dd2f369da..555285e329ed 100644
>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
>>>> @@ -329,26 +329,24 @@ int amdgpu_gem_userptr_ioctl(struct drm_device
>>>> *dev, void *data,
>>>>     r = amdgpu_bo_reserve(bo, true);
>>>>     if (r)
>>>> -    goto free_pages;
>>>> +    goto user_pages_done;
>>>>     amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_GTT);
>>>>     r = ttm_bo_validate(>tbo, >placement, );
>>>>     amdgpu_bo_unreserve(bo);
>>>>     if (r)
>>>> -    goto free_pages;
>>>> +    goto user_pages_done;
>>>>     }
>>>>     r = drm_gem_handle_create(filp, gobj, );
>>>> -    /* drop reference from allocate - handle holds it now */
>>>> -    drm_gem_object_put_unlocked(gobj);
>>>>     if (r)
>>>> -    return r;
>>>> +    goto user_pages_done;
>>>>     args->handle = handle;
>>>> -    return 0;
>>>> -free_pages:
>>>> -    release_pages(bo->tbo.ttm->pages, bo-&

Re: [PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-02-05 Thread Yang, Philip
Hi Christian,

My comments are embedded below. I will submit another patch to address 
those.

Thanks,
Philip

On 2019-02-05 6:52 a.m., Christian König wrote:
> Am 04.02.19 um 19:23 schrieb Yang, Philip:
>> Use HMM helper function hmm_vma_fault() to get physical pages backing
>> userptr and start CPU page table update track of those pages. Then use
>> hmm_vma_range_done() to check if those pages are updated before
>> amdgpu_cs_submit for gfx or before user queues are resumed for kfd.
>>
>> If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
>> from scratch, for kfd, restore worker is rescheduled to retry.
>>
>> HMM simplify the CPU page table concurrent update check, so remove
>> guptasklock, mmu_invalidations, last_set_pages fields from
>> amdgpu_ttm_tt struct.
>>
>> HMM does not pin the page (increase page ref count), so remove related
>> operations like release_pages(), put_page(), mark_page_dirty().
>>
>> Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h    |   1 -
>>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c    | 158 +++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c    |  25 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h    |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
>>   9 files changed, 198 insertions(+), 277 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> index 0b31a1859023..0e1711a75b68 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> @@ -61,7 +61,6 @@ struct kgd_mem {
>>   atomic_t invalid;
>>   struct amdkfd_process_info *process_info;
>> -    struct page **user_pages;
>>   struct amdgpu_sync sync;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> index d7b10d79f1de..ae2d838d31ea 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> @@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, 
>> struct mm_struct *mm,
>>   goto out;
>>   }
>> -    /* If no restore worker is running concurrently, user_pages
>> - * should not be allocated
>> - */
>> -    WARN(mem->user_pages, "Leaking user_pages array");
>> -
>> -    mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
>> -   sizeof(struct page *),
>> -   GFP_KERNEL | __GFP_ZERO);
>> -    if (!mem->user_pages) {
>> -    pr_err("%s: Failed to allocate pages array\n", __func__);
>> -    ret = -ENOMEM;
>> -    goto unregister_out;
>> -    }
>> -
>> -    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
>> +    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
>>   if (ret) {
>>   pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
>> -    goto free_out;
>> +    goto unregister_out;
>>   }
>> -    amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
>> -
>>   ret = amdgpu_bo_reserve(bo, true);
>>   if (ret) {
>>   pr_err("%s: Failed to reserve BO\n", __func__);
>> @@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, 
>> struct mm_struct *mm,
>>   amdgpu_bo_unreserve(bo);
>>   release_out:
>> -    if (ret)
>> -    release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
>> -free_out:
>> -    kvfree(mem->user_pages);
>> -    mem->user_pages = NULL;
>> +    amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>>   unregister_out:
>>   if (ret)
>>   amdgpu_mn_unregister(bo);
>> @@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
>>   ctx->kfd_bo.priority = 0;
>>   ctx->kfd_bo.tv.bo = >tbo;
>>   ctx->kfd_bo.tv.num_shared = 1;
>> -    ctx->kfd_bo.user_pages = NULL;
>>   list_add(>kfd_bo.tv.head, >list);
>>   amdgpu_vm_get_pd_

[PATCH 1/3] drm/amdgpu: use HMM mirror callback to replace mmu notifier v7

2019-02-04 Thread Yang, Philip
Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables
callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in
DRM_AMDGPU_USERPTR Kconfig.

It supports both KFD userptr and gfx userptr paths.

Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig |   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 154 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h |   2 +-
 4 files changed, 70 insertions(+), 94 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 9221e5489069..960a63355705 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
-   select MMU_NOTIFIER
+   select HMM_MIRROR
help
- This option selects CONFIG_MMU_NOTIFIER if it isn't already
- selected to enabled full userptr support.
+ This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
+ isn't already selected to enabled full userptr support.
 
 config DRM_AMDGPU_GART_DEBUGFS
bool "Allow GART access through debugfs"
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 466da5954a68..851001ced5e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -172,7 +172,7 @@ endif
 amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
 amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
 amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
-amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
+amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
 
 include $(FULL_AMD_PATH)/powerplay/Makefile
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 3e6823fdd939..e356867d2308 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -45,7 +45,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -58,7 +58,6 @@
  *
  * @adev: amdgpu device pointer
  * @mm: process address space
- * @mn: MMU notifier structure
  * @type: type of MMU notifier
  * @work: destruction work item
  * @node: hash table node to find structure by adev and mn
@@ -66,6 +65,7 @@
  * @objects: interval tree containing amdgpu_mn_nodes
  * @read_lock: mutex for recursive locking of @lock
  * @recursion: depth of recursion
+ * @mirror: HMM mirror function support
  *
  * Data for each amdgpu device and process address space.
  */
@@ -73,7 +73,6 @@ struct amdgpu_mn {
/* constant after initialisation */
struct amdgpu_device*adev;
struct mm_struct*mm;
-   struct mmu_notifier mn;
enum amdgpu_mn_type type;
 
/* only used on destruction */
@@ -85,8 +84,9 @@ struct amdgpu_mn {
/* objects protected by lock */
struct rw_semaphore lock;
struct rb_root_cached   objects;
-   struct mutexread_lock;
-   atomic_trecursion;
+
+   /* HMM mirror */
+   struct hmm_mirror   mirror;
 };
 
 /**
@@ -103,7 +103,7 @@ struct amdgpu_mn_node {
 };
 
 /**
- * amdgpu_mn_destroy - destroy the MMU notifier
+ * amdgpu_mn_destroy - destroy the HMM mirror
  *
  * @work: previously sheduled work item
  *
@@ -129,28 +129,26 @@ static void amdgpu_mn_destroy(struct work_struct *work)
}
up_write(>lock);
mutex_unlock(>mn_lock);
-   mmu_notifier_unregister_no_release(>mn, amn->mm);
+
+   hmm_mirror_unregister(>mirror);
kfree(amn);
 }
 
 /**
- * amdgpu_mn_release - callback to notify about mm destruction
+ * amdgpu_hmm_mirror_release - callback to notify about mm destruction
  *
- * @mn: our notifier
- * @mm: the mm this callback is about
+ * @mirror: the HMM mirror (mm) this callback is about
  *
- * Shedule a work item to lazy destroy our notifier.
+ * Shedule a work item to lazy destroy HMM mirror.
  */
-static void amdgpu_mn_release(struct mmu_notifier *mn,
- struct mm_struct *mm)
+static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror)
 {
-   struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
+   struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror);
 
INIT_WORK(>work, amdgpu_mn_destroy);
schedule_work(>work);
 }
 
-
 /**
  * amdgpu_mn_lock - take the write side lock for this notifier
  *
@@ -181,14 +179,10 @@ void amdgpu_mn_unlock(struct amdgpu_mn *mn)
 static int amdgpu_mn_read_lock(struct amdgpu_mn *amn, bool blockable)
 {
if (blockable)
-   mutex_lock(>read_lock);
-   else if (!mutex_trylock(>read_lock))
+   down_read(>lock);
+   else if (!down_read_trylock(>lock))
return -EAGAIN;
 
-   if 

[PATCH 0/3] Use HMM to replace get_user_pages

2019-02-04 Thread Yang, Philip
Hi Christian,

This patch is rebased to lastest HMM. Please review the GEM and CS part changes
in patch 3/3.

Thanks,

Philip Yang (3):
  drm/amdgpu: use HMM mirror callback to replace mmu notifier v7
  drm/amdkfd: avoid HMM change cause circular lock dependency v2
  drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

 drivers/gpu/drm/amd/amdgpu/Kconfig|   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c| 179 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |  32 ++--
 12 files changed, 285 insertions(+), 386 deletions(-)

-- 
2.17.1

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


[PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-02-04 Thread Yang, Philip
Use HMM helper function hmm_vma_fault() to get physical pages backing
userptr and start CPU page table update track of those pages. Then use
hmm_vma_range_done() to check if those pages are updated before
amdgpu_cs_submit for gfx or before user queues are resumed for kfd.

If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
from scratch, for kfd, restore worker is rescheduled to retry.

HMM simplify the CPU page table concurrent update check, so remove
guptasklock, mmu_invalidations, last_set_pages fields from
amdgpu_ttm_tt struct.

HMM does not pin the page (increase page ref count), so remove related
operations like release_pages(), put_page(), mark_page_dirty().

Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 9 files changed, 198 insertions(+), 277 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0b31a1859023..0e1711a75b68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -61,7 +61,6 @@ struct kgd_mem {
 
atomic_t invalid;
struct amdkfd_process_info *process_info;
-   struct page **user_pages;
 
struct amdgpu_sync sync;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d7b10d79f1de..ae2d838d31ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
goto out;
}
 
-   /* If no restore worker is running concurrently, user_pages
-* should not be allocated
-*/
-   WARN(mem->user_pages, "Leaking user_pages array");
-
-   mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
-  sizeof(struct page *),
-  GFP_KERNEL | __GFP_ZERO);
-   if (!mem->user_pages) {
-   pr_err("%s: Failed to allocate pages array\n", __func__);
-   ret = -ENOMEM;
-   goto unregister_out;
-   }
-
-   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
+   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
-   goto free_out;
+   goto unregister_out;
}
 
-   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
-
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
pr_err("%s: Failed to reserve BO\n", __func__);
@@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
amdgpu_bo_unreserve(bo);
 
 release_out:
-   if (ret)
-   release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
-free_out:
-   kvfree(mem->user_pages);
-   mem->user_pages = NULL;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 unregister_out:
if (ret)
amdgpu_mn_unregister(bo);
@@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
@@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
i = 0;
@@ -1371,15 +1349,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
list_del(_list_entry->head);
mutex_unlock(_info->lock);
 
-   /* Free user pages if necessary */
-   if (mem->user_pages) {
-   pr_debug("%s: Freeing user_pages array\n", __func__);
-   if (mem->user_pages[0])
-   release_pages(mem->user_pages,
-   mem->bo->tbo.ttm->num_pages);
-   kvfree(mem->user_pages);
-   }
-
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, );
if (unlikely(ret))
return ret;
@@ -1855,25 +1824,11 @@ static int update_invalid_user_pages(struct 

[PATCH 2/3] drm/amdkfd: avoid HMM change cause circular lock dependency v2

2019-02-04 Thread Yang, Philip
There is circular lock between gfx and kfd path with HMM change:
lock(dqm) -> bo::reserve -> amdgpu_mn_lock

To avoid this, move init/unint_mqd() out of lock(dqm), to remove nested
locking between mmap_sem and bo::reserve. The locking order
is: bo::reserve -> amdgpu_mn_lock(p->mn)

Change-Id: I2ec09a47571f6b4c8eaef93f22c0a600f5f70153
Signed-off-by: Philip Yang 
---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++-
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 8372556b52eb..efe0d3c0215b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1156,21 +1156,17 @@ static int create_queue_cpsch(struct 
device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd_mgr;
 
-   retval = 0;
-
-   dqm_lock(dqm);
-
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
pr_warn("Can't create new usermode queue because %d queues were 
already created\n",
dqm->total_queue_count);
retval = -EPERM;
-   goto out_unlock;
+   goto out;
}
 
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
retval = allocate_sdma_queue(dqm, >sdma_id);
if (retval)
-   goto out_unlock;
+   goto out;
q->properties.sdma_queue_id =
q->sdma_id / get_num_sdma_engines(dqm);
q->properties.sdma_engine_id =
@@ -1181,6 +1177,9 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_sdma_queue;
 
+   /* Do init_mqd before dqm_lock(dqm) to avoid circular locking order:
+* lock(dqm) -> bo::reserve
+*/
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
 
@@ -1188,6 +1187,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
retval = -ENOMEM;
goto out_deallocate_doorbell;
}
+
/*
 * Eviction state logic: we only mark active queues as evicted
 * to avoid the overhead of restoring inactive queues later
@@ -1196,9 +1196,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
q->properties.is_evicted = (q->properties.queue_size > 0 &&
q->properties.queue_percent > 0 &&
q->properties.queue_address != 0);
-
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
-
q->properties.tba_addr = qpd->tba_addr;
q->properties.tma_addr = qpd->tma_addr;
retval = mqd_mgr->init_mqd(mqd_mgr, >mqd, >mqd_mem_obj,
@@ -1206,6 +1204,8 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_doorbell;
 
+   dqm_lock(dqm);
+
list_add(>list, >queues_list);
qpd->queue_count++;
if (q->properties.is_active) {
@@ -1233,9 +1233,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
 out_deallocate_sdma_queue:
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
deallocate_sdma_queue(dqm, q->sdma_id);
-out_unlock:
-   dqm_unlock(dqm);
-
+out:
return retval;
 }
 
@@ -1398,8 +1396,6 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = true;
}
 
-   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
-
/*
 * Unconditionally decrement this counter, regardless of the queue's
 * type
@@ -1410,6 +1406,9 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
 
dqm_unlock(dqm);
 
+   /* Do uninit_mqd after dqm_unlock(dqm) to avoid circular locking */
+   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+
return retval;
 
 failed:
@@ -1631,7 +1630,11 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = false;
}
 
-   /* lastly, free mqd resources */
+   dqm_unlock(dqm);
+
+   /* Lastly, free mqd resources.
+* Do uninit_mqd() after dqm_unlock to avoid circular locking.
+*/
list_for_each_entry_safe(q, next, >queues_list, list) {
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
@@ -1645,7 +1648,6 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
}
 
 out:
-   dqm_unlock(dqm);
return retval;
 }
 
-- 
2.17.1


Re: [PATCH 1/3] drm/amdgpu: use HMM mirror callback to replace mmu notifier v6

2019-02-04 Thread Yang, Philip


On 2019-02-04 10:18 a.m., Christian König wrote:
> Am 04.02.19 um 16:06 schrieb Yang, Philip:
>> Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables
>> callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in
>> DRM_AMDGPU_USERPTR Kconfig.
>>
>> It supports both KFD userptr and gfx userptr paths.
>>
>> The depdent HMM patchset from Jérôme Glisse are all merged into 4.20.0
>> kernel now.
>>
>> Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/Kconfig |   6 +-
>>   drivers/gpu/drm/amd/amdgpu/Makefile    |   2 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 139 +++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h |   2 +-
>>   4 files changed, 67 insertions(+), 82 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
>> b/drivers/gpu/drm/amd/amdgpu/Kconfig
>> index 9221e5489069..960a63355705 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Kconfig
>> +++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
>> @@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK
>>   config DRM_AMDGPU_USERPTR
>>   bool "Always enable userptr write support"
>>   depends on DRM_AMDGPU
>> -    select MMU_NOTIFIER
>> +    select HMM_MIRROR
>>   help
>> -  This option selects CONFIG_MMU_NOTIFIER if it isn't already
>> -  selected to enabled full userptr support.
>> +  This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
>> +  isn't already selected to enabled full userptr support.
>>   config DRM_AMDGPU_GART_DEBUGFS
>>   bool "Allow GART access through debugfs"
>> diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
>> b/drivers/gpu/drm/amd/amdgpu/Makefile
>> index 466da5954a68..851001ced5e8 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/Makefile
>> +++ b/drivers/gpu/drm/amd/amdgpu/Makefile
>> @@ -172,7 +172,7 @@ endif
>>   amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
>>   amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
>>   amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
>> -amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
>> +amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
>>   include $(FULL_AMD_PATH)/powerplay/Makefile
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> index 3e6823fdd939..5d518d2bb9be 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
>> @@ -45,7 +45,7 @@
>>   #include 
>>   #include 
>> -#include 
>> +#include 
>>   #include 
>>   #include 
>>   #include 
>> @@ -58,7 +58,6 @@
>>    *
>>    * @adev: amdgpu device pointer
>>    * @mm: process address space
>> - * @mn: MMU notifier structure
>>    * @type: type of MMU notifier
>>    * @work: destruction work item
>>    * @node: hash table node to find structure by adev and mn
>> @@ -66,6 +65,7 @@
>>    * @objects: interval tree containing amdgpu_mn_nodes
>>    * @read_lock: mutex for recursive locking of @lock
>>    * @recursion: depth of recursion
>> + * @mirror: HMM mirror function support
>>    *
>>    * Data for each amdgpu device and process address space.
>>    */
>> @@ -73,7 +73,6 @@ struct amdgpu_mn {
>>   /* constant after initialisation */
>>   struct amdgpu_device    *adev;
>>   struct mm_struct    *mm;
>> -    struct mmu_notifier    mn;
>>   enum amdgpu_mn_type    type;
>>   /* only used on destruction */
>> @@ -87,6 +86,9 @@ struct amdgpu_mn {
>>   struct rb_root_cached    objects;
>>   struct mutex    read_lock;
> 
>>   atomic_t    recursion;
> 
> With HMM we don't need this any more. Please remove it and simplify 
> amdgpu_mn_read_lock() and amdgpu_mn_read_unlock().
> 
Thanks, this makes sense because HMM uses hmm->mirror_sem to serialize 
invalidate range.

amn->read_lock is also not needed anymore, this was used to protect 
atomic operations for atomic_inc_return(amn->recursion) and 
down_read(amn->lock).

Just one amn->lock is needed to sync amdgpu_cs_submit and userptr 
update. I will submit another patch.

Philip

> Apart from that looks good to me,
> Christian.
> 
>> +
>> +    /* HMM mirror */
>> +    struct hmm_mirror    mirror;
>>   };
>>   /**
>> @@ -103,7 +105,7 @@ struct amdgpu_mn_node {
>>   };
>>   /**
>> - * amdgpu_mn_destroy - destroy the MMU notifier
>> + * amdgpu_mn_destroy - destroy the HMM mirror
>>    *
>>  

[PATCH 2/3] drm/amdkfd: avoid HMM change cause circular lock dependency v2

2019-02-04 Thread Yang, Philip
There is circular lock between gfx and kfd path with HMM change:
lock(dqm) -> bo::reserve -> amdgpu_mn_lock

To avoid this, move init/unint_mqd() out of lock(dqm), to remove nested
locking between mmap_sem and bo::reserve. The locking order
is: bo::reserve -> amdgpu_mn_lock(p->mn)

Change-Id: I2ec09a47571f6b4c8eaef93f22c0a600f5f70153
Signed-off-by: Philip Yang 
---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++-
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 8372556b52eb..efe0d3c0215b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1156,21 +1156,17 @@ static int create_queue_cpsch(struct 
device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd_mgr;
 
-   retval = 0;
-
-   dqm_lock(dqm);
-
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
pr_warn("Can't create new usermode queue because %d queues were 
already created\n",
dqm->total_queue_count);
retval = -EPERM;
-   goto out_unlock;
+   goto out;
}
 
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
retval = allocate_sdma_queue(dqm, >sdma_id);
if (retval)
-   goto out_unlock;
+   goto out;
q->properties.sdma_queue_id =
q->sdma_id / get_num_sdma_engines(dqm);
q->properties.sdma_engine_id =
@@ -1181,6 +1177,9 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_sdma_queue;
 
+   /* Do init_mqd before dqm_lock(dqm) to avoid circular locking order:
+* lock(dqm) -> bo::reserve
+*/
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
 
@@ -1188,6 +1187,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
retval = -ENOMEM;
goto out_deallocate_doorbell;
}
+
/*
 * Eviction state logic: we only mark active queues as evicted
 * to avoid the overhead of restoring inactive queues later
@@ -1196,9 +1196,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
q->properties.is_evicted = (q->properties.queue_size > 0 &&
q->properties.queue_percent > 0 &&
q->properties.queue_address != 0);
-
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
-
q->properties.tba_addr = qpd->tba_addr;
q->properties.tma_addr = qpd->tma_addr;
retval = mqd_mgr->init_mqd(mqd_mgr, >mqd, >mqd_mem_obj,
@@ -1206,6 +1204,8 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_doorbell;
 
+   dqm_lock(dqm);
+
list_add(>list, >queues_list);
qpd->queue_count++;
if (q->properties.is_active) {
@@ -1233,9 +1233,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
 out_deallocate_sdma_queue:
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
deallocate_sdma_queue(dqm, q->sdma_id);
-out_unlock:
-   dqm_unlock(dqm);
-
+out:
return retval;
 }
 
@@ -1398,8 +1396,6 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = true;
}
 
-   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
-
/*
 * Unconditionally decrement this counter, regardless of the queue's
 * type
@@ -1410,6 +1406,9 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
 
dqm_unlock(dqm);
 
+   /* Do uninit_mqd after dqm_unlock(dqm) to avoid circular locking */
+   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+
return retval;
 
 failed:
@@ -1631,7 +1630,11 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = false;
}
 
-   /* lastly, free mqd resources */
+   dqm_unlock(dqm);
+
+   /* Lastly, free mqd resources.
+* Do uninit_mqd() after dqm_unlock to avoid circular locking.
+*/
list_for_each_entry_safe(q, next, >queues_list, list) {
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
@@ -1645,7 +1648,6 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
}
 
 out:
-   dqm_unlock(dqm);
return retval;
 }
 
-- 
2.17.1


[PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-02-04 Thread Yang, Philip
Use HMM helper function hmm_vma_fault() to get physical pages backing
userptr and start CPU page table update track of those pages. Then use
hmm_vma_range_done() to check if those pages are updated before
amdgpu_cs_submit for gfx or before user queues are resumed for kfd.

If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
from scratch, for kfd, restore worker is rescheduled to retry.

HMM simplify the CPU page table concurrent update check, so remove
guptasklock, mmu_invalidations, last_set_pages fields from
amdgpu_ttm_tt struct.

HMM does not pin the page (increase page ref count), so remove related
operations like release_pages(), put_page(), mark_page_dirty().

Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 9 files changed, 198 insertions(+), 277 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0b31a1859023..0e1711a75b68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -61,7 +61,6 @@ struct kgd_mem {
 
atomic_t invalid;
struct amdkfd_process_info *process_info;
-   struct page **user_pages;
 
struct amdgpu_sync sync;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d7b10d79f1de..ae2d838d31ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
goto out;
}
 
-   /* If no restore worker is running concurrently, user_pages
-* should not be allocated
-*/
-   WARN(mem->user_pages, "Leaking user_pages array");
-
-   mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
-  sizeof(struct page *),
-  GFP_KERNEL | __GFP_ZERO);
-   if (!mem->user_pages) {
-   pr_err("%s: Failed to allocate pages array\n", __func__);
-   ret = -ENOMEM;
-   goto unregister_out;
-   }
-
-   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
+   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
-   goto free_out;
+   goto unregister_out;
}
 
-   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
-
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
pr_err("%s: Failed to reserve BO\n", __func__);
@@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
amdgpu_bo_unreserve(bo);
 
 release_out:
-   if (ret)
-   release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
-free_out:
-   kvfree(mem->user_pages);
-   mem->user_pages = NULL;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 unregister_out:
if (ret)
amdgpu_mn_unregister(bo);
@@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
@@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
i = 0;
@@ -1371,15 +1349,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
list_del(_list_entry->head);
mutex_unlock(_info->lock);
 
-   /* Free user pages if necessary */
-   if (mem->user_pages) {
-   pr_debug("%s: Freeing user_pages array\n", __func__);
-   if (mem->user_pages[0])
-   release_pages(mem->user_pages,
-   mem->bo->tbo.ttm->num_pages);
-   kvfree(mem->user_pages);
-   }
-
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, );
if (unlikely(ret))
return ret;
@@ -1855,25 +1824,11 @@ static int update_invalid_user_pages(struct 

[PATCH 1/3] drm/amdgpu: use HMM mirror callback to replace mmu notifier v6

2019-02-04 Thread Yang, Philip
Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables
callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in
DRM_AMDGPU_USERPTR Kconfig.

It supports both KFD userptr and gfx userptr paths.

The depdent HMM patchset from Jérôme Glisse are all merged into 4.20.0
kernel now.

Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig |   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 139 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h |   2 +-
 4 files changed, 67 insertions(+), 82 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 9221e5489069..960a63355705 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
-   select MMU_NOTIFIER
+   select HMM_MIRROR
help
- This option selects CONFIG_MMU_NOTIFIER if it isn't already
- selected to enabled full userptr support.
+ This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
+ isn't already selected to enabled full userptr support.
 
 config DRM_AMDGPU_GART_DEBUGFS
bool "Allow GART access through debugfs"
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index 466da5954a68..851001ced5e8 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -172,7 +172,7 @@ endif
 amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
 amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
 amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
-amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
+amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
 
 include $(FULL_AMD_PATH)/powerplay/Makefile
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index 3e6823fdd939..5d518d2bb9be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -45,7 +45,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -58,7 +58,6 @@
  *
  * @adev: amdgpu device pointer
  * @mm: process address space
- * @mn: MMU notifier structure
  * @type: type of MMU notifier
  * @work: destruction work item
  * @node: hash table node to find structure by adev and mn
@@ -66,6 +65,7 @@
  * @objects: interval tree containing amdgpu_mn_nodes
  * @read_lock: mutex for recursive locking of @lock
  * @recursion: depth of recursion
+ * @mirror: HMM mirror function support
  *
  * Data for each amdgpu device and process address space.
  */
@@ -73,7 +73,6 @@ struct amdgpu_mn {
/* constant after initialisation */
struct amdgpu_device*adev;
struct mm_struct*mm;
-   struct mmu_notifier mn;
enum amdgpu_mn_type type;
 
/* only used on destruction */
@@ -87,6 +86,9 @@ struct amdgpu_mn {
struct rb_root_cached   objects;
struct mutexread_lock;
atomic_trecursion;
+
+   /* HMM mirror */
+   struct hmm_mirror   mirror;
 };
 
 /**
@@ -103,7 +105,7 @@ struct amdgpu_mn_node {
 };
 
 /**
- * amdgpu_mn_destroy - destroy the MMU notifier
+ * amdgpu_mn_destroy - destroy the HMM mirror
  *
  * @work: previously sheduled work item
  *
@@ -129,28 +131,26 @@ static void amdgpu_mn_destroy(struct work_struct *work)
}
up_write(>lock);
mutex_unlock(>mn_lock);
-   mmu_notifier_unregister_no_release(>mn, amn->mm);
+
+   hmm_mirror_unregister(>mirror);
kfree(amn);
 }
 
 /**
- * amdgpu_mn_release - callback to notify about mm destruction
+ * amdgpu_hmm_mirror_release - callback to notify about mm destruction
  *
- * @mn: our notifier
- * @mm: the mm this callback is about
+ * @mirror: the HMM mirror (mm) this callback is about
  *
- * Shedule a work item to lazy destroy our notifier.
+ * Shedule a work item to lazy destroy HMM mirror.
  */
-static void amdgpu_mn_release(struct mmu_notifier *mn,
- struct mm_struct *mm)
+static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror)
 {
-   struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
+   struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror);
 
INIT_WORK(>work, amdgpu_mn_destroy);
schedule_work(>work);
 }
 
-
 /**
  * amdgpu_mn_lock - take the write side lock for this notifier
  *
@@ -237,141 +237,126 @@ static void amdgpu_mn_invalidate_node(struct 
amdgpu_mn_node *node,
 /**
  * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change
  *
- * @mn: our notifier
- * @range: mmu notifier context
+ * @mirror: the hmm_mirror (mm) is about to update
+ * @update: the update start, end address
  *
  * Block for operations on BOs to 

[PATCH 0/3] Use HMM to replace get_user_pages

2019-02-04 Thread Yang, Philip
Hi Christian,

This patch is rebased to lastest HMM. Please review the GEM and CS part changes
in patch 3/3.

Regards,

Philip Yang (3):
  drm/amdgpu: use HMM mirror callback to replace mmu notifier v6
  drm/amdkfd: avoid HMM change cause circular lock dependency v2
  drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

 drivers/gpu/drm/amd/amdgpu/Kconfig|   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c| 164 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 .../drm/amd/amdkfd/kfd_device_queue_manager.c |  32 ++--
 12 files changed, 282 insertions(+), 374 deletions(-)

-- 
2.17.1

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


[PATCH] drm/amdgpu: use spin_lock_irqsave to protect vm_manager.pasid_idr

2019-01-31 Thread Yang, Philip
amdgpu_vm_get_task_info is called from interrupt handler and sched timeout
workqueue, so it is needed to use irq version spin_lock to avoid deadlock.

Change-Id: Ifedd4b97535bf0b5d3936edd2d9688957020efd4
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 8f394a20a9eb..bfeb9007e100 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -3386,14 +3386,15 @@ void amdgpu_vm_get_task_info(struct amdgpu_device 
*adev, unsigned int pasid,
 struct amdgpu_task_info *task_info)
 {
struct amdgpu_vm *vm;
+   unsigned long flags;
 
-   spin_lock(>vm_manager.pasid_lock);
+   spin_lock_irqsave(>vm_manager.pasid_lock, flags);
 
vm = idr_find(>vm_manager.pasid_idr, pasid);
if (vm)
*task_info = vm->task_info;
 
-   spin_unlock(>vm_manager.pasid_lock);
+   spin_unlock_irqrestore(>vm_manager.pasid_lock, flags);
 }
 
 /**
-- 
2.17.1

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


Re: Yet another RX Vega hang with another kernel panic signature. WARNING: inconsistent lock state

2019-01-31 Thread Yang, Philip
I found same issue while debugging, I will submit patch to fix this shortly.

Philip

On 2019-01-30 10:35 p.m., Mikhail Gavrilov wrote:
> Hi folks.
> Yet another kernel panic happens while GPU again is hang:
> 
> [ 1469.906798] 
> [ 1469.906799] WARNING: inconsistent lock state
> [ 1469.906801] 5.0.0-0.rc4.git2.2.fc30.x86_64 #1 Tainted: G C
> [ 1469.906802] 
> [ 1469.906804] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
> [ 1469.906806] kworker/12:3/681 [HC0[0]:SC0[0]:HE1:SE1] takes:
> [ 1469.906807] d591b82b
> (&(>vm_manager.pasid_lock)->rlock){?...}, at:
> amdgpu_vm_get_task_info+0x23/0x80 [amdgpu]
> [ 1469.906851] {IN-HARDIRQ-W} state was registered at:
> [ 1469.906855]   _raw_spin_lock+0x31/0x80
> [ 1469.906893]   amdgpu_vm_get_task_info+0x23/0x80 [amdgpu]
> [ 1469.906936]   gmc_v9_0_process_interrupt+0x198/0x2b0 [amdgpu]
> [ 1469.906978]   amdgpu_irq_dispatch+0x90/0x1f0 [amdgpu]
> [ 1469.907018]   amdgpu_irq_callback+0x4a/0x70 [amdgpu]
> [ 1469.907061]   amdgpu_ih_process+0x89/0x100 [amdgpu]
> [ 1469.907103]   amdgpu_irq_handler+0x22/0x50 [amdgpu]
> [ 1469.907106]   __handle_irq_event_percpu+0x3f/0x290
> [ 1469.907108]   handle_irq_event_percpu+0x31/0x80
> [ 1469.907109]   handle_irq_event+0x34/0x51
> [ 1469.907111]   handle_edge_irq+0x7c/0x1a0
> [ 1469.907114]   handle_irq+0xbf/0x100
> [ 1469.907116]   do_IRQ+0x61/0x120
> [ 1469.907118]   ret_from_intr+0x0/0x22
> [ 1469.907121]   cpuidle_enter_state+0xbf/0x470
> [ 1469.907123]   do_idle+0x1ec/0x280
> [ 1469.907125]   cpu_startup_entry+0x19/0x20
> [ 1469.907127]   start_secondary+0x1b3/0x200
> [ 1469.907129]   secondary_startup_64+0xa4/0xb0
> [ 1469.907131] irq event stamp: 5546749
> [ 1469.907133] hardirqs last  enabled at (5546749):
> [] ktime_get+0xfa/0x130
> [ 1469.907135] hardirqs last disabled at (5546748):
> [] ktime_get+0x2b/0x130
> [ 1469.907137] softirqs last  enabled at (5498318):
> [] __do_softirq+0x35f/0x46a
> [ 1469.907140] softirqs last disabled at (5497393):
> [] irq_exit+0x119/0x120
> [ 1469.907141]
> other info that might help us debug this:
> [ 1469.907142]  Possible unsafe locking scenario:
> 
> [ 1469.907143]CPU0
> [ 1469.907144]
> [ 1469.907144]   lock(&(>vm_manager.pasid_lock)->rlock);
> [ 1469.907146]   
> [ 1469.907147] lock(&(>vm_manager.pasid_lock)->rlock);
> [ 1469.907148]
>  *** DEADLOCK ***
> 
> [ 1469.907150] 2 locks held by kworker/12:3/681:
> [ 1469.907152]  #0: 953235a7 ((wq_completion)"events"){+.+.},
> at: process_one_work+0x1e9/0x5d0
> [ 1469.907157]  #1: 71a3d218
> ((work_completion)(&(>work_tdr)->work)){+.+.}, at:
> process_one_work+0x1e9/0x5d0
> [ 1469.907160]
> stack backtrace:
> [ 1469.907163] CPU: 12 PID: 681 Comm: kworker/12:3 Tainted: G
> C5.0.0-0.rc4.git2.2.fc30.x86_64 #1
> [ 1469.907165] Hardware name: System manufacturer System Product
> Name/ROG STRIX X470-I GAMING, BIOS 1103 11/16/2018
> [ 1469.907169] Workqueue: events drm_sched_job_timedout [gpu_sched]
> [ 1469.907171] Call Trace:
> [ 1469.907176]  dump_stack+0x85/0xc0
> [ 1469.907180]  print_usage_bug.cold+0x1ae/0x1e8
> [ 1469.907183]  ? print_shortest_lock_dependencies+0x40/0x40
> [ 1469.907185]  mark_lock+0x50a/0x600
> [ 1469.907186]  ? print_shortest_lock_dependencies+0x40/0x40
> [ 1469.907189]  __lock_acquire+0x544/0x1660
> [ 1469.907191]  ? mark_held_locks+0x57/0x80
> [ 1469.907193]  ? trace_hardirqs_on_thunk+0x1a/0x1c
> [ 1469.907195]  ? lockdep_hardirqs_on+0xed/0x180
> [ 1469.907197]  ? trace_hardirqs_on_thunk+0x1a/0x1c
> [ 1469.907200]  ? retint_kernel+0x10/0x10
> [ 1469.907202]  lock_acquire+0xa2/0x1b0
> [ 1469.907242]  ? amdgpu_vm_get_task_info+0x23/0x80 [amdgpu]
> [ 1469.907245]  _raw_spin_lock+0x31/0x80
> [ 1469.907283]  ? amdgpu_vm_get_task_info+0x23/0x80 [amdgpu]
> [ 1469.907323]  amdgpu_vm_get_task_info+0x23/0x80 [amdgpu]
> [ 1469.907324] [ cut here ]
> 
> 
> My kernel commit is: 62967898789d
> 
> 
> 
> --
> Best Regards,
> Mike Gavrilov.
> 
> 
> ___
> 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 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-01-14 Thread Yang, Philip
Ping Christian, any comments for the GEM and CS part changes?

Thanks. Philip

On 2019-01-10 12:02 p.m., Yang, Philip wrote:
> Use HMM helper function hmm_vma_fault() to get physical pages backing
> userptr and start CPU page table update track of those pages. Then use
> hmm_vma_range_done() to check if those pages are updated before
> amdgpu_cs_submit for gfx or before user queues are resumed for kfd.
> 
> If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
> from scratch, for kfd, restore worker is rescheduled to retry.
> 
> HMM simplify the CPU page table concurrent update check, so remove
> guptasklock, mmu_invalidations, last_set_pages fields from
> amdgpu_ttm_tt struct.
> 
> HMM does not pin the page (increase page ref count), so remove related
> operations like release_pages(), put_page(), mark_page_dirty().
> 
> Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
> Signed-off-by: Philip Yang 
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
>   9 files changed, 198 insertions(+), 277 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> index 0b31a1859023..0e1711a75b68 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
> @@ -61,7 +61,6 @@ struct kgd_mem {
>   
>   atomic_t invalid;
>   struct amdkfd_process_info *process_info;
> - struct page **user_pages;
>   
>   struct amdgpu_sync sync;
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> index d7b10d79f1de..ae2d838d31ea 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
> @@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
> mm_struct *mm,
>   goto out;
>   }
>   
> - /* If no restore worker is running concurrently, user_pages
> -  * should not be allocated
> -  */
> - WARN(mem->user_pages, "Leaking user_pages array");
> -
> - mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
> -sizeof(struct page *),
> -GFP_KERNEL | __GFP_ZERO);
> - if (!mem->user_pages) {
> - pr_err("%s: Failed to allocate pages array\n", __func__);
> - ret = -ENOMEM;
> - goto unregister_out;
> - }
> -
> - ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
> + ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
>   if (ret) {
>   pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
> - goto free_out;
> + goto unregister_out;
>   }
>   
> - amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
> -
>   ret = amdgpu_bo_reserve(bo, true);
>   if (ret) {
>   pr_err("%s: Failed to reserve BO\n", __func__);
> @@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
> mm_struct *mm,
>   amdgpu_bo_unreserve(bo);
>   
>   release_out:
> - if (ret)
> - release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
> -free_out:
> - kvfree(mem->user_pages);
> - mem->user_pages = NULL;
> + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>   unregister_out:
>   if (ret)
>   amdgpu_mn_unregister(bo);
> @@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
>   ctx->kfd_bo.priority = 0;
>   ctx->kfd_bo.tv.bo = >tbo;
>   ctx->kfd_bo.tv.num_shared = 1;
> - ctx->kfd_bo.user_pages = NULL;
>   list_add(>kfd_bo.tv.head, >list);
>   
>   amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
> @@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
>   ctx->kfd_bo.priority = 0;
>   ctx->kfd_bo.tv.bo = >tbo;
>   ctx->kfd_bo.tv.num_shared = 1;
> - ctx->kfd_bo.user_pages

[PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v6

2019-01-10 Thread Yang, Philip
Use HMM helper function hmm_vma_fault() to get physical pages backing
userptr and start CPU page table update track of those pages. Then use
hmm_vma_range_done() to check if those pages are updated before
amdgpu_cs_submit for gfx or before user queues are resumed for kfd.

If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
from scratch, for kfd, restore worker is rescheduled to retry.

HMM simplify the CPU page table concurrent update check, so remove
guptasklock, mmu_invalidations, last_set_pages fields from
amdgpu_ttm_tt struct.

HMM does not pin the page (increase page ref count), so remove related
operations like release_pages(), put_page(), mark_page_dirty().

Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
 .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 158 +++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 173 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   3 +-
 9 files changed, 198 insertions(+), 277 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index 0b31a1859023..0e1711a75b68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -61,7 +61,6 @@ struct kgd_mem {
 
atomic_t invalid;
struct amdkfd_process_info *process_info;
-   struct page **user_pages;
 
struct amdgpu_sync sync;
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index d7b10d79f1de..ae2d838d31ea 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
goto out;
}
 
-   /* If no restore worker is running concurrently, user_pages
-* should not be allocated
-*/
-   WARN(mem->user_pages, "Leaking user_pages array");
-
-   mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
-  sizeof(struct page *),
-  GFP_KERNEL | __GFP_ZERO);
-   if (!mem->user_pages) {
-   pr_err("%s: Failed to allocate pages array\n", __func__);
-   ret = -ENOMEM;
-   goto unregister_out;
-   }
-
-   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
+   ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
if (ret) {
pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
-   goto free_out;
+   goto unregister_out;
}
 
-   amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
-
ret = amdgpu_bo_reserve(bo, true);
if (ret) {
pr_err("%s: Failed to reserve BO\n", __func__);
@@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
mm_struct *mm,
amdgpu_bo_unreserve(bo);
 
 release_out:
-   if (ret)
-   release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
-free_out:
-   kvfree(mem->user_pages);
-   mem->user_pages = NULL;
+   amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
 unregister_out:
if (ret)
amdgpu_mn_unregister(bo);
@@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
amdgpu_vm_get_pd_bo(vm, >list, >vm_pd[0]);
@@ -743,7 +722,6 @@ static int reserve_bo_and_cond_vms(struct kgd_mem *mem,
ctx->kfd_bo.priority = 0;
ctx->kfd_bo.tv.bo = >tbo;
ctx->kfd_bo.tv.num_shared = 1;
-   ctx->kfd_bo.user_pages = NULL;
list_add(>kfd_bo.tv.head, >list);
 
i = 0;
@@ -1371,15 +1349,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu(
list_del(_list_entry->head);
mutex_unlock(_info->lock);
 
-   /* Free user pages if necessary */
-   if (mem->user_pages) {
-   pr_debug("%s: Freeing user_pages array\n", __func__);
-   if (mem->user_pages[0])
-   release_pages(mem->user_pages,
-   mem->bo->tbo.ttm->num_pages);
-   kvfree(mem->user_pages);
-   }
-
ret = reserve_bo_and_cond_vms(mem, NULL, BO_VM_ALL, );
if (unlikely(ret))
return ret;
@@ -1855,25 +1824,11 @@ static int update_invalid_user_pages(struct 

[PATCH 1/3] drm/amdgpu: use HMM mirror callback to replace mmu notifier v6

2019-01-10 Thread Yang, Philip
Replace our MMU notifier with hmm_mirror_ops.sync_cpu_device_pagetables
callback. Enable CONFIG_HMM and CONFIG_HMM_MIRROR as a dependency in
DRM_AMDGPU_USERPTR Kconfig.

It supports both KFD userptr and gfx userptr paths.

The depdent HMM patchset from Jérôme Glisse are all merged into 4.20.0
kernel now.

Change-Id: Ie62c3c5e3c5b8521ab3b438d1eff2aa2a003835e
Signed-off-by: Philip Yang 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig |   6 +-
 drivers/gpu/drm/amd/amdgpu/Makefile|   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c | 122 ++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h |   2 +-
 4 files changed, 55 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 9221e5489069..960a63355705 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -26,10 +26,10 @@ config DRM_AMDGPU_CIK
 config DRM_AMDGPU_USERPTR
bool "Always enable userptr write support"
depends on DRM_AMDGPU
-   select MMU_NOTIFIER
+   select HMM_MIRROR
help
- This option selects CONFIG_MMU_NOTIFIER if it isn't already
- selected to enabled full userptr support.
+ This option selects CONFIG_HMM and CONFIG_HMM_MIRROR if it
+ isn't already selected to enabled full userptr support.
 
 config DRM_AMDGPU_GART_DEBUGFS
bool "Allow GART access through debugfs"
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile 
b/drivers/gpu/drm/amd/amdgpu/Makefile
index f76bcb9c45e4..675efc850ff4 100644
--- a/drivers/gpu/drm/amd/amdgpu/Makefile
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile
@@ -172,7 +172,7 @@ endif
 amdgpu-$(CONFIG_COMPAT) += amdgpu_ioc32.o
 amdgpu-$(CONFIG_VGA_SWITCHEROO) += amdgpu_atpx_handler.o
 amdgpu-$(CONFIG_ACPI) += amdgpu_acpi.o
-amdgpu-$(CONFIG_MMU_NOTIFIER) += amdgpu_mn.o
+amdgpu-$(CONFIG_HMM_MIRROR) += amdgpu_mn.o
 
 include $(FULL_AMD_PATH)/powerplay/Makefile
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
index e55508b39496..5d518d2bb9be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c
@@ -45,7 +45,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -58,7 +58,6 @@
  *
  * @adev: amdgpu device pointer
  * @mm: process address space
- * @mn: MMU notifier structure
  * @type: type of MMU notifier
  * @work: destruction work item
  * @node: hash table node to find structure by adev and mn
@@ -66,6 +65,7 @@
  * @objects: interval tree containing amdgpu_mn_nodes
  * @read_lock: mutex for recursive locking of @lock
  * @recursion: depth of recursion
+ * @mirror: HMM mirror function support
  *
  * Data for each amdgpu device and process address space.
  */
@@ -73,7 +73,6 @@ struct amdgpu_mn {
/* constant after initialisation */
struct amdgpu_device*adev;
struct mm_struct*mm;
-   struct mmu_notifier mn;
enum amdgpu_mn_type type;
 
/* only used on destruction */
@@ -87,6 +86,9 @@ struct amdgpu_mn {
struct rb_root_cached   objects;
struct mutexread_lock;
atomic_trecursion;
+
+   /* HMM mirror */
+   struct hmm_mirror   mirror;
 };
 
 /**
@@ -103,7 +105,7 @@ struct amdgpu_mn_node {
 };
 
 /**
- * amdgpu_mn_destroy - destroy the MMU notifier
+ * amdgpu_mn_destroy - destroy the HMM mirror
  *
  * @work: previously sheduled work item
  *
@@ -129,28 +131,26 @@ static void amdgpu_mn_destroy(struct work_struct *work)
}
up_write(>lock);
mutex_unlock(>mn_lock);
-   mmu_notifier_unregister_no_release(>mn, amn->mm);
+
+   hmm_mirror_unregister(>mirror);
kfree(amn);
 }
 
 /**
- * amdgpu_mn_release - callback to notify about mm destruction
+ * amdgpu_hmm_mirror_release - callback to notify about mm destruction
  *
- * @mn: our notifier
- * @mm: the mm this callback is about
+ * @mirror: the HMM mirror (mm) this callback is about
  *
- * Shedule a work item to lazy destroy our notifier.
+ * Shedule a work item to lazy destroy HMM mirror.
  */
-static void amdgpu_mn_release(struct mmu_notifier *mn,
- struct mm_struct *mm)
+static void amdgpu_hmm_mirror_release(struct hmm_mirror *mirror)
 {
-   struct amdgpu_mn *amn = container_of(mn, struct amdgpu_mn, mn);
+   struct amdgpu_mn *amn = container_of(mirror, struct amdgpu_mn, mirror);
 
INIT_WORK(>work, amdgpu_mn_destroy);
schedule_work(>work);
 }
 
-
 /**
  * amdgpu_mn_lock - take the write side lock for this notifier
  *
@@ -237,21 +237,19 @@ static void amdgpu_mn_invalidate_node(struct 
amdgpu_mn_node *node,
 /**
  * amdgpu_mn_invalidate_range_start_gfx - callback to notify about mm change
  *
- * @mn: our notifier
- * @mm: the mm this callback is about
- * @start: start of updated range
- * @end: end of updated range
+ * @mirror: the hmm_mirror (mm) is about to update
+ * @update: 

[PATCH 2/3] drm/amdkfd: avoid HMM change cause circular lock dependency v2

2019-01-10 Thread Yang, Philip
There is circular lock between gfx and kfd path with HMM change:
lock(dqm) -> bo::reserve -> amdgpu_mn_lock

To avoid this, move init/unint_mqd() out of lock(dqm), to remove nested
locking between mmap_sem and bo::reserve. The locking order
is: bo::reserve -> amdgpu_mn_lock(p->mn)

Change-Id: I2ec09a47571f6b4c8eaef93f22c0a600f5f70153
Signed-off-by: Philip Yang 
---
 .../drm/amd/amdkfd/kfd_device_queue_manager.c | 32 ++-
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 8372556b52eb..efe0d3c0215b 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1156,21 +1156,17 @@ static int create_queue_cpsch(struct 
device_queue_manager *dqm, struct queue *q,
int retval;
struct mqd_manager *mqd_mgr;
 
-   retval = 0;
-
-   dqm_lock(dqm);
-
if (dqm->total_queue_count >= max_num_of_queues_per_device) {
pr_warn("Can't create new usermode queue because %d queues were 
already created\n",
dqm->total_queue_count);
retval = -EPERM;
-   goto out_unlock;
+   goto out;
}
 
if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
retval = allocate_sdma_queue(dqm, >sdma_id);
if (retval)
-   goto out_unlock;
+   goto out;
q->properties.sdma_queue_id =
q->sdma_id / get_num_sdma_engines(dqm);
q->properties.sdma_engine_id =
@@ -1181,6 +1177,9 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_sdma_queue;
 
+   /* Do init_mqd before dqm_lock(dqm) to avoid circular locking order:
+* lock(dqm) -> bo::reserve
+*/
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
 
@@ -1188,6 +1187,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
retval = -ENOMEM;
goto out_deallocate_doorbell;
}
+
/*
 * Eviction state logic: we only mark active queues as evicted
 * to avoid the overhead of restoring inactive queues later
@@ -1196,9 +1196,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
q->properties.is_evicted = (q->properties.queue_size > 0 &&
q->properties.queue_percent > 0 &&
q->properties.queue_address != 0);
-
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
-
q->properties.tba_addr = qpd->tba_addr;
q->properties.tma_addr = qpd->tma_addr;
retval = mqd_mgr->init_mqd(mqd_mgr, >mqd, >mqd_mem_obj,
@@ -1206,6 +1204,8 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
if (retval)
goto out_deallocate_doorbell;
 
+   dqm_lock(dqm);
+
list_add(>list, >queues_list);
qpd->queue_count++;
if (q->properties.is_active) {
@@ -1233,9 +1233,7 @@ static int create_queue_cpsch(struct device_queue_manager 
*dqm, struct queue *q,
 out_deallocate_sdma_queue:
if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
deallocate_sdma_queue(dqm, q->sdma_id);
-out_unlock:
-   dqm_unlock(dqm);
-
+out:
return retval;
 }
 
@@ -1398,8 +1396,6 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = true;
}
 
-   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
-
/*
 * Unconditionally decrement this counter, regardless of the queue's
 * type
@@ -1410,6 +1406,9 @@ static int destroy_queue_cpsch(struct 
device_queue_manager *dqm,
 
dqm_unlock(dqm);
 
+   /* Do uninit_mqd after dqm_unlock(dqm) to avoid circular locking */
+   mqd_mgr->uninit_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj);
+
return retval;
 
 failed:
@@ -1631,7 +1630,11 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
qpd->reset_wavefronts = false;
}
 
-   /* lastly, free mqd resources */
+   dqm_unlock(dqm);
+
+   /* Lastly, free mqd resources.
+* Do uninit_mqd() after dqm_unlock to avoid circular locking.
+*/
list_for_each_entry_safe(q, next, >queues_list, list) {
mqd_mgr = dqm->ops.get_mqd_manager(dqm,
get_mqd_type_from_queue_type(q->properties.type));
@@ -1645,7 +1648,6 @@ static int process_termination_cpsch(struct 
device_queue_manager *dqm,
}
 
 out:
-   dqm_unlock(dqm);
return retval;
 }
 
-- 
2.17.1


Re: [PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v5

2019-01-07 Thread Yang, Philip


On 2019-01-07 9:21 a.m., Christian König wrote:
> Am 14.12.18 um 22:10 schrieb Yang, Philip:
>> Use HMM helper function hmm_vma_fault() to get physical pages backing
>> userptr and start CPU page table update track of those pages. Then use
>> hmm_vma_range_done() to check if those pages are updated before
>> amdgpu_cs_submit for gfx or before user queues are resumed for kfd.
>>
>> If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
>> from scratch, for kfd, restore worker is rescheduled to retry.
>>
>> HMM simplify the CPU page table concurrent update check, so remove
>> guptasklock, mmu_invalidations, last_set_pages fields from
>> amdgpu_ttm_tt struct.
>>
>> HMM does not pin the page (increase page ref count), so remove related
>> operations like release_pages(), put_page(), mark_page_dirty().
>>
>> Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h    |   1 -
>>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c   |   2 -
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   3 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c    | 185 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c    |  25 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h    |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 168 ++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c    |   1 -
>>   11 files changed, 209 insertions(+), 293 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> index 70429f7aa9a8..717791d4fa45 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> @@ -62,7 +62,6 @@ struct kgd_mem {
>>   atomic_t invalid;
>>   struct amdkfd_process_info *process_info;
>> -    struct page **user_pages;
>>   struct amdgpu_sync sync;
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> index be1ab43473c6..2897793600f7 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> @@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, 
>> struct mm_struct *mm,
>>   goto out;
>>   }
>> -    /* If no restore worker is running concurrently, user_pages
>> - * should not be allocated
>> - */
>> -    WARN(mem->user_pages, "Leaking user_pages array");
>> -
>> -    mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
>> -   sizeof(struct page *),
>> -   GFP_KERNEL | __GFP_ZERO);
>> -    if (!mem->user_pages) {
>> -    pr_err("%s: Failed to allocate pages array\n", __func__);
>> -    ret = -ENOMEM;
>> -    goto unregister_out;
>> -    }
>> -
>> -    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
>> +    ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
>>   if (ret) {
>>   pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
>> -    goto free_out;
>> +    goto unregister_out;
>>   }
>> -    amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
>> -
>>   ret = amdgpu_bo_reserve(bo, true);
>>   if (ret) {
>>   pr_err("%s: Failed to reserve BO\n", __func__);
>> @@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, 
>> struct mm_struct *mm,
>>   amdgpu_bo_unreserve(bo);
>>   release_out:
>> -    if (ret)
>> -    release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
>> -free_out:
>> -    kvfree(mem->user_pages);
>> -    mem->user_pages = NULL;
>> +    amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm);
>>   unregister_out:
>>   if (ret)
>>   amdgpu_mn_unregister(bo);
>> @@ -679,7 +659,6 @@ static int reserve_bo_and_vm(struct kgd_mem *mem,
>>   ctx->kfd_bo.priority = 0;
>>   ctx->kfd_bo.tv.bo = >tbo;
>>   ctx->kfd_bo.tv.num_shared = 1;
>> -    ctx->kfd_bo.user_pages = NULL;
>>   list_add(>kfd_bo.tv.head, >list);
>>   amdgp

Re: [PATCH 3/3] drm/amdgpu: replace get_user_pages with HMM address mirror helpers v5

2019-01-02 Thread Yang, Philip
Hi Christian,

May you help review the CS parts related changes? I tested it using 
libdrm Userptr Test under X. Do you know other test applications which 
can stress the CS userptr path?

Thanks,
Philip

On 2018-12-14 4:25 p.m., Kuehling, Felix wrote:
> Except for the GEM and CS parts, the series is Reviewed-by: Felix
> Kuehling 
> 
> Regards,
>    Felix
> 
> On 2018-12-14 4:10 p.m., Yang, Philip wrote:
>> Use HMM helper function hmm_vma_fault() to get physical pages backing
>> userptr and start CPU page table update track of those pages. Then use
>> hmm_vma_range_done() to check if those pages are updated before
>> amdgpu_cs_submit for gfx or before user queues are resumed for kfd.
>>
>> If userptr pages are updated, for gfx, amdgpu_cs_ioctl will restart
>> from scratch, for kfd, restore worker is rescheduled to retry.
>>
>> HMM simplify the CPU page table concurrent update check, so remove
>> guptasklock, mmu_invalidations, last_set_pages fields from
>> amdgpu_ttm_tt struct.
>>
>> HMM does not pin the page (increase page ref count), so remove related
>> operations like release_pages(), put_page(), mark_page_dirty().
>>
>> Change-Id: I2e8c0c6f0d8c21e5596a32d7fc91762778bc9e67
>> Signed-off-by: Philip Yang 
>> ---
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h|   1 -
>>   .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c  |  95 +++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c   |   2 -
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h   |   3 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c| 185 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c   |  14 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c|  25 ++-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h|   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c   | 168 ++--
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h   |   4 +-
>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c|   1 -
>>   11 files changed, 209 insertions(+), 293 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> index 70429f7aa9a8..717791d4fa45 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
>> @@ -62,7 +62,6 @@ struct kgd_mem {
>>   
>>  atomic_t invalid;
>>  struct amdkfd_process_info *process_info;
>> -struct page **user_pages;
>>   
>>  struct amdgpu_sync sync;
>>   
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> index be1ab43473c6..2897793600f7 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
>> @@ -582,28 +582,12 @@ static int init_user_pages(struct kgd_mem *mem, struct 
>> mm_struct *mm,
>>  goto out;
>>  }
>>   
>> -/* If no restore worker is running concurrently, user_pages
>> - * should not be allocated
>> - */
>> -WARN(mem->user_pages, "Leaking user_pages array");
>> -
>> -mem->user_pages = kvmalloc_array(bo->tbo.ttm->num_pages,
>> -   sizeof(struct page *),
>> -   GFP_KERNEL | __GFP_ZERO);
>> -if (!mem->user_pages) {
>> -pr_err("%s: Failed to allocate pages array\n", __func__);
>> -ret = -ENOMEM;
>> -goto unregister_out;
>> -}
>> -
>> -ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, mem->user_pages);
>> +ret = amdgpu_ttm_tt_get_user_pages(bo->tbo.ttm, bo->tbo.ttm->pages);
>>  if (ret) {
>>  pr_err("%s: Failed to get user pages: %d\n", __func__, ret);
>> -goto free_out;
>> +goto unregister_out;
>>  }
>>   
>> -amdgpu_ttm_tt_set_user_pages(bo->tbo.ttm, mem->user_pages);
>> -
>>  ret = amdgpu_bo_reserve(bo, true);
>>  if (ret) {
>>  pr_err("%s: Failed to reserve BO\n", __func__);
>> @@ -616,11 +600,7 @@ static int init_user_pages(struct kgd_mem *mem, struct 
>> mm_struct *mm,
>>  amdgpu_bo_unreserve(bo);
>>   
>>   release_out:
>> -if (ret)
>> -release_pages(mem->user_pages, bo->tbo.ttm->num_pages);
>> -free_out:
>> -kvfree(mem->user_pages);
>> -mem->user_pages = NULL;
>> +amdgpu_ttm_tt_get_user_pages_done(bo-&g

  1   2   >