<html xmlns:v="urn:schemas-microsoft-com:vml" 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;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
span.EmailStyle19
        {mso-style-type:personal-compose;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<p class="msipheadera4477989" align="Left" style="margin:0"><span style="font-size:10.0pt;font-family:Arial;color:#0000FF">[AMD Official Use Only]</span></p>
<br>
<div class="WordSection1">
<p><o:p> </o:p></p>
<div>
<p class="MsoNormal">On 2/21/2022 7:58 PM, Christian König wrote:<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Am 21.02.22 um 15:19 schrieb Somalapuram, Amaranath: <br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">[AMD Official Use Only] <br>
<br>
<br>
On 2/21/2022 7:09 PM, Christian König wrote: <br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><br>
Am 21.02.22 um 14:34 schrieb Somalapuram Amaranath: <br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">List of register populated for dump collection during the GPU reset.
<br>
<br>
Signed-off-by: Somalapuram Amaranath <a href="mailto:Amaranath.Somalapuram@amd.com">
<Amaranath.Somalapuram@amd.com></a> <br>
--- <br>
   drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  4 + <br>
   drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 96 +++++++++++++++++++++ <br>
   2 files changed, 100 insertions(+) <br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h <br>
b/drivers/gpu/drm/amd/amdgpu/amdgpu.h <br>
index b85b67a88a3d..6e35f2c4c869 100644 <br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h <br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h <br>
@@ -1097,6 +1097,10 @@ struct amdgpu_device { <br>
         struct amdgpu_reset_control     *reset_cntl; <br>
       uint32_t ip_versions[HW_ID_MAX][HWIP_MAX_INSTANCE]; <br>
+ <br>
+    /* reset dump register */ <br>
+    uint32_t            *reset_dump_reg_list; <br>
+    int                             num_regs; <br>
   }; <br>
     static inline struct amdgpu_device *drm_to_adev(struct drm_device <br>
*ddev) <br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c <br>
b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c <br>
index 164d6a9e9fbb..69c0a28deeac 100644 <br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c <br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c <br>
@@ -1609,6 +1609,100 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL, <br>
   DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL, <br>
               amdgpu_debugfs_sclk_set, "%llu\n"); <br>
   +static ssize_t amdgpu_reset_dump_register_list_read(struct file *f, <br>
+                char __user *buf, size_t size, loff_t *pos) <br>
+{ <br>
+    struct amdgpu_device *adev = (struct amdgpu_device <br>
*)file_inode(f)->i_private; <br>
+    char reg_offset[11]; <br>
+    int i, ret, len = 0; <br>
+ <br>
+    if (*pos) <br>
+        return 0; <br>
+ <br>
+    ret = down_read_killable(&adev->reset_sem); <br>
+ <br>
+    if (ret) <br>
+        return ret; <o:p></o:p></p>
</blockquote>
<p class="MsoNormal">We usually don't have an empty line between function call and checking
<br>
the return code. <br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">+ <br>
+    for (i = 0; i < adev->num_regs; i++) { <br>
+        down_read(&adev->reset_sem); <o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom:12.0pt">That here will just crash because we have already locked the semaphore
<br>
before the loop. <o:p></o:p></p>
</blockquote>
<p class="MsoNormal">unfortunately it did not crash. Sorry I misunderstood your earlier comments.
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">+        sprintf(reg_offset, "0x%x ", adev->reset_dump_reg_list[i]);
<br>
+        up_read(&adev->reset_sem); <br>
+        ret = copy_to_user(buf + len, reg_offset, strlen(reg_offset)); <br>
+ <br>
+        if (ret) <br>
+            goto error; <br>
+ <br>
+        len += strlen(reg_offset); <o:p></o:p></p>
</blockquote>
<p class="MsoNormal">And here the down_read_killable() is missing. <br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">+    } <br>
+ <br>
+    up_read(&adev->reset_sem); <br>
+    ret = copy_to_user(buf + len, "\n", 1); <br>
+ <br>
+    if (ret) <br>
+        return -EFAULT; <br>
+ <br>
+    len++; <br>
+    *pos += len; <br>
+ <br>
+    return len; <br>
+error: <br>
+    up_read(&adev->reset_sem); <br>
+    return -EFAULT; <br>
+} <br>
+ <br>
+static ssize_t amdgpu_reset_dump_register_list_write(struct file *f, <br>
+            const char __user *buf, size_t size, loff_t *pos) <br>
+{ <br>
+    struct amdgpu_device *adev = (struct amdgpu_device <br>
*)file_inode(f)->i_private; <br>
+    char *reg_offset, *reg, reg_temp[11]; <br>
+    uint32_t *tmp; <br>
+    int ret, i = 0, len = 0; <br>
+ <br>
+    do { <br>
+        reg_offset = reg_temp; <o:p></o:p></p>
</blockquote>
<p class="MsoNormal" style="margin-bottom:12.0pt">I think you can just drop the reg_offset variable;
<o:p></o:p></p>
</blockquote>
<p class="MsoNormal">strsep takes only pointer as input, this is workaround. <o:p>
</o:p></p>
</blockquote>
<p class="MsoNormal"><br>
Ah, now I see what you are doing here. <br>
<br>
Please don't do it like that. Better use memchr() instead. <o:p></o:p></p>
</blockquote>
<p>memchr will not work. I couldn't find any other string API I can use.<o:p></o:p></p>
<p>other references similar to code:<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:blue">static</span><span style="font-size:10.5pt;font-family:Consolas;color:black">
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">void</span><span style="font-size:10.5pt;font-family:Consolas;color:black"> amdgpu_device_enable_virtual_display(</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">struct</span><span style="font-size:10.5pt;font-family:Consolas;color:black">
 amdgpu_device *adev)<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">{<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">    adev->enable_virtual_display =
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">false</span><span style="font-size:10.5pt;font-family:Consolas;color:black">;<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">   
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">if</span><span style="font-size:10.5pt;font-family:Consolas;color:black"> (amdgpu_virtual_display) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">const</span><span style="font-size:10.5pt;font-family:Consolas;color:black">
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">char</span><span style="font-size:10.5pt;font-family:Consolas;color:black"> *pci_address_name = pci_name(adev->pdev);<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">char</span><span style="font-size:10.5pt;font-family:Consolas;color:black"> *pciaddstr, *pciaddstr_tmp, *pciaddname_tmp, *pciaddname;<o:p></o:p></span></p>
</div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">        pciaddstr = kstrdup(amdgpu_virtual_display,
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">GFP_KERNEL</span><span style="font-size:10.5pt;font-family:Consolas;color:black">);<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">        pciaddstr_tmp = pciaddstr;<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">       
</span><span style="font-size:10.5pt;font-family:Consolas;color:blue">while</span><span style="font-size:10.5pt;font-family:Consolas;color:black"> ((pciaddname_tmp = strsep(&pciaddstr_tmp,
</span><span style="font-size:10.5pt;font-family:Consolas;color:#A31515">";"</span><span style="font-size:10.5pt;font-family:Consolas;color:black">))) {<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="line-height:14.25pt;background:white"><span style="font-size:10.5pt;font-family:Consolas;color:black">            pciaddname = strsep(&pciaddname_tmp,
</span><span style="font-size:10.5pt;font-family:Consolas;color:#A31515">","</span><span style="font-size:10.5pt;font-family:Consolas;color:black">);<o:p></o:p></span></p>
</div>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">+        memset(reg_offset, 0, 11); <br>
+        ret = copy_from_user(reg_offset, buf + len, min(11, <br>
((int)size-len))); <br>
+ <br>
+        if (ret) <br>
+            goto error_free; <br>
+ <br>
+        reg = strsep(&reg_offset, " "); <br>
+        tmp = krealloc_array(tmp, 1, sizeof(uint32_t), GFP_KERNEL); <o:p></o:p></p>
</blockquote>
<p class="MsoNormal">That must be krealloc_array(tmp, i, ... not krealloc_array(tmp, 1, ... !
<o:p></o:p></p>
</blockquote>
<p class="MsoNormal">I thought it will append (if not it should have crashed or some kernel dump)
<o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><br>
No, krealloc_array works similar to realloc() in userspace. <br>
<br>
You need to give it the full size of the necessary space. <br>
<br>
Regards, <br>
Christian. <br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">Regards, <br>
Christian. <br>
<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p class="MsoNormal">+        ret = kstrtouint(reg, 16, &tmp[i]); <br>
+ <br>
+        if (ret) <br>
+            goto error_free; <br>
+ <br>
+        len += strlen(reg) + 1; <br>
+        i++; <br>
+ <br>
+    } while (len < size); <br>
+ <br>
+    ret = down_write_killable(&adev->reset_sem); <br>
+ <br>
+    if (ret) <br>
+        goto error_free; <br>
+ <br>
+    swap(adev->reset_dump_reg_list, tmp); <br>
+    adev->num_regs = i; <br>
+    up_write(&adev->reset_sem); <br>
+    ret = size; <br>
+ <br>
+error_free: <br>
+    kfree(tmp); <br>
+    return ret; <br>
+} <br>
+ <br>
+ <br>
+ <br>
+static const struct file_operations amdgpu_reset_dump_register_list = { <br>
+    .owner = THIS_MODULE, <br>
+    .read = amdgpu_reset_dump_register_list_read, <br>
+    .write = amdgpu_reset_dump_register_list_write, <br>
+    .llseek = default_llseek <br>
+}; <br>
+ <br>
   int amdgpu_debugfs_init(struct amdgpu_device *adev) <br>
   { <br>
       struct dentry *root = adev_to_drm(adev)->primary->debugfs_root; <br>
@@ -1672,6 +1766,8 @@ int amdgpu_debugfs_init(struct amdgpu_device <br>
*adev) <br>
                   &amdgpu_debugfs_test_ib_fops); <br>
       debugfs_create_file("amdgpu_vm_info", 0444, root, adev, <br>
                   &amdgpu_debugfs_vm_info_fops); <br>
+    debugfs_create_file("amdgpu_reset_dump_register_list", 0644, <br>
root, adev, <br>
+                &amdgpu_reset_dump_register_list); <br>
         adev->debugfs_vbios_blob.data = adev->bios; <br>
       adev->debugfs_vbios_blob.size = adev->bios_size; <o:p></o:p></p>
</blockquote>
</blockquote>
<p class="MsoNormal">> <o:p></o:p></p>
</blockquote>
<p class="MsoNormal"><o:p> </o:p></p>
</blockquote>
</div>
</body>
</html>