<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> Christian König <ckoenig.leichtzumerken@gmail.com><br>
<b>Sent:</b> Wednesday, September 8, 2021 8:43 AM<br>
<b>To:</b> Lazar, Lijo <Lijo.Lazar@amd.com>; Yu, Lang <Lang.Yu@amd.com>; amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Deucher, Alexander <Alexander.Deucher@amd.com>; Huang, Ray <Ray.Huang@amd.com>; Tian Tao <tiantao6@hisilicon.com>; Powell, Darren <Darren.Powell@amd.com><br>
<b>Subject:</b> Re: [PATCH] drm/amdgpu: fix sysfs_emit/sysfs_emit_at warnings</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">Am 08.09.21 um 12:22 schrieb Lazar, Lijo:<br>
> On 9/8/2021 3:08 PM, Christian König wrote:<br>
>> Am 08.09.21 um 11:29 schrieb Lazar, Lijo:<br>
>>> On 9/8/2021 2:32 PM, Yu, Lang wrote:<br>
>>>> [AMD Official Use Only]<br>
>>>>> -----Original Message-----<br>
>>>>> From: Lazar, Lijo <Lijo.Lazar@amd.com><br>
>>>>> Sent: Wednesday, September 8, 2021 4:55 PM<br>
>>>>> To: Yu, Lang <Lang.Yu@amd.com>; Christian König<br>
>>>>> <ckoenig.leichtzumerken@gmail.com>; amd-gfx@lists.freedesktop.org<br>
>>>>> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Huang, Ray<br>
>>>>> <Ray.Huang@amd.com>; Tian Tao <tiantao6@hisilicon.com><br>
>>>>> Subject: Re: [PATCH] drm/amdgpu: fix sysfs_emit/sysfs_emit_at <br>
>>>>> warnings<br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>>> On 9/8/2021 1:14 PM, Yu, Lang wrote:<br>
>>>>>> [AMD Official Use Only]<br>
>>>>>><br>
>>>>>><br>
>>>>>><br>
>>>>>>> -----Original Message-----<br>
>>>>>>> From: Lazar, Lijo <Lijo.Lazar@amd.com><br>
>>>>>>> Sent: Wednesday, September 8, 2021 3:36 PM<br>
>>>>>>> To: Christian König <ckoenig.leichtzumerken@gmail.com>; Yu, Lang<br>
>>>>>>> <Lang.Yu@amd.com>; amd-gfx@lists.freedesktop.org<br>
>>>>>>> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>; Huang, Ray<br>
>>>>>>> <Ray.Huang@amd.com>; Tian Tao <tiantao6@hisilicon.com><br>
>>>>>>> Subject: Re: [PATCH] drm/amdgpu: fix sysfs_emit/sysfs_emit_at<br>
>>>>>>> warnings<br>
>>>>>>><br>
>>>>>>><br>
>>>>>>><br>
>>>>>>> On 9/8/2021 12:07 PM, Christian König wrote:<br>
>>>>>>>> Am 08.09.21 um 07:56 schrieb Lang Yu:<br>
>>>>>>>>> sysfs_emit and sysfs_emit_at requrie a page boundary aligned buf<br>
>>>>>>>>> address. Make them happy!<br>
>>>>>>>>><br>
>>>>>>>>> Warning Log:<br>
>>>>>>>>> [  492.545174] invalid sysfs_emit_at: buf:00000000f19bdfde at:0 [<br>
>>>>>>>>> 492.546416] WARNING: CPU: 7 PID: 1304 at fs/sysfs/file.c:765<br>
>>>>>>>>> sysfs_emit_at+0x4a/0xa0<br>
>>>>>>>>> [  492.654805] Call Trace:<br>
>>>>>>>>> [  492.655353]  ? smu_cmn_get_metrics_table+0x40/0x50 [amdgpu] [<br>
>>>>>>>>> 492.656780]  vangogh_print_clk_levels+0x369/0x410 [amdgpu] [<br>
>>>>>>>>> 492.658245] vangogh_common_print_clk_levels+0x77/0x80 [amdgpu] [<br>
>>>>>>>>> 492.659733]  ? preempt_schedule_common+0x18/0x30 [ 492.660713]<br>
>>>>>>>>> smu_print_ppclk_levels+0x65/0x90 [amdgpu] [ 492.662107]<br>
>>>>>>>>> amdgpu_get_pp_od_clk_voltage+0x13d/0x190 [amdgpu] [ 492.663620]<br>
>>>>>>>>> dev_attr_show+0x1d/0x40<br>
>>>>>>>><br>
>>>>>>>> Mhm, that at least partially doesn't looks like the right <br>
>>>>>>>> approach to me.<br>
>>>>>>>><br>
>>>>>>>> Why do we have string printing and sysfs code in the hardware<br>
>>>>>>>> version specific backend in the first place?<br>
>>>>>>>><br>
>>>>>>><br>
>>>>>>> This is a callback meant for printing ASIC specific information to<br>
>>>>>>> sysfs node. The buffer passed in sysfs read is passed as it is <br>
>>>>>>> to the callback API.<br>
>>>>>>><br>
>>>>>>>> That stuff needs to be implemented for each hardware generation <br>
>>>>>>>> and<br>
>>>>>>>> is now cluttered with sysfs buffer offset calculations.<br>
>>>>>>>><br>
>>>>>>><br>
>>>>>>> Looks like the warning happened because of this usage.<br>
>>>>>>><br>
>>>>>>>                   size = amdgpu_dpm_print_clock_levels(adev, <br>
>>>>>>> OD_SCLK, buf);<br>
>>>>>>>                   size += amdgpu_dpm_print_clock_levels(adev, <br>
>>>>>>> OD_MCLK,<br>
>>>>>>> buf+size);<br>
>>>>>>>                   size += amdgpu_dpm_print_clock_levels(adev,<br>
>>>>>>> OD_VDDC_CURVE, buf+size);<br>
>>>>>>>                   size += amdgpu_dpm_print_clock_levels(adev,<br>
>>>>>>> OD_VDDGFX_OFFSET, buf+size);<br>
>>>>>>>                   size += amdgpu_dpm_print_clock_levels(adev,<br>
>>>>>>> OD_RANGE,<br>
>>>>>>> buf+size);<br>
>>>>>>>                   size += amdgpu_dpm_print_clock_levels(adev, <br>
>>>>>>> OD_CCLK,<br>
>>>>>>> buf+size);<br>
>>>>>>><br>
>>>>>>><br>
>>>>>> [Yu, Lang]<br>
>>>>>> Yes. So it is fine we just fix the caller <br>
>>>>>> amdgpu_get_pp_od_clk_voltage like<br>
>>>>> following:<br>
>>>>>><br>
>>>>>> static ssize_t amdgpu_get_pp_od_clk_voltage(struct device *dev,<br>
>>>>>>         struct device_attribute *attr,<br>
>>>>>>         char *buf)<br>
>>>>>> {<br>
>>>>>>     struct drm_device *ddev = dev_get_drvdata(dev);<br>
>>>>>>     struct amdgpu_device *adev = drm_to_adev(ddev);<br>
>>>>>>     ssize_t size, offset;<br>
>>>>>>     int ret, i;<br>
>>>>>>     char temp_buf[512];<br>
>>>>>>     char clock_type[] = {OD_SCLK, OD_MCLK, OD_VDDC_CURVE,<br>
>>>>>>                          OD_VDDGFX_OFFSET, OD_RANGE, OD_CCLK};<br>
>>>>>><br>
>>>>>>     if (amdgpu_in_reset(adev))<br>
>>>>>>         return -EPERM;<br>
>>>>>>     if (adev->in_suspend && !adev->in_runpm)<br>
>>>>>>         return -EPERM;<br>
>>>>>><br>
>>>>>>     ret = pm_runtime_get_sync(ddev->dev);<br>
>>>>>>     if (ret < 0) {<br>
>>>>>>         pm_runtime_put_autosuspend(ddev->dev);<br>
>>>>>>         return ret;<br>
>>>>>>     }<br>
>>>>>><br>
>>>>>>     offset = 0;<br>
>>>>>><br>
>>>>>>     if (adev->powerplay.pp_funcs->print_clock_levels) {<br>
>>>>>>         for (i = 0; i < ARRAY_SIZE(clock_type); i++) {<br>
>>>>>>             size = amdgpu_dpm_print_clock_levels(adev,<br>
>>>>> clock_type[i], buf);<br>
>>>>>>             if (offset + size > PAGE_SIZE)<br>
>>>>>>                 break;<br>
>>>>>>             memcpy(temp_buf + offset, buf, size);<br>
>>>>>>             offset += size;<br>
>>>>>>         }<br>
>>>>>>         memcpy(buf, temp_buf, offset);<br>
>>>>>>         size = offset;<br>
>>>>>>     } else {<br>
>>>>>>         size = sysfs_emit(buf, "\n");<br>
>>>>>>     }<br>
>>>>>>     pm_runtime_mark_last_busy(ddev->dev);<br>
>>>>>>     pm_runtime_put_autosuspend(ddev->dev);<br>
>>>>>><br>
>>>>>>     return size;<br>
>>>>>> }<br>
>>>>>><br>
>>>>> Prefer to avoid any extra stack or heap usage for buffer. Maybe <br>
>>>>> another arg to<br>
>>>>> pass offset along with buf?<br>
>>>>><br>
>>>> [Yu, Lang]<br>
>>>> Actually, the buf address contains the offset(offset_in_page(buf)) .<br>
>>><br>
>>> Though it's not a problem based on codeflow, static analysis tools <br>
>>> might complain.<br>
>>><br>
>>>> Or we just rollback to sprintf/snprintf.<br>
>>>><br>
>>><br>
>>> snprintf with (PAGE_SIZE-size) may be simpler. I think Darren took <br>
>>> the effort to convert these, he may have some other ideas.<br>
The changes I made were intended to simply replace snprintf with sysfs_emit as per </div>
<div class="PlainText">linux/Documentation/filesystems/sysfs.rst:246,247
<div> -  show() should only use sysfs_emit() or sysfs_emit_at() when formatting</div>
    the value to be returned to user space.<br>
</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">I specifically tried not to change the design, but only as I didn't have </div>
<div class="PlainText">background in Power Management.</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">>><br>
>> This is not what I meant. See from the design point of view the <br>
>> print_clock_levels() callback is the bad idea to begin with.<br>
>><br>
>> What we should have instead is a callback which returns the clock as <br>
>> a value which is then printed in the amdgpu_get_pp_od_clk_voltage() <br>
>> function.<br>
>><br>
>> This avoids passing around the buffer and remaining size everywhere <br>
>> and also guarantees that the sysfs have unified printing over all <br>
>> hardware generations.<br>
>><br>
><br>
> The scenario is one node used for multiple parameters - OD_SCLK, <br>
> OD_CCLK, OD_VDDGFX_OFFSET etc.(mostly to avoid cluttering sysfs with <br>
> lots of nodes). On top of it, the parameters supported (for ex: CCLK <br>
> is not valid on dGPUs),  the number of levels supported etc. vary <br>
> across ASICs. There has to be multiple calls or the call needs to <br>
> return multiple values for a single parameter (for ex: up to 4, 8 or <br>
> 16 levels of GFXCLK depending on ASIC).<br>
<br>
Well exactly that is questionable design for sysfs.<br>
<br>
See the sysfs_emit() and sysfs_emit_at() functions are designed the way <br>
they are because you should have only one value per file, which is then <br>
printed at exactly one location.<br>
<br>
Take a look at the documentation for sysfs for more details.<br>
<br>
> I don't know the history of the callback, mostly it was considered <br>
> more efficient to print it directly rather than fetch and print. <br>
> Alex/Evan may know the details.<br>
<br>
Yeah, somebody with a bit more background in power management needs to <br>
take a closer look at this here. Just keep me looped in.<br>
<br>
Regards,<br>
Christian.<br>
<br>
><br>
> Thanks,<br>
> Lijo<br>
><br>
>> Regards,<br>
>> Christian.<br>
>><br>
<br>
</div>
</span></font></div>
</div>
</body>
</html>