From: Felix Kuehling <felix.kuehling@amd.com>
To: philip yang <yangp@amd.com>, Philip Yang <Philip.Yang@amd.com>,
amd-gfx@lists.freedesktop.org
Subject: Re: [PATCH 3/3] drm/amdkfd: simplify drain retry fault
Date: Thu, 18 Nov 2021 11:39:16 -0500 [thread overview]
Message-ID: <423b2831-ba9c-3239-574b-ae3ac8ebb112@amd.com> (raw)
In-Reply-To: <eac293ce-bbf5-fe59-a12c-b0113e64f66e@amd.com>
Am 2021-11-18 um 11:19 a.m. schrieb philip yang:
>
>
> On 2021-11-17 7:14 p.m., Felix Kuehling wrote:
>>
>> On 2021-11-16 10:43 p.m., Philip Yang wrote:
>>> unmap range always set svms->drain_pagefaults flag to simplify both
>>> parent range and child range unmap. Deferred list work takes mmap write
>>> lock to read and clear svms->drain_pagefaults, to serialize with unmap
>>> callback.
>>>
>>> Add atomic flag svms->draining_faults, if svms->draining_faults is set,
>>> page fault handle ignore the retry fault, to speed up interrupt
>>> handling.
>> Having both svms->drain_pagefaults and svms->draining_faults is
>> confusing. Do we really need both?
>
> Using one flag, I can not find a way to handle the case, unmap new
> range. if the flag is set, restore_pages uses the flag to drop fault,
> then drain_retry_fault reset the flag after draining is done, we will
> not able to drain retry fault for the new range.
>
I think the correct solution would be to use atomic_inc to set the flag
and atomic_cmp_xchg in svm_range_drain_retry_fault to clear it. If the
flag was changed while svm_range_drain_retry_fault executed, it means
another drain was requested by someone else and the flag should remain
set for another round of draining.
Regards,
Felix
> Regards,
>
> Philip
>
>> Regards,
>> Felix
>>
>>>
>>> Signed-off-by: Philip Yang <Philip.Yang@amd.com>
>>> ---
>>> drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 1 +
>>> drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 24 ++++++++++++++++++------
>>> 2 files changed, 19 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>>> b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>>> index 1d3f012bcd2a..4e4640b731e1 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
>>> @@ -767,6 +767,7 @@ struct svm_range_list {
>>> spinlock_t deferred_list_lock;
>>> atomic_t evicted_ranges;
>>> bool drain_pagefaults;
>>> + atomic_t draining_faults;
>>> struct delayed_work restore_work;
>>> DECLARE_BITMAP(bitmap_supported, MAX_GPU_INSTANCE);
>>> struct task_struct *faulting_task;
>>> diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> index 3eb0a9491755..d332462bf9d3 100644
>>> --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
>>> @@ -1962,6 +1962,7 @@ void svm_range_drain_retry_fault(struct
>>> svm_range_list *svms)
>>> p = container_of(svms, struct kfd_process, svms);
>>> + atomic_set(&svms->draining_faults, 1);
>>> for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) {
>>> pdd = p->pdds[i];
>>> if (!pdd)
>>> @@ -1975,6 +1976,7 @@ void svm_range_drain_retry_fault(struct
>>> svm_range_list *svms)
>>> flush_work(&adev->irq.ih1_work);
>>> pr_debug("drain retry fault gpu %d svms 0x%p done\n", i,
>>> svms);
>>> }
>>> + atomic_set(&svms->draining_faults, 0);
>>> }
>>> static void svm_range_deferred_list_work(struct work_struct *work)
>>> @@ -2002,6 +2004,7 @@ static void
>>> svm_range_deferred_list_work(struct work_struct *work)
>>> * mmap write lock to serialize with munmap notifiers.
>>> */
>>> if (unlikely(READ_ONCE(svms->drain_pagefaults))) {
>>> + atomic_set(&svms->draining_faults, 1);
>>> WRITE_ONCE(svms->drain_pagefaults, false);
>>> mmap_write_unlock(mm);
>>> svm_range_drain_retry_fault(svms);
>>> @@ -2049,12 +2052,6 @@ svm_range_add_list_work(struct svm_range_list
>>> *svms, struct svm_range *prange,
>>> struct mm_struct *mm, enum svm_work_list_ops op)
>>> {
>>> spin_lock(&svms->deferred_list_lock);
>>> - /* Make sure pending page faults are drained in the deferred
>>> worker
>>> - * before the range is freed to avoid straggler interrupts on
>>> - * unmapped memory causing "phantom faults".
>>> - */
>>> - if (op == SVM_OP_UNMAP_RANGE)
>>> - svms->drain_pagefaults = true;
>>> /* if prange is on the deferred list */
>>> if (!list_empty(&prange->deferred_list)) {
>>> pr_debug("update exist prange 0x%p work op %d\n", prange,
>>> op);
>>> @@ -2133,6 +2130,13 @@ svm_range_unmap_from_cpu(struct mm_struct
>>> *mm, struct svm_range *prange,
>>> pr_debug("svms 0x%p prange 0x%p [0x%lx 0x%lx] [0x%lx
>>> 0x%lx]\n", svms,
>>> prange, prange->start, prange->last, start, last);
>>> + /* Make sure pending page faults are drained in the deferred
>>> worker
>>> + * before the range is freed to avoid straggler interrupts on
>>> + * unmapped memory causing "phantom faults".
>>> + */
>>> + pr_debug("set range drain_pagefaults true\n");
>>> + WRITE_ONCE(svms->drain_pagefaults, true);
>>> +
>>> unmap_parent = start <= prange->start && last >= prange->last;
>>> list_for_each_entry(pchild, &prange->child_list, child_list) {
>>> @@ -2595,6 +2599,13 @@ svm_range_restore_pages(struct amdgpu_device
>>> *adev, unsigned int pasid,
>>> mm = p->mm;
>>> mmap_write_lock(mm);
>>> + if (!!atomic_read(&svms->draining_faults) ||
>>> + READ_ONCE(svms->drain_pagefaults)) {
>>> + pr_debug("draining retry fault, drop fault 0x%llx\n", addr);
>>> + mmap_write_downgrade(mm);
>>> + goto out_unlock_mm;
>>> + }
>>> +
>>> vma = find_vma(p->mm, addr << PAGE_SHIFT);
>>> if (!vma || (addr << PAGE_SHIFT) < vma->vm_start) {
>>> pr_debug("VMA not found for address 0x%llx\n", addr);
>>> @@ -2732,6 +2743,7 @@ int svm_range_list_init(struct kfd_process *p)
>>> mutex_init(&svms->lock);
>>> INIT_LIST_HEAD(&svms->list);
>>> atomic_set(&svms->evicted_ranges, 0);
>>> + atomic_set(&svms->draining_faults, 0);
>>> INIT_DELAYED_WORK(&svms->restore_work, svm_range_restore_work);
>>> INIT_WORK(&svms->deferred_list_work,
>>> svm_range_deferred_list_work);
>>> INIT_LIST_HEAD(&svms->deferred_range_list);
next prev parent reply other threads:[~2021-11-18 16:39 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-17 3:43 [PATCH 1/3] drm/amdkfd: process exit and retry fault race Philip Yang
2021-11-17 3:43 ` [PATCH 2/3] drm/amdkfd: handle VMA remove race Philip Yang
2021-11-18 0:10 ` Felix Kuehling
2021-11-18 15:00 ` philip yang
2021-11-18 15:07 ` Felix Kuehling
2021-11-18 15:55 ` philip yang
2021-11-18 16:01 ` Felix Kuehling
2021-11-17 3:43 ` [PATCH 3/3] drm/amdkfd: simplify drain retry fault Philip Yang
2021-11-18 0:14 ` Felix Kuehling
2021-11-18 16:19 ` philip yang
2021-11-18 16:39 ` Felix Kuehling [this message]
2021-11-18 16:45 ` philip yang
2021-11-17 23:18 ` [PATCH 1/3] drm/amdkfd: process exit and retry fault race Felix Kuehling
2021-11-18 14:30 ` philip yang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=423b2831-ba9c-3239-574b-ae3ac8ebb112@amd.com \
--to=felix.kuehling@amd.com \
--cc=Philip.Yang@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=yangp@amd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox