<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p style="font-family:Arial;font-size:10pt;color:#0078D7;margin:15pt;" align="Left">
[AMD Official Use Only - Internal Distribution Only]<br>
</p>
<br>
<div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
I still hit page fault with option 1 while running oclperf test.<br>
</div>
<div dir="auto" style="direction: ltr; margin: 0; padding: 0; font-family: sans-serif; font-size: 11pt; color: black; ">
Looks like we need sync fence after commit.</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Tao, Yintian <Yintian.Tao@amd.com><br>
<b>Sent:</b> Monday, March 16, 2020 4:15:01 PM<br>
<b>To:</b> Pan, Xinhui <Xinhui.Pan@amd.com>; Koenig, Christian <Christian.Koenig@amd.com><br>
<b>Cc:</b> Deucher, Alexander <Alexander.Deucher@amd.com>; Kuehling, Felix <Felix.Kuehling@amd.com>; Pan, Xinhui <Xinhui.Pan@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Subject:</b> RE: [PATCH v4 2/2] drm/amdgpu: unref pt bo after job submit</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi Xinhui<br>
<br>
<br>
I encounter the same problem(page fault) when test vk_example benchmark.<br>
I use your first option which can fix the problem. Can you help submit one patch?<br>
<br>
<br>
-       if (flags & AMDGPU_PTE_VALID) {<br>
-               struct amdgpu_bo *root = vm->root.base.bo;<br>
-               if (!dma_fence_is_signaled(vm->last_direct))<br>
-                       amdgpu_bo_fence(root, vm->last_direct, true);<br>
+       if (!dma_fence_is_signaled(vm->last_direct))<br>
+               amdgpu_bo_fence(root, vm->last_direct, true);<br>
 <br>
-               if (!dma_fence_is_signaled(vm->last_delayed))<br>
-                       amdgpu_bo_fence(root, vm->last_delayed, true);<br>
-       }<br>
+       if (!dma_fence_is_signaled(vm->last_delayed))<br>
+               amdgpu_bo_fence(root, vm->last_delayed, true);<br>
<br>
<br>
Best Regards<br>
Yintian Tao<br>
<br>
-----Original Message-----<br>
From: amd-gfx <amd-gfx-bounces@lists.freedesktop.org> On Behalf Of Pan, Xinhui<br>
Sent: 2020年3月14日 21:07<br>
To: Koenig, Christian <Christian.Koenig@amd.com><br>
Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Kuehling, Felix <Felix.Kuehling@amd.com>; Pan, Xinhui <Xinhui.Pan@amd.com>; amd-gfx@lists.freedesktop.org<br>
Subject: Re: [PATCH v4 2/2] drm/amdgpu: unref pt bo after job submit<br>
<br>
hi, All<br>
I think I found the root cause. here is what happened.<br>
<br>
user: alloc/mapping memory<br>
          kernel: validate memory and update the bo mapping, and update the page table<br>
                        -> amdgpu_vm_bo_update_mapping<br>
                                -> amdgpu_vm_update_ptes<br>
                                        -> amdgpu_vm_alloc_pts<br>
                                                -> amdgpu_vm_clear_bo // it will submit a job and we have a fence. BUT it is NOT added in resv.<br>
user: free/unmapping memory<br>
                kernel: unmapping mmeory and udpate the page table<br>
                        -> amdgpu_vm_bo_update_mapping<br>
                        sync last_delay fence if flag & AMDGPU_PTE_VALID // of source we did not sync it here, as this is unmapping.<br>
                                -> amdgpu_vm_update_ptes<br>
                                        -> amdgpu_vm_free_pts // unref page table bo.<br>
<br>
So from the sequence above, we know there is a race betwen bo releasing and bo clearing.<br>
bo might have been released before job running.<br>
<br>
we can fix it in several ways,<br>
1) sync last_delay in both mapping and unmapping case.<br>
 Chris, you just sync last_delay in mapping case, should it be ok to sync it also in unmapping case?<br>
<br>
2) always add fence to resv after commit. <br>
 this is done by patchset v4. And only need patch 1. no need to move unref bo after commit.<br>
<br>
3) move unref bo after commit, and add the last delay fence to resv. <br>
This is done by patchset V1. <br>
<br>
<br>
any ideas?<br>
<br>
thanks<br>
xinhui<br>
<br>
> 2020年3月14日 02:05,Koenig, Christian <Christian.Koenig@amd.com> 写道:<br>
> <br>
> The page table is not updated and then freed. A higher level PDE is updated and because of this the lower level page tables is freed.<br>
> <br>
> Without this it could be that the memory backing the freed page table is reused while the PDE is still pointing to it.<br>
> <br>
> Rather unlikely that this causes problems, but better save than sorry.<br>
> <br>
> Regards,<br>
> Christian.<br>
> <br>
> Am 13.03.20 um 18:36 schrieb Felix Kuehling:<br>
>> This seems weird. This means that we update a page table, and then free it in the same amdgpu_vm_update_ptes call? That means the update is redundant. Can we eliminate the redundant PTE update if the page table is about to be freed anyway?<br>
>> <br>
>> Regards,<br>
>>   Felix<br>
>> <br>
>> On 2020-03-13 12:09, xinhui pan wrote:<br>
>>> Free page table bo before job submit is insane.<br>
>>> We might touch invalid memory while job is runnig.<br>
>>> <br>
>>> we now have individualized bo resv during bo releasing.<br>
>>> So any fences added to root PT bo is actually untested when a normal <br>
>>> PT bo is releasing.<br>
>>> <br>
>>> We might hit gmc page fault or memory just got overwrited.<br>
>>> <br>
>>> Cc: Christian König <christian.koenig@amd.com><br>
>>> Cc: Alex Deucher <alexander.deucher@amd.com><br>
>>> Cc: Felix Kuehling <Felix.Kuehling@amd.com><br>
>>> Signed-off-by: xinhui pan <xinhui.pan@amd.com><br>
>>> ---<br>
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 24 +++++++++++++++++++++---<br>
>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |  3 +++<br>
>>>   2 files changed, 24 insertions(+), 3 deletions(-)<br>
>>> <br>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c <br>
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c<br>
>>> index 73398831196f..346e2f753474 100644<br>
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c<br>
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c<br>
>>> @@ -937,6 +937,21 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,<br>
>>>       return r;<br>
>>>   }<br>
>>>   +static void amdgpu_vm_free_zombie_bo(struct amdgpu_device *adev,<br>
>>> +        struct amdgpu_vm *vm)<br>
>>> +{<br>
>>> +    struct amdgpu_vm_pt *entry;<br>
>>> +<br>
>>> +    while (!list_empty(&vm->zombies)) {<br>
>>> +        entry = list_first_entry(&vm->zombies, struct amdgpu_vm_pt,<br>
>>> +                base.vm_status);<br>
>>> +        list_del(&entry->base.vm_status);<br>
>>> +<br>
>>> +        amdgpu_bo_unref(&entry->base.bo->shadow);<br>
>>> +        amdgpu_bo_unref(&entry->base.bo);<br>
>>> +    }<br>
>>> +}<br>
>>> +<br>
>>>   /**<br>
>>>    * amdgpu_vm_free_table - fre one PD/PT<br>
>>>    *<br>
>>> @@ -945,10 +960,9 @@ static int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,<br>
>>>   static void amdgpu_vm_free_table(struct amdgpu_vm_pt *entry)<br>
>>>   {<br>
>>>       if (entry->base.bo) {<br>
>>> +        list_move(&entry->base.vm_status, <br>
>>> + &entry->base.bo->vm_bo->vm->zombies);<br>
>>>           entry->base.bo->vm_bo = NULL;<br>
>>> -        list_del(&entry->base.vm_status);<br>
>>> -        amdgpu_bo_unref(&entry->base.bo->shadow);<br>
>>> -        amdgpu_bo_unref(&entry->base.bo);<br>
>>>       }<br>
>>>       kvfree(entry->entries);<br>
>>>       entry->entries = NULL;<br>
>>> @@ -1624,6 +1638,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,<br>
>>>       r = vm->update_funcs->commit(&params, fence);<br>
>>>     error_unlock:<br>
>>> +    amdgpu_vm_free_zombie_bo(adev, vm);<br>
>>>       amdgpu_vm_eviction_unlock(vm);<br>
>>>       return r;<br>
>>>   }<br>
>>> @@ -2807,6 +2822,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,<br>
>>>       INIT_LIST_HEAD(&vm->invalidated);<br>
>>>       spin_lock_init(&vm->invalidated_lock);<br>
>>>       INIT_LIST_HEAD(&vm->freed);<br>
>>> +    INIT_LIST_HEAD(&vm->zombies);<br>
>>>           /* create scheduler entities for page table updates */ @@ <br>
>>> -3119,6 +3135,8 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)<br>
>>>       }<br>
>>>         amdgpu_vm_free_pts(adev, vm, NULL);<br>
>>> +    amdgpu_vm_free_zombie_bo(adev, vm);<br>
>>> +<br>
>>>       amdgpu_bo_unreserve(root);<br>
>>>       amdgpu_bo_unref(&root);<br>
>>>       WARN_ON(vm->root.base.bo);<br>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h <br>
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h<br>
>>> index b5705fcfc935..9baf44fa16f0 100644<br>
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h<br>
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h<br>
>>> @@ -269,6 +269,9 @@ struct amdgpu_vm {<br>
>>>       /* BO mappings freed, but not yet updated in the PT */<br>
>>>       struct list_head    freed;<br>
>>>   +    /* BO will be freed soon */<br>
>>> +    struct list_head    zombies;<br>
>>> +<br>
>>>       /* contains the page directory */<br>
>>>       struct amdgpu_vm_pt     root;<br>
>>>       struct dma_fence    *last_update;<br>
> <br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=02%7C01%7Cyintian.tao%40amd.com%7C580c8ec15d484bf546b208d7c8188cc2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637197880120611671&amp;sdata=dqSLasyuZhQskB38Kib6g8lQR9iMnyxFxfHGXXENoDc%3D&amp;reserved=0">https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&amp;data=02%7C01%7Cyintian.tao%40amd.com%7C580c8ec15d484bf546b208d7c8188cc2%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637197880120611671&amp;sdata=dqSLasyuZhQskB38Kib6g8lQR9iMnyxFxfHGXXENoDc%3D&amp;reserved=0</a><br>
</div>
</span></font></div>
</div>
</body>
</html>