Re: [PATCH v2 1/2] drm/amdgpu: add debugfs for reset registers list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am 11.02.22 um 14:15 schrieb Somalapuram, Amaranath:

On 2/11/2022 5:22 PM, Christian König wrote:
Am 11.02.22 um 12:47 schrieb Somalapuram Amaranath:
List of register to be populated for dump collection during the GPU reset.

Signed-off-by: Somalapuram Amaranath <Amaranath.Somalapuram@xxxxxxx>
---
  drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  5 ++
  drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 61 +++++++++++++++++++++
  2 files changed, 66 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index b85b67a88a3d..b90349b86918 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -813,6 +813,7 @@ struct amd_powerplay {
    #define AMDGPU_RESET_MAGIC_NUM 64
  #define AMDGPU_MAX_DF_PERFMONS 4
+#define AMDGPU_RESET_DUMP_REGS_MAX     128
  struct amdgpu_device {
      struct device            *dev;
      struct pci_dev            *pdev;
@@ -1097,6 +1098,10 @@ struct amdgpu_device {
        struct amdgpu_reset_control     *reset_cntl;
      uint32_t ip_versions[HW_ID_MAX][HWIP_MAX_INSTANCE];
+
+    /* reset dump register */
+    uint32_t reset_dump_reg_list[AMDGPU_RESET_DUMP_REGS_MAX];

Using an xarray or just dynamic allocation with krealloc_array would probably be better.

Regards,
Christian.

I can use krealloc_array,
Then in the second patch i need to use kmalloc (or hard-code values) for this: uint32_t reg_value[AMDGPU_RESET_DUMP_REGS_MAX]; We actually tried to avoid  dynamic allocation during reset (second patch).

It's correct that you can't allocate any memory during reset, but that's also not necessary since you just need to trace one register at a time and that uses the trace ring buffer.

Also AMDGPU_RESET_DUMP_REGS_MAX getting used in trace function.

Exactly that's what I'm trying to avoid here. Big traces have caused us quite a bunch of problems already :)

Regards,
Christian.


Regards,
S.Amarnath
+    int                n_regs;
  };
    static inline struct amdgpu_device *drm_to_adev(struct drm_device *ddev) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 164d6a9e9fbb..fb99f3d657a4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1609,6 +1609,65 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_ib_preempt, NULL,
  DEFINE_DEBUGFS_ATTRIBUTE(fops_sclk_set, NULL,
              amdgpu_debugfs_sclk_set, "%llu\n");
  +static ssize_t amdgpu_reset_dump_register_list_read(struct file *f,
+                char __user *buf, size_t size, loff_t *pos)
+{
+    struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
+    char *reg_offset;
+    int i, r, len;
+
+    reg_offset = kmalloc(2048, GFP_KERNEL);
+    memset(reg_offset,  0, 2048);
+    for (i = 0; i < adev->n_regs; i++)
+        sprintf(reg_offset + strlen(reg_offset), "0x%x ", adev->reset_dump_reg_list[i]);
+
+    sprintf(reg_offset + strlen(reg_offset), "\n");
+    len = strlen(reg_offset);
+
+    if (*pos >=  len)
+        return 0;
+
+    r = copy_to_user(buf, reg_offset, len);
+    *pos += len - r;
+    kfree(reg_offset);
+
+    return len - r;
+}
+
+static ssize_t amdgpu_reset_dump_register_list_write(struct file *f, const char __user *buf,
+        size_t size, loff_t *pos)
+{
+    struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
+    char *reg_offset, *reg;
+    int ret, i = 0;
+
+    reg_offset = kmalloc(size, GFP_KERNEL);
+    memset(reg_offset,  0, size);
+    ret = copy_from_user(reg_offset, buf, size);
+
+    if (ret)
+        return -EFAULT;
+
+    while ((reg = strsep(&reg_offset, " ")) != NULL) {
+        ret  = kstrtouint(reg, 16, &adev->reset_dump_reg_list[i]);
+        if (ret)
+            return -EINVAL;
+        i++;
+    }
+
+    adev->n_regs = i;
+    kfree(reg_offset);
+
+    return size;
+}
+
+static const struct file_operations amdgpu_reset_dump_register_list = {
+    .owner = THIS_MODULE,
+    .read = amdgpu_reset_dump_register_list_read,
+    .write = amdgpu_reset_dump_register_list_write,
+    .llseek = default_llseek
+};
+
  int amdgpu_debugfs_init(struct amdgpu_device *adev)
  {
      struct dentry *root = adev_to_drm(adev)->primary->debugfs_root;
@@ -1672,6 +1731,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)
                  &amdgpu_debugfs_test_ib_fops);
      debugfs_create_file("amdgpu_vm_info", 0444, root, adev,
                  &amdgpu_debugfs_vm_info_fops);
+    debugfs_create_file("amdgpu_reset_dump_register_list", 0644, root, adev,
+                &amdgpu_reset_dump_register_list);
        adev->debugfs_vbios_blob.data = adev->bios;
      adev->debugfs_vbios_blob.size = adev->bios_size;





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux