[PATCH v4 11/17] ras: AEST: Add error count tracking and debugfs interface
Ruidong Tian
tianruidong at linux.alibaba.com
Mon Dec 22 01:43:44 PST 2025
This commit introduces error counting functionality for AEST records.
Previously, error statistics were not directly available for individual
error records or AEST nodes.
Signed-off-by: Ruidong Tian <tianruidong at linux.alibaba.com>
---
Documentation/ABI/testing/debugfs-aest | 14 ++++++
drivers/ras/aest/aest-core.c | 21 +++++++++
drivers/ras/aest/aest-sysfs.c | 64 ++++++++++++++++++++++++++
drivers/ras/aest/aest.h | 10 ++++
4 files changed, 109 insertions(+)
diff --git a/Documentation/ABI/testing/debugfs-aest b/Documentation/ABI/testing/debugfs-aest
index 1152fc83c3fc..a984fcedede2 100644
--- a/Documentation/ABI/testing/debugfs-aest
+++ b/Documentation/ABI/testing/debugfs-aest
@@ -23,9 +23,23 @@ Description:
See more at:
https://developer.arm.com/documentation/den0085/latest/
+What: /sys/kernel/debug/aest/<name>.<id>/<node_name>/err_count
+Date: Dec 2025
+KernelVersion 6.19
+Contact: Ruidong Tian <tianruidong at linux.alibaba.com>
+Description:
+ (RO) Outputs error statistics for all error records of this node.
+
What: /sys/kernel/debug/aest/<name>.<id>/<node_name>/record<index>/err_*
Date: Dec 2025
KernelVersion 6.19
Contact: Ruidong Tian <tianruidong at linux.alibaba.com>
Description:
(RO) Read err_* register and return val.
+
+What: /sys/kernel/debug/aest/<name>.<id>/<node_name>/record<index>/err_count
+Date: Dec 2025
+KernelVersion 6.19
+Contact: Ruidong Tian <tianruidong at linux.alibaba.com>
+Description:
+ (RO) Outputs error statistics for all this records.
diff --git a/drivers/ras/aest/aest-core.c b/drivers/ras/aest/aest-core.c
index 3bcc635cf8e4..75cca98024ad 100644
--- a/drivers/ras/aest/aest-core.c
+++ b/drivers/ras/aest/aest-core.c
@@ -170,6 +170,27 @@ static int aest_node_gen_pool_add(struct aest_device *adev,
init_aest_event(event, record, regs);
llist_add(&event->llnode, &adev->event_list);
+ if (regs->err_status & ERR_STATUS_CE)
+ record->count.ce++;
+ if (regs->err_status & ERR_STATUS_DE)
+ record->count.de++;
+ if (regs->err_status & ERR_STATUS_UE) {
+ switch (regs->err_status & ERR_STATUS_UET) {
+ case ERR_STATUS_UET_UC:
+ record->count.uc++;
+ break;
+ case ERR_STATUS_UET_UEU:
+ record->count.ueu++;
+ break;
+ case ERR_STATUS_UET_UER:
+ record->count.uer++;
+ break;
+ case ERR_STATUS_UET_UEO:
+ record->count.ueo++;
+ break;
+ }
+ }
+
return 0;
}
diff --git a/drivers/ras/aest/aest-sysfs.c b/drivers/ras/aest/aest-sysfs.c
index f3b5427ff4f0..b54e879506aa 100644
--- a/drivers/ras/aest/aest-sysfs.c
+++ b/drivers/ras/aest/aest-sysfs.c
@@ -7,6 +7,46 @@
#include "aest.h"
+static void
+aest_error_count(struct aest_record *record, void *data)
+{
+ struct record_count *count = data;
+
+ count->ce += record->count.ce;
+ count->de += record->count.de;
+ count->uc += record->count.uc;
+ count->ueu += record->count.ueu;
+ count->uer += record->count.uer;
+ count->ueo += record->count.ueo;
+}
+
+/*******************************************************************************
+ *
+ * Debugfs for AEST node
+ *
+ ******************************************************************************/
+
+static int aest_node_err_count_show(struct seq_file *m, void *data)
+{
+ struct aest_node *node = m->private;
+ struct record_count count = { 0 };
+ int i;
+
+ for (i = 0; i < node->record_count; i++)
+ aest_error_count(&node->records[i], &count);
+
+ seq_printf(m, "CE: %llu\n"
+ "DE: %llu\n"
+ "UC: %llu\n"
+ "UEU: %llu\n"
+ "UEO: %llu\n"
+ "UER: %llu\n",
+ count.ce, count.de, count.uc, count.ueu,
+ count.uer, count.ueo);
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(aest_node_err_count);
+
/*******************************************************************************
*
* Attribute for AEST record
@@ -37,6 +77,25 @@ DEFINE_AEST_DEBUGFS_ATTR(err_misc1, ERXMISC1);
DEFINE_AEST_DEBUGFS_ATTR(err_misc2, ERXMISC2);
DEFINE_AEST_DEBUGFS_ATTR(err_misc3, ERXMISC3);
+static int aest_record_err_count_show(struct seq_file *m, void *data)
+{
+ struct aest_record *record = m->private;
+ struct record_count count = { 0 };
+
+ aest_error_count(record, &count);
+
+ seq_printf(m, "CE: %llu\n"
+ "DE: %llu\n"
+ "UC: %llu\n"
+ "UEU: %llu\n"
+ "UEO: %llu\n"
+ "UER: %llu\n",
+ count.ce, count.de, count.uc, count.ueu,
+ count.uer, count.ueo);
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(aest_record_err_count);
+
static void aest_record_init_debugfs(struct aest_record *record)
{
debugfs_create_file("err_fr", 0600, record->debugfs, record,
@@ -55,6 +114,8 @@ static void aest_record_init_debugfs(struct aest_record *record)
&err_misc2_ops);
debugfs_create_file("err_misc3", 0600, record->debugfs, record,
&err_misc3_ops);
+ debugfs_create_file("err_count", 0400, record->debugfs, record,
+ &aest_record_err_count_fops);
}
static void
@@ -63,6 +124,9 @@ aest_node_init_debugfs(struct aest_node *node)
int i;
struct aest_record *record;
+ debugfs_create_file("err_count", 0400, node->debugfs, node,
+ &aest_node_err_count_fops);
+
for (i = 0; i < node->record_count; i++) {
record = &node->records[i];
if (!record->name)
diff --git a/drivers/ras/aest/aest.h b/drivers/ras/aest/aest.h
index ceb9e32bcee3..802430857dc4 100644
--- a/drivers/ras/aest/aest.h
+++ b/drivers/ras/aest/aest.h
@@ -116,6 +116,15 @@ struct ce_threshold {
u64 reg_val;
};
+struct record_count {
+ u64 ce;
+ u64 de;
+ u64 uc;
+ u64 uer;
+ u64 ueo;
+ u64 ueu;
+};
+
struct aest_record {
char *name;
int index;
@@ -136,6 +145,7 @@ struct aest_record {
struct ce_threshold ce;
enum ras_ce_threshold threshold_type;
+ struct record_count count;
struct dentry *debugfs;
};
--
2.51.2.612.gdc70283dfc
More information about the linux-arm-kernel
mailing list