368 lines
11 KiB
Diff
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
|
|
|