From 5ae4ad1d71e931fa1639f605c83a0313f641c282 Mon Sep 17 00:00:00 2001 From: lvying 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 --- 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 +#include +#include +#include +#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 +#include +#include +#include +#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 #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