<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="en-CN" link="#467886" vlink="#96607D" style="word-wrap:break-word">
<div class="WordSection1">
<div>
<p class="MsoNormal"><br>
On 2025/5/21 16:06, Christian König wrote:<br>
> On 5/20/25 07:10, Zhang, GuoQing (Sam) wrote:<br>
>>>> +    if (amdgpu_virt_xgmi_migrate_enabled(adev)) {<br>
>>>> +            /* set mc->vram_start to 0 to switch the returned GPU address of<br>
>>>> +             * amdgpu_bo_create_reserved() from FB aperture to GART aperture.<br>
>>>> +             */<br>
>>>> +            amdgpu_gmc_vram_location(adev, mc, 0);<br>
>>> This function does a lot more than just setting mc->vram_start and mc->vram_end.<br>
>>><br>
>>> You should probably just update the two setting and not call amdgpu_gmc_vram_location() at all.<br>
>> I tried only setting mc->vram_start and mc->vram_end. But KMD load will<br>
>> fail with following error logs.<br>
>><br>
>> [  329.314346] amdgpu 0000:09:00.0: amdgpu: VRAM: 196288M<br>
>> 0x0000000000000000 - 0x0000002FEBFFFFFF (196288M used)<br>
>> [  329.314348] amdgpu 0000:09:00.0: amdgpu: GART: 512M<br>
>> 0x0000018000000000 - 0x000001801FFFFFFF<br>
>> [  329.314385] [drm] Detected VRAM RAM=196288M, BAR=262144M<br>
>> [  329.314386] [drm] RAM width 8192bits HBM<br>
>> [  329.314546] amdgpu 0000:09:00.0: amdgpu: (-22) failed to allocate<br>
>> kernel bo<br>
>> [  329.315013] [drm:amdgpu_device_init [amdgpu]] *ERROR* sw_init of IP<br>
>> block <gmc_v9_0> failed -22<br>
>> [  329.315846] amdgpu 0000:09:00.0: amdgpu: amdgpu_device_ip_init failed<br>
>><br>
>><br>
>> It seems like setting mc->visible_vram_size and mc->visible_vram_size<br>
>> fields are also needed. In this case call amdgpu_gmc_vram_location() is<br>
>> better than inline the logic, I think.<br>
> Yeah, exactly that is not a good idea.<br>
><br>
> The mc->visible_vram_size and mc->real_vram_size should have been initialized by gmc_v9_0_mc_init(). Why didn't that happen?<br>
<br>
<br>
[Sam] visible_vram_size is set to 0x4000000000 (256G) from <br>
`pci_resource_len(adev->pdev, 0)` in `gmc_v9_0_mc_init()`.<br>
It is set to real_vram_size 0x2fec000000(192G) in <br>
amdgpu_gmc_vram_location().<br>
<br>
Should I update the 3 variables inline and not call <br>
amdgpu_gmc_vram_location()?<br>
<br>
         mc->vram_start = 0;<br>
         mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;<br>
         if (mc->real_vram_size < mc->visible_vram_size)<br>
             mc->visible_vram_size = mc->real_vram_size;<br>
<br>
<br>
><br>
>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c<br>
>>>> index 84cde1239ee4..18e80aa78aff 100644<br>
>>>> --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c<br>
>>>> +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c<br>
>>>> @@ -45,8 +45,10 @@ static u64 mmhub_v1_8_get_fb_location(struct amdgpu_device *adev)<br>
>>>>         top &= MC_VM_FB_LOCATION_TOP__FB_TOP_MASK;<br>
>>>>         top <<= 24;<br>
>>>>    <br>
>>>> -    adev->gmc.fb_start = base;<br>
>>>> -    adev->gmc.fb_end = top;<br>
>>>> +    if (!amdgpu_virt_xgmi_migrate_enabled(adev)) {<br>
>>>> +            adev->gmc.fb_start = base;<br>
>>>> +            adev->gmc.fb_end = top;<br>
>>>> +    }<br>
>>> We should probably avoid calling this in the first place.<br>
>>><br>
>>> The function gmc_v9_0_vram_gtt_location() should probably be adjusted.<br>
>> mmhub_v1_8_get_fb_location() is called by the new<br>
>> amdgpu_bo_fb_aper_addr() as well, not just gmc_v9_0_vram_gtt_location().<br>
> Oh, that is probably a bad idea. The function amdgpu_bo_fb_aper_addr() should only rely on cached data.<br>
<br>
<br>
[Sam] Can I add new `fb_base` field in `struct amdgpu_gmc` to cache the <br>
value of `get_fb_location()`?<br>
Using this approach, we don't need to set fb_start and fb_end on resume <br>
any more, since the reset of the 2 field is caused by <br>
mmhub_v1_8_get_fb_location() calls from amdgpu_bo_fb_aper_addr().<br>
Please see the code change below.<br>
<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h<br>
@@ -259,6 +259,7 @@ struct amdgpu_gmc {<br>
          */<br>
         u64                     fb_start;<br>
         u64                     fb_end;<br>
+       u64                     fb_base;<br>
         unsigned                vram_width;<br>
         u64                     real_vram_size;<br>
         int                     vram_mtrr;<br>
<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c<br>
@@ -1527,7 +1527,7 @@ u64 amdgpu_bo_fb_aper_addr(struct amdgpu_bo *bo)<br>
<br>
         WARN_ON_ONCE(bo->tbo.resource->mem_type != TTM_PL_VRAM);<br>
<br>
-       fb_base = adev->mmhub.funcs->get_fb_location(adev);<br>
+       fb_base = adev->gmc.fb_base;<br>
         fb_base += adev->gmc.xgmi.physical_node_id * <br>
adev->gmc.xgmi.node_segment_size;<br>
         offset = (bo->tbo.resource->start << PAGE_SHIFT) + fb_base;<br>
         return amdgpu_gmc_sign_extend(offset);<br>
<br>
--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c<br>
@@ -1728,6 +1728,7 @@ static void gmc_v9_0_vram_gtt_location(struct <br>
amdgpu_device *adev,<br>
                                         struct amdgpu_gmc *mc)<br>
  {<br>
         u64 base = adev->mmhub.funcs->get_fb_location(adev);<br>
+       mc->fb_base = base;<br>
<br>
         /* add the xgmi offset of the physical node */<br>
         base += adev->gmc.xgmi.physical_node_id * <br>
adev->gmc.xgmi.node_segment_size;<br>
<br>
--- a/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v1_8.c<br>
@@ -45,10 +45,8 @@ static u64 mmhub_v1_8_get_fb_location(struct <br>
amdgpu_device *adev)<br>
         top &= MC_VM_FB_LOCATION_TOP__FB_TOP_MASK;<br>
         top <<= 24;<br>
<br>
-       if (!amdgpu_virt_xgmi_migrate_enabled(adev)) {<br>
-               adev->gmc.fb_start = base;<br>
-               adev->gmc.fb_end = top;<br>
-       }<br>
+       adev->gmc.fb_start = base;<br>
+       adev->gmc.fb_end = top;<br>
<br>
<br>
Regards<br>
Sam<br>
<br>
<br>
><br>
>> mmhub_v1_8_get_fb_location() is supposed to be a query api according to<br>
>> its name. having such side effect is very surprising.<br>
>><br>
>> Another approach is set the right fb_start and fb_end in the new<br>
>> amdgpu_virt_resume(), like updating vram_base_offset.<br>
> That is probably better. And skip setting fb_start and fb_end in amdgpu_gmc_sysvm_location() for this use case.<br>
><br>
> That was done only because we re-program those registers on bare metal.<br>
><br>
> Regards,<br>
> Christian.<br>
><br>
>> Which approach do you prefer? Or any better suggestions? Thank you.<br>
>><br>
>><br>
>> Regards<br>
>> Sam<br>
>><br>
>><br>
>><br>
>>> Regards,<br>
>>> Christian.<br>
>>><br>
>>>>    <br>
>>>>         return base;<br>
>>>>     }<o:p></o:p></p>
</div>
</div>
</body>
</html>