<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:10pt;color:#0000FF;margin:5pt;" align="Left">
[AMD Official Use Only]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Kuehling, Felix <Felix.Kuehling@amd.com><br>
<b>Sent:</b> Thursday, April 21, 2022 5:21 AM<br>
<b>To:</b> Lazar, Lijo <Lijo.Lazar@amd.com>; Koenig, Christian <Christian.Koenig@amd.com>; Wang, Yang(Kevin) <KevinYang.Wang@amd.com>; Christian König <ckoenig.leichtzumerken@gmail.com>; dri-devel@lists.freedesktop.org <dri-devel@lists.freedesktop.org>; amd-gfx@lists.freedesktop.org
 <amd-gfx@lists.freedesktop.org><br>
<b>Subject:</b> Re: [PATCH] drm/ttm: fix ttm tt init fail when size exceeds kmalloc limit</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText elementToProof"><br>
On 2022-04-20 09:23, Lazar, Lijo wrote:<br>
><br>
><br>
> On 4/20/2022 6:26 PM, Christian König wrote:<br>
>> Am 20.04.22 um 14:54 schrieb Wang, Yang(Kevin):<br>
>>><br>
>>> [AMD Official Use Only]<br>
>>><br>
>>><br>
>>> Hi Chris,<br>
>>><br>
>>> 1) Change the test case to use something larger than 1TiB.<br>
>>> sure, we can increase the size of BO and make test pass,<br>
>>> but if user really want to allocate 1TB GTT BO, we have no reason to <br>
>>> let it fail? right?<br>
>><br>
>> No, the reason is the underlying core kernel doesn't allow kvmalloc <br>
>> allocations with GFP_ZERO which are large enough to hold the array of <br>
>> allocated pages for this.<br>
>><br>
>> We are working on top of the core Linux kernel and should *NEVER* <br>
>> ever add workarounds like what was suggested here. ><br>
><br>
> AFAIU, for the purpose of ttm use, fallback to vmalloc is fine.<br>
><br>
>  * Please note that any use of gfp flags outside of GFP_KERNEL is <br>
> careful to not<br>
>  * fall back to vmalloc.<br>
>  *<br>
<br>
That's weird, because kvcalloc does the same thing. If that were not <br>
able to fall back to vmalloc, it would be pretty useless.<br>
<br>
    static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, gfp_t flags)<br>
    {<br>
             return kvmalloc_array(n, size, flags | __GFP_ZERO);<br>
    }<br>
<br>
Maybe kvcalloc is the function we TTM should be using here anyway, <br>
instead of open-coding the kvmalloc_array call with an extra GFP flag.<br>
<br>
Regards,<br>
   Felix</div>
<div class="PlainText elementToProof"><br>
</div>
<div class="PlainText elementToProof">Yes, I agree with your point, and in amdkfd driver code, we have the same risk in svm_range_dma_map_dev().<br>
<br>
Best Regards,<br>
Kevin<br>
<br>
><br>
> Actually the current implementation documents the behavior, but it is <br>
> deep inside the implementation to be noticeable - at least not obvious <br>
> while using kvmalloc_array.<br>
><br>
> Thanks,<br>
> Lijo<br>
><br>
>> Regards,<br>
>> Christian.<br>
>><br>
>>> the system availed memory about 2T, but it will still fail.<br>
>>><br>
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc <br>
>>> fallback path.<br>
>>>     the 5.18 kernel will add this patch to fix this issue .<br>
>>><br>
>>> Best Regards,<br>
>>> Kevin<br>
>>> ------------------------------------------------------------------------ <br>
>>><br>
>>> *From:* Koenig, Christian <Christian.Koenig@amd.com><br>
>>> *Sent:* Wednesday, April 20, 2022 8:42 PM<br>
>>> *To:* Wang, Yang(Kevin) <KevinYang.Wang@amd.com>; Christian König <br>
>>> <ckoenig.leichtzumerken@gmail.com>; dri-devel@lists.freedesktop.org <br>
>>> <dri-devel@lists.freedesktop.org>; amd-gfx@lists.freedesktop.org <br>
>>> <amd-gfx@lists.freedesktop.org><br>
>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size <br>
>>> exceeds kmalloc limit<br>
>>> Hi Kevin,<br>
>>><br>
>>> yes and that is perfectly valid and expected behavior. There is <br>
>>> absolutely no need to change anything in TTM here.<br>
>>><br>
>>> What we could do is:<br>
>>> 1) Change the test case to use something larger than 1TiB.<br>
>>> 2) Change kvmalloc to allow GFP_ZERO allocations even in the vmalloc <br>
>>> fallback path.<br>
>>><br>
>>> Regards,<br>
>>> Christian.<br>
>>><br>
>>> Am 20.04.22 um 14:39 schrieb Wang, Yang(Kevin):<br>
>>>><br>
>>>> [AMD Official Use Only]<br>
>>>><br>
>>>><br>
>>>> Hi Chirs,<br>
>>>><br>
>>>> yes, right, the amdgpu drive rwill use amdgpu_bo_validate_size() <br>
>>>> function to verify bo size,<br>
>>>> but when driver try to allocate VRAM domain bo fail, the amdgpu <br>
>>>> driver will fall back to allocate domain = (GTT | VRAM)  bo.<br>
>>>> please check following code, it will cause the 2nd time to allocate <br>
>>>> bo fail during allocate 256Mb buffer to store dma address (via <br>
>>>> kvmalloc()).<br>
>>>><br>
>>>> initial_domain = (u32)(0xffffffff & args->in.domains);<br>
>>>> retry:<br>
>>>>         r = amdgpu_gem_object_create(adev, size, args->in.alignment,<br>
>>>>                    initial_domain,<br>
>>>>                    flags, ttm_bo_type_device, resv, &gobj);<br>
>>>>         if (r && r != -ERESTARTSYS) {<br>
>>>>                 if (flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) {<br>
>>>>       flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;<br>
>>>>       goto retry;<br>
>>>>                 }<br>
>>>><br>
>>>>                 if (initial_domain == AMDGPU_GEM_DOMAIN_VRAM) {<br>
>>>>       initial_domain |= AMDGPU_GEM_DOMAIN_GTT;<br>
>>>>       goto retry;<br>
>>>>                 }<br>
>>>> DRM_DEBUG("Failed to allocate GEM object (%llu, %d, %llu, %d)\n",<br>
>>>>               size, initial_domain, args->in.alignment, r);<br>
>>>>         }<br>
>>>><br>
>>>> Best Regards,<br>
>>>> Kevin<br>
>>>><br>
>>>> ------------------------------------------------------------------------ <br>
>>>><br>
>>>> *From:* Christian König <ckoenig.leichtzumerken@gmail.com> <br>
>>>> <<a href="mailto:ckoenig.leichtzumerken@gmail.com" data-auth="NotApplicable">mailto:ckoenig.leichtzumerken@gmail.com</a>><br>
>>>> *Sent:* Wednesday, April 20, 2022 7:55 PM<br>
>>>> *To:* Wang, Yang(Kevin) <KevinYang.Wang@amd.com> <br>
>>>> <<a href="mailto:KevinYang.Wang@amd.com" data-auth="NotApplicable">mailto:KevinYang.Wang@amd.com</a>>; Koenig, Christian
<br>
>>>> <Christian.Koenig@amd.com> <<a href="mailto:Christian.Koenig@amd.com" data-auth="NotApplicable">mailto:Christian.Koenig@amd.com</a>>;
<br>
>>>> dri-devel@lists.freedesktop.org <br>
>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>
<br>
>>>> <dri-devel@lists.freedesktop.org> <br>
>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>;
<br>
>>>> amd-gfx@lists.freedesktop.org <br>
>>>> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>>
<br>
>>>> <amd-gfx@lists.freedesktop.org> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>><br>
>>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size <br>
>>>> exceeds kmalloc limit<br>
>>>> Hi Kevin,<br>
>>>><br>
>>>> no, the test case should already fail in amdgpu_bo_validate_size().<br>
>>>><br>
>>>> If we have a system with 2TiB of memory where the test case could <br>
>>>> succeed then we should increase the requested size to something <br>
>>>> larger.<br>
>>>><br>
>>>> And if the underlying core Linux kernel functions don't allow <br>
>>>> allocations as large as the requested one we should *NEVER* ever <br>
>>>> add workarounds like this.<br>
>>>><br>
>>>> It is perfectly expected that this test case is not able to fulfill <br>
>>>> the desired allocation. That it fails during kvmalloc is <br>
>>>> unfortunate, but not a show stopper.<br>
>>>><br>
>>>> Regards,<br>
>>>> Christian.<br>
>>>><br>
>>>><br>
>>>> Am 20.04.22 um 13:32 schrieb Wang, Yang(Kevin):<br>
>>>>><br>
>>>>> [AMD Official Use Only]<br>
>>>>><br>
>>>>><br>
>>>>> Hi Chris,<br>
>>>>><br>
>>>>> you misunderstood background about this case.<br>
>>>>><br>
>>>>> although we expect this test case to fail, it should fail at the <br>
>>>>> location where the Bo actual memory is actually allocated. now the <br>
>>>>> code logic will cause the failure to allocate memory to store DMA <br>
>>>>> address.<br>
>>>>><br>
>>>>> e.g: the case is failed in 2TB system ram machine, it should be <br>
>>>>> allocated successful, but it is failed.<br>
>>>>><br>
>>>>> allocate 1TB BO, the ttm should allocate 1TB/4k * 8 buffer to <br>
>>>>> store allocate result (page address), this should not be failed <br>
>>>>> usually.<br>
>>>>><br>
>>>>> There is a similar fix in upstream kernel 5.18, before this fix <br>
>>>>> entered the TTM code, this problem existed in TTM.<br>
>>>>><br>
>>>>> kernel/git/torvalds/linux.git - Linux kernel source tree <br>
>>>>> <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.18-rc3&id=a421ef303008b0ceee2cfc625c3246fa7654b0ca<br>
>>>>> mm: allow !GFP_KERNEL allocations for kvmalloc<br>
>>>>><br>
>>>>> Best Regards,<br>
>>>>> Kevin<br>
>>>>><br>
>>>>> ------------------------------------------------------------------------ <br>
>>>>><br>
>>>>> *From:* Koenig, Christian <Christian.Koenig@amd.com> <br>
>>>>> <<a href="mailto:Christian.Koenig@amd.com" data-auth="NotApplicable">mailto:Christian.Koenig@amd.com</a>><br>
>>>>> *Sent:* Wednesday, April 20, 2022 6:53 PM<br>
>>>>> *To:* Wang, Yang(Kevin) <KevinYang.Wang@amd.com> <br>
>>>>> <<a href="mailto:KevinYang.Wang@amd.com" data-auth="NotApplicable">mailto:KevinYang.Wang@amd.com</a>>; dri-devel@lists.freedesktop.org
<br>
>>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>
<br>
>>>>> <dri-devel@lists.freedesktop.org> <br>
>>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>;
<br>
>>>>> amd-gfx@lists.freedesktop.org <br>
>>>>> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>>
<br>
>>>>> <amd-gfx@lists.freedesktop.org> <br>
>>>>> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>><br>
>>>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size <br>
>>>>> exceeds kmalloc limit<br>
>>>>> Am 20.04.22 um 11:07 schrieb Wang, Yang(Kevin):<br>
>>>>>><br>
>>>>>> [AMD Official Use Only]<br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>>> ------------------------------------------------------------------------ <br>
>>>>>><br>
>>>>>> *From:* Koenig, Christian <Christian.Koenig@amd.com> <br>
>>>>>> <<a href="mailto:Christian.Koenig@amd.com" data-auth="NotApplicable">mailto:Christian.Koenig@amd.com</a>><br>
>>>>>> *Sent:* Wednesday, April 20, 2022 5:00 PM<br>
>>>>>> *To:* Wang, Yang(Kevin) <KevinYang.Wang@amd.com> <br>
>>>>>> <<a href="mailto:KevinYang.Wang@amd.com" data-auth="NotApplicable">mailto:KevinYang.Wang@amd.com</a>>; dri-devel@lists.freedesktop.org
<br>
>>>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>
<br>
>>>>>> <dri-devel@lists.freedesktop.org> <br>
>>>>>> <<a href="mailto:dri-devel@lists.freedesktop.org" data-auth="NotApplicable">mailto:dri-devel@lists.freedesktop.org</a>>;
<br>
>>>>>> amd-gfx@lists.freedesktop.org <br>
>>>>>> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>>
<br>
>>>>>> <amd-gfx@lists.freedesktop.org> <br>
>>>>>> <<a href="mailto:amd-gfx@lists.freedesktop.org" data-auth="NotApplicable">mailto:amd-gfx@lists.freedesktop.org</a>><br>
>>>>>> *Subject:* Re: [PATCH] drm/ttm: fix ttm tt init fail when size <br>
>>>>>> exceeds kmalloc limit<br>
>>>>>> Am 20.04.22 um 10:56 schrieb Yang Wang:<br>
>>>>>> > if the __GFP_ZERO is set, the kvmalloc() can't fallback to use <br>
>>>>>> vmalloc()<br>
>>>>>><br>
>>>>>> Hui what? Why should kvmalloc() not be able to fallback to vmalloc()<br>
>>>>>> when __GFP_ZERO is set?<br>
>>>>>><br>
>>>>>> And even that is really the case then that sounds like a bug in <br>
>>>>>> kvmalloc().<br>
>>>>>><br>
>>>>>> Regards,<br>
>>>>>> Christian.<br>
>>>>>><br>
>>>>>> [kevin]:<br>
>>>>>> it is really test case from libdrm amdgpu test, which try to <br>
>>>>>> allocate a big BO which will cause ttm tt init fail.<br>
>>>>><br>
>>>>><br>
>>>>> LOL! Guys, this test case is intended to fail!<br>
>>>>> *<br>
>>>>> *The test consists of allocating a buffer so ridiculous large that <br>
>>>>> it should never succeed and be rejected by the kernel driver.<br>
>>>>><br>
>>>>> This patch here is a really clear NAK.<br>
>>>>><br>
>>>>> Regards,<br>
>>>>> Christian.<br>
>>>>><br>
>>>>>> it may be a kvmalloc() bug, and this patch can as a workaround <br>
>>>>>> in ttm before this issue fix.<br>
>>>>>><br>
>>>>>> void *kvmalloc_node(size_t size, gfp_t flags, int node)<br>
>>>>>> {<br>
>>>>>> ...<br>
>>>>>>       if ((flags & GFP_KERNEL) != GFP_KERNEL)<br>
>>>>>>               return kmalloc_node(size, flags, node);<br>
>>>>>> ...<br>
>>>>>> }<br>
>>>>>><br>
>>>>>> Best Regards,<br>
>>>>>> Kevin<br>
>>>>>><br>
>>>>>> > to allocate memory, when request size is exceeds kmalloc limit, <br>
>>>>>> it will<br>
>>>>>> > cause allocate memory fail.<br>
>>>>>> ><br>
>>>>>> > e.g: when ttm want to create a BO with 1TB size, it maybe fail.<br>
>>>>>> ><br>
>>>>>> > Signed-off-by: Yang Wang <KevinYang.Wang@amd.com> <br>
>>>>>> <<a href="mailto:KevinYang.Wang@amd.com" data-auth="NotApplicable">mailto:KevinYang.Wang@amd.com</a>><br>
>>>>>> > ---<br>
>>>>>> >   drivers/gpu/drm/ttm/ttm_tt.c | 14 +++++++++++---<br>
>>>>>> >   1 file changed, 11 insertions(+), 3 deletions(-)<br>
>>>>>> ><br>
>>>>>> > diff --git a/drivers/gpu/drm/ttm/ttm_tt.c <br>
>>>>>> b/drivers/gpu/drm/ttm/ttm_tt.c<br>
>>>>>> > index 79c870a3bef8..9f2f3e576b8d 100644<br>
>>>>>> > --- a/drivers/gpu/drm/ttm/ttm_tt.c<br>
>>>>>> > +++ b/drivers/gpu/drm/ttm/ttm_tt.c<br>
>>>>>> > @@ -97,9 +97,12 @@ int ttm_tt_create(struct ttm_buffer_object <br>
>>>>>> *bo, bool zero_alloc)<br>
>>>>>> >   static int ttm_tt_alloc_page_directory(struct ttm_tt *ttm)<br>
>>>>>> >   {<br>
>>>>>> >        ttm->pages = kvmalloc_array(ttm->num_pages, sizeof(void*),<br>
>>>>>> > -                     GFP_KERNEL | __GFP_ZERO);<br>
>>>>>> > + GFP_KERNEL);<br>
>>>>>> >        if (!ttm->pages)<br>
>>>>>> >                return -ENOMEM;<br>
>>>>>> > +<br>
>>>>>> > +     memset(ttm->pages, 0, ttm->num_pages * sizeof(void *));<br>
>>>>>> > +<br>
>>>>>> >        return 0;<br>
>>>>>> >   }<br>
>>>>>> ><br>
>>>>>> > @@ -108,10 +111,12 @@ static int <br>
>>>>>> ttm_dma_tt_alloc_page_directory(struct ttm_tt *ttm)<br>
>>>>>> >        ttm->pages = kvmalloc_array(ttm->num_pages,<br>
>>>>>> > sizeof(*ttm->pages) +<br>
>>>>>> > sizeof(*ttm->dma_address),<br>
>>>>>> > - GFP_KERNEL | __GFP_ZERO);<br>
>>>>>> > + GFP_KERNEL);<br>
>>>>>> >        if (!ttm->pages)<br>
>>>>>> >                return -ENOMEM;<br>
>>>>>> ><br>
>>>>>> > +     memset(ttm->pages, 0, ttm->num_pages * <br>
>>>>>> (sizeof(*ttm->pages) + sizeof(*ttm->dma_address)));<br>
>>>>>> > +<br>
>>>>>> >        ttm->dma_address = (void *)(ttm->pages + ttm->num_pages);<br>
>>>>>> >        return 0;<br>
>>>>>> >   }<br>
>>>>>> > @@ -120,9 +125,12 @@ static int <br>
>>>>>> ttm_sg_tt_alloc_page_directory(struct ttm_tt *ttm)<br>
>>>>>> >   {<br>
>>>>>> >        ttm->dma_address = kvmalloc_array(ttm->num_pages,<br>
>>>>>> > sizeof(*ttm->dma_address),<br>
>>>>>> > - GFP_KERNEL | __GFP_ZERO);<br>
>>>>>> > + GFP_KERNEL);<br>
>>>>>> >        if (!ttm->dma_address)<br>
>>>>>> >                return -ENOMEM;<br>
>>>>>> > +<br>
>>>>>> > +     memset(ttm->dma_address, 0, ttm->num_pages * <br>
>>>>>> sizeof(*ttm->dma_address));<br>
>>>>>> > +<br>
>>>>>> >        return 0;<br>
>>>>>> >   }<br>
>>>>>> ><br>
>>>>>><br>
>>>>><br>
>>>><br>
>>><br>
>><br>
</div>
</span></font></div>
</div>
</body>
</html>