<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(®_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>