diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1552-drm-amdgpu-add-human-readable-debugfs-control-suppor.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1552-drm-amdgpu-add-human-readable-debugfs-control-suppor.patch | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1552-drm-amdgpu-add-human-readable-debugfs-control-suppor.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1552-drm-amdgpu-add-human-readable-debugfs-control-suppor.patch new file mode 100644 index 00000000..60e2a63a --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1552-drm-amdgpu-add-human-readable-debugfs-control-suppor.patch @@ -0,0 +1,160 @@ +From d54626ae3eb0ba95d549b25af99801637ed1b548 Mon Sep 17 00:00:00 2001 +From: xinhui pan <xinhui.pan@amd.com> +Date: Fri, 1 Mar 2019 16:32:11 +0800 +Subject: [PATCH 1552/2940] drm/amdgpu: add human readable debugfs control + support + +Currently, the debugfs control node can't parse bash-like commands. +Now add such support for any tester that uses scripts. + +Signed-off-by: xinhui pan <xinhui.pan@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 109 +++++++++++++++++++++--- + 1 file changed, 96 insertions(+), 13 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +index ca9c7d1ede2f..8b1088dac686 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +@@ -200,14 +200,84 @@ static const struct file_operations amdgpu_ras_debugfs_ops = { + .llseek = default_llseek + }; + ++static int amdgpu_ras_find_block_id_by_name(const char *name, int *block_id) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(ras_block_string); i++) { ++ *block_id = i; ++ if (strcmp(name, ras_block_str(i)) == 0) ++ return 0; ++ } ++ return -EINVAL; ++} ++ ++static int amdgpu_ras_debugfs_ctrl_parse_data(struct file *f, ++ const char __user *buf, size_t size, ++ loff_t *pos, struct ras_debug_if *data) ++{ ++ ssize_t s = min_t(u64, 64, size); ++ char str[65]; ++ char block_name[33]; ++ char err[9] = "ue"; ++ int op = -1; ++ int block_id; ++ u64 address, value; ++ ++ if (*pos) ++ return -EINVAL; ++ *pos = size; ++ ++ memset(str, 0, sizeof(str)); ++ memset(data, 0, sizeof(*data)); ++ ++ if (copy_from_user(str, buf, s)) ++ return -EINVAL; ++ ++ if (sscanf(str, "disable %32s", block_name) == 1) ++ op = 0; ++ else if (sscanf(str, "enable %32s %8s", block_name, err) == 2) ++ op = 1; ++ else if (sscanf(str, "inject %32s %8s", block_name, err) == 2) ++ op = 2; ++ ++ if (op != -1) { ++ if (amdgpu_ras_find_block_id_by_name(block_name, &block_id)) ++ return -EINVAL; ++ ++ data->head.block = block_id; ++ data->head.type = memcmp("ue", err, 2) == 0 ? ++ AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE : ++ AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE; ++ data->op = op; ++ ++ if (op == 2) { ++ if (sscanf(str, "%*s %*s %*s %llu %llu", ++ &address, &value) != 2) ++ if (sscanf(str, "%*s %*s %*s 0x%llx 0x%llx", ++ &address, &value) != 2) ++ return -EINVAL; ++ data->inject.address = address; ++ data->inject.value = value; ++ } ++ } else { ++ if (size < sizeof(data)) ++ return -EINVAL; ++ ++ if (copy_from_user(data, buf, sizeof(*data))) ++ return -EINVAL; ++ } ++ ++ return 0; ++} + /* + * DOC: ras debugfs control interface + * + * It accepts struct ras_debug_if who has two members. + * + * First member: ras_debug_if::head or ras_debug_if::inject. +- * It is used to indicate which IP block will be under control. +- * Its contents are not human readable, IOW, write it by your programs. ++ * ++ * head is used to indicate which IP block will be under control. + * + * head has four members, they are block, type, sub_block_index, name. + * block: which IP will be under control. +@@ -225,6 +295,28 @@ static const struct file_operations amdgpu_ras_debugfs_ops = { + * 1: enable RAS on the block. Take ::head as its data. + * 2: inject errors on the block. Take ::inject as its data. + * ++ * How to use the interface? ++ * programs: ++ * copy the struct ras_debug_if in your codes and initialize it. ++ * write the struct to the control node. ++ * ++ * bash: ++ * echo op block [error [address value]] > .../ras/ras_ctrl ++ * op: disable, enable, inject ++ * disable: only block is needed ++ * enable: block and error are needed ++ * inject: error, address, value are needed ++ * block: umc, smda, gfx, ......... ++ * see ras_block_string[] for details ++ * error: ue, ce ++ * ue: multi_uncorrectable ++ * ce: single_correctable ++ * ++ * here are some examples for bash commands, ++ * echo inject umc ue 0x0 0x0 > /sys/kernel/debug/dri/0/ras/ras_ctrl ++ * echo inject umc ce 0 0 > /sys/kernel/debug/dri/0/ras/ras_ctrl ++ * echo disable umc > /sys/kernel/debug/dri/0/ras/ras_ctrl ++ * + * How to check the result? + * + * For disable/enable, please check ras features at +@@ -243,19 +335,10 @@ static ssize_t amdgpu_ras_debugfs_ctrl_write(struct file *f, const char __user * + struct ras_debug_if data; + int ret = 0; + +- if (size < sizeof(data)) +- return -EINVAL; +- +- memset(&data, 0, sizeof(data)); +- +- if (*pos) +- return -EINVAL; +- +- if (copy_from_user(&data, buf, sizeof(data))) ++ ret = amdgpu_ras_debugfs_ctrl_parse_data(f, buf, size, pos, &data); ++ if (ret) + return -EINVAL; + +- *pos = size; +- + if (!amdgpu_ras_is_supported(adev, data.head.block)) + return -EINVAL; + +-- +2.17.1 + |