rasdaemon/feature-report-ARM-processor-info.patch
2019-09-30 11:16:11 -04:00

368 lines
11 KiB
Diff

From 5ae4ad1d71e931fa1639f605c83a0313f641c282 Mon Sep 17 00:00:00 2001
From: lvying <lvying6@huawei.com>
Date: Wed, 24 Apr 2019 17:50:57 +0800
Subject: [PATCH] rasdaemon:report ARM processor info
reason: report ARM processor info
Signed-off-by: lvying <lvying6@huawei.com>
---
Makefile.am | 4 +-
ras-arm-ctx-handler.c | 75 ++++++++++++++++++++++++++++++
ras-arm-ctx-handler.h | 23 +++++++++
ras-arm-error-info-handler.c | 90 ++++++++++++++++++++++++++++++++++++
ras-arm-error-info-handler.h | 23 +++++++++
ras-events.c | 18 ++++++++
ras-events.h | 2 +
ras-record.h | 19 ++++++++
8 files changed, 252 insertions(+), 2 deletions(-)
create mode 100644 ras-arm-ctx-handler.c
create mode 100644 ras-arm-ctx-handler.h
create mode 100644 ras-arm-error-info-handler.c
create mode 100644 ras-arm-error-info-handler.h
diff --git a/Makefile.am b/Makefile.am
index 6fc39f2..52cd1a2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -28,7 +28,7 @@ if WITH_NON_STANDARD
rasdaemon_SOURCES += ras-non-standard-handler.c
endif
if WITH_ARM
- rasdaemon_SOURCES += ras-arm-handler.c
+ rasdaemon_SOURCES += ras-arm-handler.c ras-arm-error-info-handler.c ras-arm-ctx-handler.c
endif
if WITH_MCE
rasdaemon_SOURCES += ras-mce-handler.c mce-intel.c mce-amd.c \
@@ -59,7 +59,7 @@ rasdaemon_LDADD = -lpthread $(SQLITE3_LIBS) libtrace/libtrace.a
include_HEADERS = config.h ras-events.h ras-logger.h ras-mc-handler.h \
ras-aer-handler.h ras-mce-handler.h ras-record.h bitfield.h ras-report.h \
ras-extlog-handler.h ras-arm-handler.h ras-non-standard-handler.h \
- ras-devlink-handler.h ras-diskerror-handler.h rbtree.h ras-page-isolation.h
+ ras-devlink-handler.h ras-diskerror-handler.h rbtree.h ras-page-isolation.h ras-arm-ctx-handler.h ras-arm-error-info-handler.h
# This rule can't be called with more than one Makefile job (like make -j8)
# I can't figure out a way to fix that
diff --git a/ras-arm-ctx-handler.c b/ras-arm-ctx-handler.c
new file mode 100644
index 0000000..4abe3a8
--- /dev/null
+++ b/ras-arm-ctx-handler.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "libtrace/kbuffer.h"
+#include "ras-arm-ctx-handler.h"
+#include "ras-record.h"
+#include "ras-logger.h"
+#include "ras-report.h"
+
+int ras_arm_ctx_handler(struct trace_seq *s,
+ struct pevent_record *record,
+ struct event_format *event, void *context)
+{
+ unsigned long long val;
+ struct ras_events *ras = context;
+ struct ras_arm_ctx_event ev;
+ time_t now;
+ struct tm *tm = NULL;
+ int len;
+
+ memset(&ev, 0, sizeof(ev));
+
+ /*
+ * Newer kernels (3.10-rc1 or upper) provide an uptime clock.
+ * On previous kernels, the way to properly generate an event would
+ * be to inject a fake one, measure its timestamp and diff it against
+ * gettimeofday. We won't do it here. Instead, let's use uptime,
+ * falling-back to the event report's time, if "uptime" clock is
+ * not available (legacy kernels).
+ */
+
+ if (ras->use_uptime)
+ now = record->ts/user_hz + ras->uptime_diff;
+ else
+ now = time(NULL);
+
+ tm = localtime(&now);
+ if (tm)
+ strftime(ev.timestamp, sizeof(ev.timestamp),
+ "%Y-%m-%d %H:%M:%S %z", tm);
+
+ if (pevent_get_field_val(s, event, "index", record, &val, 1) < 0)
+ return -1;
+ ev.index = val;
+ trace_seq_printf(s, " Context info structure %d:", ev.index);
+
+ ev.processor_ctx_info = pevent_get_field_raw(s, event, "processor_ctx_info", record, &len, 1);
+ if (!ev.processor_ctx_info)
+ return -1;
+
+ if (*ev.processor_ctx_info) {
+ trace_seq_puts(s, "\n");
+ trace_seq_puts(s, ev.processor_ctx_info);
+ }
+
+ // TODO: how to design this table: related to ARM event table or sperated table?
+
+ // TODO: report to ABRT
+
+ return 0;
+}
diff --git a/ras-arm-ctx-handler.h b/ras-arm-ctx-handler.h
new file mode 100644
index 0000000..d23a142
--- /dev/null
+++ b/ras-arm-ctx-handler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __RAS_ARM_CTX_HANDLER_H
+#define __RAS_ARM_CTX_HANDLER_H
+
+#include "ras-events.h"
+#include "libtrace/event-parse.h"
+
+int ras_arm_ctx_handler(struct trace_seq *s,
+ struct pevent_record *record,
+ struct event_format *event, void *context);
+#endif
diff --git a/ras-arm-error-info-handler.c b/ras-arm-error-info-handler.c
new file mode 100644
index 0000000..afafe89
--- /dev/null
+++ b/ras-arm-error-info-handler.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "libtrace/kbuffer.h"
+#include "ras-arm-error-info-handler.h"
+#include "ras-record.h"
+#include "ras-logger.h"
+#include "ras-report.h"
+
+int ras_arm_error_info_handler(struct trace_seq *s,
+ struct pevent_record *record,
+ struct event_format *event, void *context)
+{
+ unsigned long long val;
+ struct ras_events *ras = context;
+ struct ras_arm_err_info_event ev;
+ time_t now;
+ struct tm *tm = NULL;
+ int len;
+
+ memset(&ev, 0, sizeof(ev));
+
+ /*
+ * Newer kernels (3.10-rc1 or upper) provide an uptime clock.
+ * On previous kernels, the way to properly generate an event would
+ * be to inject a fake one, measure its timestamp and diff it against
+ * gettimeofday. We won't do it here. Instead, let's use uptime,
+ * falling-back to the event report's time, if "uptime" clock is
+ * not available (legacy kernels).
+ */
+
+ if (ras->use_uptime)
+ now = record->ts/user_hz + ras->uptime_diff;
+ else
+ now = time(NULL);
+
+ tm = localtime(&now);
+ if (tm)
+ strftime(ev.timestamp, sizeof(ev.timestamp),
+ "%Y-%m-%d %H:%M:%S %z", tm);
+
+ if (pevent_get_field_val(s, event, "index", record, &val, 1) < 0)
+ return -1;
+ ev.index = val;
+ trace_seq_printf(s, " Error info structure %d:", ev.index);
+
+ if (pevent_get_field_val(s, event, "multiplie_error", record, &val, 1) < 0)
+ return -1;
+ ev.multiplie_error = val;
+ trace_seq_printf(s, "\n num errors: %d", ev.multiplie_error);
+
+ ev.processor_error_info = pevent_get_field_raw(s, event, "processor_error_info", record, &len, 1);
+ if (!ev.processor_error_info)
+ return -1;
+
+ if (*ev.processor_error_info) {
+ trace_seq_puts(s, "\n");
+ trace_seq_puts(s, ev.processor_error_info);
+ }
+
+ if (pevent_get_field_val(s, event, "va", record, &val, 1) < 0)
+ return -1;
+ ev.va = val;
+ trace_seq_printf(s, "\n virtual fault address: 0x%lx", ev.va);
+
+ if (pevent_get_field_val(s, event, "pa", record, &val, 1) < 0)
+ return -1;
+ ev.pa = val;
+ trace_seq_printf(s, "\n physical fault address: 0x%lx", ev.pa);
+
+ // TODO: how to design this table: related to ARM event table or sperated table?
+
+ // TODO: report to ABRT
+
+ return 0;
+}
diff --git a/ras-arm-error-info-handler.h b/ras-arm-error-info-handler.h
new file mode 100644
index 0000000..9680989
--- /dev/null
+++ b/ras-arm-error-info-handler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __RAS_ARM_ERROR_INFO_HANDLER_H
+#define __RAS_ARM_ERROR_INFO_HANDLER_H
+
+#include "ras-events.h"
+#include "libtrace/event-parse.h"
+
+int ras_arm_error_info_handler(struct trace_seq *s,
+ struct pevent_record *record,
+ struct event_format *event, void *context);
+#endif
diff --git a/ras-events.c b/ras-events.c
index 70b02e5..a8f7fe9 100644
--- a/ras-events.c
+++ b/ras-events.c
@@ -27,6 +27,8 @@
#include <sys/poll.h>
#include "libtrace/kbuffer.h"
#include "libtrace/event-parse.h"
+#include "ras-arm-error-info-handler.h"
+#include "ras-arm-ctx-handler.h"
#include "ras-mc-handler.h"
#include "ras-aer-handler.h"
#include "ras-non-standard-handler.h"
@@ -800,6 +802,22 @@ int handle_ras_events(int record_events)
else
log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
"ras", "arm_event");
+
+ rc = add_event_handler(ras, pevent, page_size, "ras", "arm_err_info_event",
+ ras_arm_error_info_handler, NULL, ARM_ERR_INFO_EVENT);
+ if (!rc)
+ num_events++;
+ else
+ log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
+ "ras", "arm_err_info_event");
+
+ rc = add_event_handler(ras, pevent, page_size, "ras", "arm_ctx_event",
+ ras_arm_ctx_handler, NULL, ARM_CTX_EVENT);
+ if (!rc)
+ num_events++;
+ else
+ log(ALL, LOG_ERR, "Can't get traces from %s:%s\n",
+ "ras", "arm_ctx_event");
#endif
cpus = get_num_cpus(ras);
diff --git a/ras-events.h b/ras-events.h
index f028741..6accdd1 100644
--- a/ras-events.h
+++ b/ras-events.h
@@ -38,6 +38,8 @@ enum {
EXTLOG_EVENT,
DEVLINK_EVENT,
DISKERROR_EVENT,
+ ARM_ERR_INFO_EVENT,
+ ARM_CTX_EVENT,
NR_EVENTS
};
diff --git a/ras-record.h b/ras-record.h
index 5311c67..b7d7436 100644
--- a/ras-record.h
+++ b/ras-record.h
@@ -94,11 +94,30 @@ struct diskerror_event {
const char *cmd;
};
+struct ras_arm_err_info_event
+{
+ char timestamp[64];
+ uint32_t index;
+ uint16_t multiplie_error;
+ uint64_t va;
+ uint64_t pa;
+ const char *processor_error_info;
+};
+
+struct ras_arm_ctx_event
+{
+ char timestamp[64];
+ uint32_t index;
+ const char *processor_ctx_info;
+};
+
struct ras_mc_event;
struct ras_aer_event;
struct ras_extlog_event;
struct ras_non_standard_event;
struct ras_arm_event;
+struct ras_arm_err_info_event;
+struct ras_arm_ctx_event;
struct mce_event;
struct devlink_event;
struct diskerror_event;
--
2.19.1