diff --git a/SOURCES/0001-ras-mc-ctl-Improve-error-summary-to-show-label-and-m.patch b/SOURCES/0001-ras-mc-ctl-Improve-error-summary-to-show-label-and-m.patch new file mode 100644 index 0000000..60c0bbd --- /dev/null +++ b/SOURCES/0001-ras-mc-ctl-Improve-error-summary-to-show-label-and-m.patch @@ -0,0 +1,38 @@ +From 5e8fb95e2f6dd3f427e0ae5d7d066aeb6d61fd0f Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Wed, 29 May 2013 21:53:58 -0300 +Subject: [PATCH 01/32] ras-mc-ctl: Improve error summary to show label and mc + +Both information are useful for the users, even on summary. + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index 32c4edb..5b1ca4d 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -827,15 +827,15 @@ sub summary + + my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {}); + +- my $query = "select top_layer,middle_layer,lower_layer, count(*) from mc_event group by top_layer,middle_layer,lower_layer"; ++ my $query = "select label, mc, top_layer,middle_layer,lower_layer, count(*) from mc_event group by label,mc,top_layer,middle_layer,lower_layer"; + my $query_handle = $dbh->prepare($query); + $query_handle->execute(); + +- $query_handle->bind_columns(\my($top, $mid, $low, $count)); ++ $query_handle->bind_columns(\my($label, $mc, $top, $mid, $low, $count)); + + print "Memory controller events summary:\n"; + while($query_handle->fetch()) { +- print "location: $top:$mid:$low errors: $count\n"; ++ print "DIMM Label(s): '$label' location: $mc:$top:$mid:$low errors: $count\n"; + } + + $query_handle->finish; +-- +1.7.1 + diff --git a/SOURCES/0002-ras-record-make-the-code-more-generic.patch b/SOURCES/0002-ras-record-make-the-code-more-generic.patch new file mode 100644 index 0000000..243aa28 --- /dev/null +++ b/SOURCES/0002-ras-record-make-the-code-more-generic.patch @@ -0,0 +1,240 @@ +From 002238dff53b284c9455554f146176ee8de2de4a Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 12:41:01 -0300 +Subject: [PATCH 02/32] ras-record: make the code more generic + +Now that we're ready to add more tables to the database, make +the code that creates and inserts data into the table more +generic. + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-record.c | 173 +++++++++++++++++++++++++++++++++++++--------------------- + 1 files changed, 110 insertions(+), 63 deletions(-) + +diff --git a/ras-record.c b/ras-record.c +index 8995c9e..3af0791 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -28,80 +28,128 @@ + #include "ras-mc-handler.h" + #include "ras-logger.h" + ++/* #define DEBUG_SQL 1 */ ++ + #define SQLITE_RAS_DB RASSTATEDIR "/" RAS_DB_FNAME + +-const char *mc_event_db = " mc_event "; +-const char *mc_event_db_create_fields = "(" +- "id INTEGER PRIMARY KEY" +- ", timestamp TEXT" +- ", err_count INTEGER" +- ", err_type TEXT" +- ", err_msg TEXT" /* 5 */ +- ", label TEXT" +- ", mc INTEGER" +- ", top_layer INTEGER" +- ", middle_layer INTEGER" +- ", lower_layer INTEGER" /* 10 */ +- ", address INTEGER" +- ", grain INTEGER" +- ", syndrome INTEGER" +- ", driver_detail TEXT" /* 14 */ +- ")"; +- +-const char *mc_event_db_fields = "(" +- "id" +- ", timestamp" +- ", err_count" +- ", err_type" +- ", err_msg" /* 5 */ +- ", label" +- ", mc" +- ", top_layer" +- ", middle_layer" +- ", lower_layer" /* 10 */ +- ", address" +- ", grain" +- ", syndrome" +- ", driver_detail" /* 14 */ +- ")"; +- +-#define NUM_MC_EVENT_DB_VALUES 14 +- +-const char *createdb = "CREATE TABLE IF NOT EXISTS"; ++ ++#define ARRAY_SIZE(x) (sizeof(x)/sizeof(*(x))) ++ ++struct db_fields { ++ char *name; ++ char *type; ++}; ++ ++struct db_table_descriptor { ++ char *name; ++ const struct db_fields *fields; ++ size_t num_fields; ++}; ++ ++static const struct db_fields mc_event_fields[] = { ++ { .name="id", .type="INTEGER PRIMARY KEY" }, ++ { .name="timestamp", .type="TEXT" }, ++ { .name="err_count", .type="INTEGER" }, ++ { .name="err_type", .type="TEXT" }, ++ { .name="err_msg", .type="TEXT" }, ++ { .name="label", .type="TEXT" }, ++ { .name="mc", .type="INTEGER" }, ++ { .name="top_layer", .type="INTEGER" }, ++ { .name="middle_layer", .type="INTEGER" }, ++ { .name="lower_layer", .type="INTEGER" }, ++ { .name="address", .type="INTEGER" }, ++ { .name="grain", .type="INTEGER" }, ++ { .name="syndrome", .type="INTEGER" }, ++ { .name="driver_detail", .type="TEXT" }, ++}; ++ ++static const struct db_table_descriptor mc_event_tab = { ++ .name = "mc_event", ++ .fields = mc_event_fields, ++ .num_fields = ARRAY_SIZE(mc_event_fields), ++}; ++ + const char *insertdb = "INSERT INTO"; + const char *valuesdb = " VALUES "; + +-static int ras_mc_prepare_stmt(struct sqlite3_priv *priv) ++static int ras_mc_prepare_stmt(struct sqlite3_priv *priv, ++ sqlite3_stmt **stmt, ++ const struct db_table_descriptor *db_tab) ++ + { + int i, rc; +- char sql[1024]; ++ char sql[1024], *p = sql, *end = sql + sizeof(sql); ++ const struct db_fields *field; ++ ++ p += snprintf(p, end - p, "INSERT INTO %s (", ++ db_tab->name); ++ ++ for (i = 0; i < db_tab->num_fields; i++) { ++ field = &db_tab->fields[i]; ++ p += snprintf(p, end - p, "%s", field->name); ++ ++ if (i < db_tab->num_fields - 1) ++ p += snprintf(p, end - p, ", "); ++ } + +- strcpy(sql, insertdb); +- strcat(sql, mc_event_db); +- strcat(sql, mc_event_db_fields); +- strcat(sql, valuesdb); ++ p += snprintf(p, end - p, ") VALUES ( NULL, "); + +- strcat(sql, "(NULL, "); /* Auto-increment field */ +- for (i = 1; i < NUM_MC_EVENT_DB_VALUES; i++) { +- if (i < NUM_MC_EVENT_DB_VALUES - 1) ++ for (i = 1; i < db_tab->num_fields; i++) { ++ if (i < db_tab->num_fields - 1) + strcat(sql, "?, "); + else + strcat(sql, "?)"); + } + +- rc = sqlite3_prepare_v2(priv->db, sql, -1, &priv->stmt, NULL); ++#ifdef DEBUG_SQL ++ log(TERM, LOG_INFO, "SQL: %s\n", sql); ++#endif ++ ++ rc = sqlite3_prepare_v2(priv->db, sql, -1, stmt, NULL); + if (rc != SQLITE_OK) +- log(TERM, LOG_ERR, "Failed to prepare insert db on %s: error = %s\n", +- SQLITE_RAS_DB, sqlite3_errmsg(priv->db)); ++ log(TERM, LOG_ERR, ++ "Failed to prepare insert db at table %s (db %s): error = %s\n", ++ db_tab->name, SQLITE_RAS_DB, sqlite3_errmsg(priv->db)); + + return rc; + } + ++static int ras_mc_create_table(struct sqlite3_priv *priv, ++ const struct db_table_descriptor *db_tab) ++{ ++ const struct db_fields *field; ++ char sql[1024], *p = sql, *end = sql + sizeof(sql); ++ int i,rc; ++ ++ p += snprintf(p, end - p, "CREATE TABLE IF NOT EXISTS %s (", ++ db_tab->name); ++ ++ for (i = 0; i < db_tab->num_fields; i++) { ++ field = &db_tab->fields[i]; ++ p += snprintf(p, end - p, "%s %s", field->name, field->type); ++ ++ if (i < db_tab->num_fields - 1) ++ p += snprintf(p, end - p, ", "); ++ } ++ p += snprintf(p, end - p, ")"); ++ ++#ifdef DEBUG_SQL ++ log(TERM, LOG_INFO, "SQL: %s\n", sql); ++#endif ++ ++ rc = sqlite3_exec(priv->db, sql, NULL, NULL, NULL); ++ if (rc != SQLITE_OK) { ++ log(TERM, LOG_ERR, ++ "Failed to create table %s on %s: error = %d\n", ++ db_tab->name, SQLITE_RAS_DB, rc); ++ } ++ return rc; ++} ++ + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + { + int rc; + sqlite3 *db; +- char sql[1024]; + struct sqlite3_priv *priv; + + printf("Calling %s()\n", __FUNCTION__); +@@ -137,27 +185,26 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + free(priv); + return -1; + } ++ priv->db = db; + +- strcpy(sql, createdb); +- strcat(sql, mc_event_db); +- strcat(sql, mc_event_db_create_fields); +- rc = sqlite3_exec(db, sql, NULL, NULL, NULL); ++ rc = ras_mc_create_table(priv, &mc_event_tab); + if (rc != SQLITE_OK) { +- log(TERM, LOG_ERR, +- "cpu %u: Failed to create db on %s: error = %d\n", +- cpu, SQLITE_RAS_DB, rc); ++ sqlite3_close(db); + free(priv); + return -1; + } + +- priv->db = db; +- ras->db_priv = priv; +- +- rc = ras_mc_prepare_stmt(priv); +- if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt, &mc_event_tab); ++ if (rc == SQLITE_OK) { + log(TERM, LOG_INFO, + "cpu %u: Recording events at %s\n", + cpu, SQLITE_RAS_DB); ++ ras->db_priv = priv; ++ } else { ++ sqlite3_close(db); ++ free(priv); ++ return -1; ++ } + + return 0; + } +-- +1.7.1 + diff --git a/SOURCES/0003-ras-record-rename-stmt-to-stmt_mc_event.patch b/SOURCES/0003-ras-record-rename-stmt-to-stmt_mc_event.patch new file mode 100644 index 0000000..f72a1a0 --- /dev/null +++ b/SOURCES/0003-ras-record-rename-stmt-to-stmt_mc_event.patch @@ -0,0 +1,97 @@ +From 016802f4093e80971a52c590c661a04924cb9aa3 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 13:10:16 -0300 +Subject: [PATCH 03/32] ras-record: rename stmt to stmt_mc_event + +This stmt is used only for mc_event. So, rename it, as we'll be +adding other stmts for the other tables. + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-record.c | 46 ++++++++++++++++++++++++---------------------- + ras-record.h | 2 +- + 2 files changed, 25 insertions(+), 23 deletions(-) + +diff --git a/ras-record.c b/ras-record.c +index 3af0791..efcd78f 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -194,7 +194,7 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + return -1; + } + +- rc = ras_mc_prepare_stmt(priv, &priv->stmt, &mc_event_tab); ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_mc_event, &mc_event_tab); + if (rc == SQLITE_OK) { + log(TERM, LOG_INFO, + "cpu %u: Recording events at %s\n", +@@ -214,30 +214,32 @@ int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) + int rc; + struct sqlite3_priv *priv = ras->db_priv; + +- if (!priv || !priv->stmt) ++ if (!priv || !priv->stmt_mc_event) + return 0; +- log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt); +- +- sqlite3_bind_text(priv->stmt, 1, ev->timestamp, -1, NULL); +- sqlite3_bind_int (priv->stmt, 2, ev->error_count); +- sqlite3_bind_text(priv->stmt, 3, ev->error_type, -1, NULL); +- sqlite3_bind_text(priv->stmt, 4, ev->msg, -1, NULL); +- sqlite3_bind_text(priv->stmt, 5, ev->label, -1, NULL); +- sqlite3_bind_int (priv->stmt, 6, ev->mc_index); +- sqlite3_bind_int (priv->stmt, 7, ev->top_layer); +- sqlite3_bind_int (priv->stmt, 8, ev->middle_layer); +- sqlite3_bind_int (priv->stmt, 9, ev->lower_layer); +- sqlite3_bind_int (priv->stmt, 10, ev->address); +- sqlite3_bind_int (priv->stmt, 11, ev->grain); +- sqlite3_bind_int (priv->stmt, 12, ev->syndrome); +- sqlite3_bind_text(priv->stmt, 13, ev->driver_detail, -1, NULL); +- rc = sqlite3_step(priv->stmt); ++ log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt_mc_event); ++ ++ sqlite3_bind_text(priv->stmt_mc_event, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_int (priv->stmt_mc_event, 2, ev->error_count); ++ sqlite3_bind_text(priv->stmt_mc_event, 3, ev->error_type, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mc_event, 4, ev->msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mc_event, 5, ev->label, -1, NULL); ++ sqlite3_bind_int (priv->stmt_mc_event, 6, ev->mc_index); ++ sqlite3_bind_int (priv->stmt_mc_event, 7, ev->top_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 8, ev->middle_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 9, ev->lower_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 10, ev->address); ++ sqlite3_bind_int (priv->stmt_mc_event, 11, ev->grain); ++ sqlite3_bind_int (priv->stmt_mc_event, 12, ev->syndrome); ++ sqlite3_bind_text(priv->stmt_mc_event, 13, ev->driver_detail, -1, NULL); ++ rc = sqlite3_step(priv->stmt_mc_event); + if (rc != SQLITE_OK && rc != SQLITE_DONE) +- log(TERM, LOG_ERR, "Failed to do mc_event step on sqlite: error = %d\n", rc); +- rc = sqlite3_reset(priv->stmt); ++ log(TERM, LOG_ERR, ++ "Failed to do mc_event step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_mc_event); + if (rc != SQLITE_OK && rc != SQLITE_DONE) +- log(TERM, LOG_ERR, "Failed reset mc_event on sqlite: error = %d\n", +- rc); ++ log(TERM, LOG_ERR, ++ "Failed reset mc_event on sqlite: error = %d\n", ++ rc); + log(TERM, LOG_INFO, "register inserted at db\n"); + + return rc; +diff --git a/ras-record.h b/ras-record.h +index 20c327f..9791185 100644 +--- a/ras-record.h ++++ b/ras-record.h +@@ -46,7 +46,7 @@ struct ras_aer_event { + + struct sqlite3_priv { + sqlite3 *db; +- sqlite3_stmt *stmt; ++ sqlite3_stmt *stmt_mc_event; + }; + + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras); +-- +1.7.1 + diff --git a/SOURCES/0004-ras-record-reorder-functions.patch b/SOURCES/0004-ras-record-reorder-functions.patch new file mode 100644 index 0000000..4e6f58b --- /dev/null +++ b/SOURCES/0004-ras-record-reorder-functions.patch @@ -0,0 +1,114 @@ +From 4474f696c9207ceb21d55a0047ab6871879afe5a Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 13:51:55 -0300 +Subject: [PATCH 04/32] ras-record: reorder functions + +No functional changes + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-record.c | 77 +++++++++++++++++++++++++++++---------------------------- + 1 files changed, 39 insertions(+), 38 deletions(-) + +diff --git a/ras-record.c b/ras-record.c +index efcd78f..298977e 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -46,6 +46,10 @@ struct db_table_descriptor { + size_t num_fields; + }; + ++/* ++ * Table and functions to handle ras:mc_event ++ */ ++ + static const struct db_fields mc_event_fields[] = { + { .name="id", .type="INTEGER PRIMARY KEY" }, + { .name="timestamp", .type="TEXT" }, +@@ -69,8 +73,41 @@ static const struct db_table_descriptor mc_event_tab = { + .num_fields = ARRAY_SIZE(mc_event_fields), + }; + +-const char *insertdb = "INSERT INTO"; +-const char *valuesdb = " VALUES "; ++int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) ++{ ++ int rc; ++ struct sqlite3_priv *priv = ras->db_priv; ++ ++ if (!priv || !priv->stmt_mc_event) ++ return 0; ++ log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt_mc_event); ++ ++ sqlite3_bind_text(priv->stmt_mc_event, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_int (priv->stmt_mc_event, 2, ev->error_count); ++ sqlite3_bind_text(priv->stmt_mc_event, 3, ev->error_type, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mc_event, 4, ev->msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mc_event, 5, ev->label, -1, NULL); ++ sqlite3_bind_int (priv->stmt_mc_event, 6, ev->mc_index); ++ sqlite3_bind_int (priv->stmt_mc_event, 7, ev->top_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 8, ev->middle_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 9, ev->lower_layer); ++ sqlite3_bind_int (priv->stmt_mc_event, 10, ev->address); ++ sqlite3_bind_int (priv->stmt_mc_event, 11, ev->grain); ++ sqlite3_bind_int (priv->stmt_mc_event, 12, ev->syndrome); ++ sqlite3_bind_text(priv->stmt_mc_event, 13, ev->driver_detail, -1, NULL); ++ rc = sqlite3_step(priv->stmt_mc_event); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed to do mc_event step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_mc_event); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed reset mc_event on sqlite: error = %d\n", ++ rc); ++ log(TERM, LOG_INFO, "register inserted at db\n"); ++ ++ return rc; ++} + + static int ras_mc_prepare_stmt(struct sqlite3_priv *priv, + sqlite3_stmt **stmt, +@@ -208,39 +245,3 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + + return 0; + } +- +-int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) +-{ +- int rc; +- struct sqlite3_priv *priv = ras->db_priv; +- +- if (!priv || !priv->stmt_mc_event) +- return 0; +- log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt_mc_event); +- +- sqlite3_bind_text(priv->stmt_mc_event, 1, ev->timestamp, -1, NULL); +- sqlite3_bind_int (priv->stmt_mc_event, 2, ev->error_count); +- sqlite3_bind_text(priv->stmt_mc_event, 3, ev->error_type, -1, NULL); +- sqlite3_bind_text(priv->stmt_mc_event, 4, ev->msg, -1, NULL); +- sqlite3_bind_text(priv->stmt_mc_event, 5, ev->label, -1, NULL); +- sqlite3_bind_int (priv->stmt_mc_event, 6, ev->mc_index); +- sqlite3_bind_int (priv->stmt_mc_event, 7, ev->top_layer); +- sqlite3_bind_int (priv->stmt_mc_event, 8, ev->middle_layer); +- sqlite3_bind_int (priv->stmt_mc_event, 9, ev->lower_layer); +- sqlite3_bind_int (priv->stmt_mc_event, 10, ev->address); +- sqlite3_bind_int (priv->stmt_mc_event, 11, ev->grain); +- sqlite3_bind_int (priv->stmt_mc_event, 12, ev->syndrome); +- sqlite3_bind_text(priv->stmt_mc_event, 13, ev->driver_detail, -1, NULL); +- rc = sqlite3_step(priv->stmt_mc_event); +- if (rc != SQLITE_OK && rc != SQLITE_DONE) +- log(TERM, LOG_ERR, +- "Failed to do mc_event step on sqlite: error = %d\n", rc); +- rc = sqlite3_reset(priv->stmt_mc_event); +- if (rc != SQLITE_OK && rc != SQLITE_DONE) +- log(TERM, LOG_ERR, +- "Failed reset mc_event on sqlite: error = %d\n", +- rc); +- log(TERM, LOG_INFO, "register inserted at db\n"); +- +- return rc; +-} +-- +1.7.1 + diff --git a/SOURCES/0005-ras-record-Make-the-code-easier-to-add-support-for-o.patch b/SOURCES/0005-ras-record-Make-the-code-easier-to-add-support-for-o.patch new file mode 100644 index 0000000..ec8c437 --- /dev/null +++ b/SOURCES/0005-ras-record-Make-the-code-easier-to-add-support-for-o.patch @@ -0,0 +1,60 @@ +From 93217061a4b1dc7f287f2715aadc621d2c00425d Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 13:53:18 -0300 +Subject: [PATCH 05/32] ras-record: Make the code easier to add support for other tables + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-record.c | 25 ++++++++----------------- + 1 files changed, 8 insertions(+), 17 deletions(-) + +diff --git a/ras-record.c b/ras-record.c +index 298977e..36b3373 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -143,10 +143,14 @@ static int ras_mc_prepare_stmt(struct sqlite3_priv *priv, + #endif + + rc = sqlite3_prepare_v2(priv->db, sql, -1, stmt, NULL); +- if (rc != SQLITE_OK) ++ if (rc != SQLITE_OK) { + log(TERM, LOG_ERR, + "Failed to prepare insert db at table %s (db %s): error = %s\n", + db_tab->name, SQLITE_RAS_DB, sqlite3_errmsg(priv->db)); ++ stmt = NULL; ++ } else { ++ log(TERM, LOG_INFO, "Recording %s events\n", db_tab->name); ++ } + + return rc; + } +@@ -225,23 +229,10 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + priv->db = db; + + rc = ras_mc_create_table(priv, &mc_event_tab); +- if (rc != SQLITE_OK) { +- sqlite3_close(db); +- free(priv); +- return -1; +- } ++ if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_mc_event, &mc_event_tab); + +- rc = ras_mc_prepare_stmt(priv, &priv->stmt_mc_event, &mc_event_tab); +- if (rc == SQLITE_OK) { +- log(TERM, LOG_INFO, +- "cpu %u: Recording events at %s\n", +- cpu, SQLITE_RAS_DB); +- ras->db_priv = priv; +- } else { +- sqlite3_close(db); +- free(priv); +- return -1; +- } + ++ ras->db_priv = priv; + return 0; + } +-- +1.7.1 + diff --git a/SOURCES/0006-Add-support-to-record-AER-events.patch b/SOURCES/0006-Add-support-to-record-AER-events.patch new file mode 100644 index 0000000..5d5ab87 --- /dev/null +++ b/SOURCES/0006-Add-support-to-record-AER-events.patch @@ -0,0 +1,141 @@ +From 11004aaa98865dd7c0ee28b4af8d6ba6b6f11507 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 13:54:11 -0300 +Subject: [PATCH 06/32] Add support to record AER events + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-aer-handler.c | 4 ++- + ras-record.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + ras-record.h | 6 +++++ + 3 files changed, 68 insertions(+), 2 deletions(-) + +diff --git a/ras-aer-handler.c b/ras-aer-handler.c +index ec63e2a..e5abaca 100644 +--- a/ras-aer-handler.c ++++ b/ras-aer-handler.c +@@ -111,7 +111,9 @@ int ras_aer_event_handler(struct trace_seq *s, + trace_seq_puts(s, ev.error_type); + + /* Insert data into the SGBD */ +-// ras_store_aer_event(ras, &ev); ++#ifdef HAVE_SQLITE3 ++ ras_store_aer_event(ras, &ev); ++#endif + + return 0; + } +diff --git a/ras-record.c b/ras-record.c +index 36b3373..cb302ce 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -26,6 +26,7 @@ + #include + #include "ras-events.h" + #include "ras-mc-handler.h" ++#include "ras-aer-handler.h" + #include "ras-logger.h" + + /* #define DEBUG_SQL 1 */ +@@ -109,6 +110,56 @@ int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) + return rc; + } + ++/* ++ * Table and functions to handle ras:aer ++ */ ++ ++#ifdef HAVE_AER ++static const struct db_fields aer_event_fields[] = { ++ { .name="id", .type="INTEGER PRIMARY KEY" }, ++ { .name="timestamp", .type="TEXT" }, ++ { .name="err_type", .type="TEXT" }, ++ { .name="err_msg", .type="TEXT" }, ++}; ++ ++static const struct db_table_descriptor aer_event_tab = { ++ .name = "aer_event", ++ .fields = aer_event_fields, ++ .num_fields = ARRAY_SIZE(aer_event_fields), ++}; ++ ++int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) ++{ ++ int rc; ++ struct sqlite3_priv *priv = ras->db_priv; ++ ++ if (!priv || !priv->stmt_aer_event) ++ return 0; ++ log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt_aer_event); ++ ++ sqlite3_bind_text(priv->stmt_aer_event, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_text(priv->stmt_aer_event, 3, ev->error_type, -1, NULL); ++ sqlite3_bind_text(priv->stmt_aer_event, 4, ev->msg, -1, NULL); ++ ++ rc = sqlite3_step(priv->stmt_aer_event); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed to do aer_event step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_aer_event); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed reset aer_event on sqlite: error = %d\n", ++ rc); ++ log(TERM, LOG_INFO, "register inserted at db\n"); ++ ++ return rc; ++} ++#endif ++ ++/* ++ * Generic code ++ */ ++ + static int ras_mc_prepare_stmt(struct sqlite3_priv *priv, + sqlite3_stmt **stmt, + const struct db_table_descriptor *db_tab) +@@ -230,8 +281,15 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + + rc = ras_mc_create_table(priv, &mc_event_tab); + if (rc == SQLITE_OK) +- rc = ras_mc_prepare_stmt(priv, &priv->stmt_mc_event, &mc_event_tab); ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_mc_event, ++ &mc_event_tab); + ++#ifdef HAVE_AER ++ rc = ras_mc_create_table(priv, &aer_event_tab); ++ if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_aer_event, ++ &aer_event_tab); ++#endif + + ras->db_priv = priv; + return 0; +diff --git a/ras-record.h b/ras-record.h +index 9791185..5008906 100644 +--- a/ras-record.h ++++ b/ras-record.h +@@ -47,14 +47,20 @@ struct ras_aer_event { + struct sqlite3_priv { + sqlite3 *db; + sqlite3_stmt *stmt_mc_event; ++#ifdef HAVE_AER ++ sqlite3_stmt *stmt_aer_event; ++#endif + }; + + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras); + int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev); ++int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev); + + #else + static inline int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) { return 0; }; + static inline int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) { return 0; }; ++static inline int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; }; ++ + #endif + + #endif +-- +1.7.1 + diff --git a/SOURCES/0007-Add-support-to-store-MCE-events-at-the-database.patch b/SOURCES/0007-Add-support-to-store-MCE-events-at-the-database.patch new file mode 100644 index 0000000..8caf335 --- /dev/null +++ b/SOURCES/0007-Add-support-to-store-MCE-events-at-the-database.patch @@ -0,0 +1,202 @@ +From 0a31d938cf29e065e96de1206a7d35042962e02a Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 14:18:24 -0300 +Subject: [PATCH 07/32] Add support to store MCE events at the database + +Signed-off-by: Mauro Carvalho Chehab +--- + ras-mce-handler.c | 5 +++ + ras-record.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++- + ras-record.h | 9 +++++ + 3 files changed, 116 insertions(+), 2 deletions(-) + +diff --git a/ras-mce-handler.c b/ras-mce-handler.c +index 614a0eb..59e8d05 100644 +--- a/ras-mce-handler.c ++++ b/ras-mce-handler.c +@@ -396,5 +396,10 @@ int ras_mce_event_handler(struct trace_seq *s, + return rc; + + report_mce_event(ras, record, s, &e); ++ ++#ifdef HAVE_SQLITE3 ++ ras_store_mce_record(ras, &e); ++#endif ++ + return 0; + } +diff --git a/ras-record.c b/ras-record.c +index cb302ce..daa3cb1 100644 +--- a/ras-record.c ++++ b/ras-record.c +@@ -27,6 +27,7 @@ + #include "ras-events.h" + #include "ras-mc-handler.h" + #include "ras-aer-handler.h" ++#include "ras-mce-handler.h" + #include "ras-logger.h" + + /* #define DEBUG_SQL 1 */ +@@ -135,7 +136,7 @@ int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) + + if (!priv || !priv->stmt_aer_event) + return 0; +- log(TERM, LOG_INFO, "mc_event store: %p\n", priv->stmt_aer_event); ++ log(TERM, LOG_INFO, "aer_event store: %p\n", priv->stmt_aer_event); + + sqlite3_bind_text(priv->stmt_aer_event, 1, ev->timestamp, -1, NULL); + sqlite3_bind_text(priv->stmt_aer_event, 3, ev->error_type, -1, NULL); +@@ -156,6 +157,98 @@ int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) + } + #endif + ++ ++/* ++ * Table and functions to handle mce:mce_record ++ */ ++ ++#ifdef HAVE_MCE ++static const struct db_fields mce_record_fields[] = { ++ { .name="id", .type="INTEGER PRIMARY KEY" }, ++ { .name="timestamp", .type="TEXT" }, ++ ++ /* MCE registers */ ++ { .name="mcgcap", .type="INTEGER" }, ++ { .name="mcgstatus", .type="INTEGER" }, ++ { .name="status", .type="INTEGER" }, ++ { .name="addr", .type="INTEGER" }, // 5 ++ { .name="misc", .type="INTEGER" }, ++ { .name="ip", .type="INTEGER" }, ++ { .name="tsc", .type="INTEGER" }, ++ { .name="walltime", .type="INTEGER" }, ++ { .name="cpu", .type="INTEGER" }, // 10 ++ { .name="cpuid", .type="INTEGER" }, ++ { .name="apicid", .type="INTEGER" }, ++ { .name="socketid", .type="INTEGER" }, ++ { .name="cs", .type="INTEGER" }, ++ { .name="bank", .type="INTEGER" }, //15 ++ { .name="cpuvendor", .type="INTEGER" }, ++ ++ /* Parsed data - will likely change */ ++ { .name="bank_name", .type="TEXT" }, ++ { .name="error_msg", .type="TEXT" }, ++ { .name="mcgstatus_msg", .type="TEXT" }, ++ { .name="mcistatus_msg", .type="TEXT" }, // 20 ++ { .name="user_action", .type="TEXT" }, ++ { .name="mc_location", .type="TEXT" }, ++}; ++ ++static const struct db_table_descriptor mce_record_tab = { ++ .name = "mce_record", ++ .fields = mce_record_fields, ++ .num_fields = ARRAY_SIZE(mce_record_fields), ++}; ++ ++int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev) ++{ ++ int rc; ++ struct sqlite3_priv *priv = ras->db_priv; ++ ++ if (!priv || !priv->stmt_mce_record) ++ return 0; ++ log(TERM, LOG_INFO, "mce_record store: %p\n", priv->stmt_mce_record); ++ ++ sqlite3_bind_text(priv->stmt_mce_record, 1, ev->timestamp, -1, NULL); ++ sqlite3_bind_int (priv->stmt_mce_record, 2, ev->mcgcap); ++ sqlite3_bind_int (priv->stmt_mce_record, 3, ev->mcgstatus); ++ sqlite3_bind_int (priv->stmt_mce_record, 4, ev->status); ++ sqlite3_bind_int (priv->stmt_mce_record, 5, ev->addr); ++ sqlite3_bind_int (priv->stmt_mce_record, 6, ev->misc); ++ sqlite3_bind_int (priv->stmt_mce_record, 7, ev->ip); ++ sqlite3_bind_int (priv->stmt_mce_record, 8, ev->tsc); ++ sqlite3_bind_int (priv->stmt_mce_record, 9, ev->walltime); ++ sqlite3_bind_int (priv->stmt_mce_record, 10, ev->cpu); ++ sqlite3_bind_int (priv->stmt_mce_record, 11, ev->cpuid); ++ sqlite3_bind_int (priv->stmt_mce_record, 12, ev->apicid); ++ sqlite3_bind_int (priv->stmt_mce_record, 13, ev->socketid); ++ sqlite3_bind_int (priv->stmt_mce_record, 14, ev->cs); ++ sqlite3_bind_int (priv->stmt_mce_record, 15, ev->bank); ++ sqlite3_bind_int (priv->stmt_mce_record, 16, ev->cpuvendor); ++ ++ sqlite3_bind_text(priv->stmt_mce_record, 17, ev->bank_name, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 18, ev->error_msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 19, ev->mcgstatus_msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 20, ev->mcistatus_msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 21, ev->mcastatus_msg, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 22, ev->user_action, -1, NULL); ++ sqlite3_bind_text(priv->stmt_mce_record, 23, ev->mc_location, -1, NULL); ++ ++ rc = sqlite3_step(priv->stmt_mce_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed to do mce_record step on sqlite: error = %d\n", rc); ++ rc = sqlite3_reset(priv->stmt_mce_record); ++ if (rc != SQLITE_OK && rc != SQLITE_DONE) ++ log(TERM, LOG_ERR, ++ "Failed reset mce_record on sqlite: error = %d\n", ++ rc); ++ log(TERM, LOG_INFO, "register inserted at db\n"); ++ ++ return rc; ++} ++#endif ++ ++ + /* + * Generic code + */ +@@ -291,6 +384,13 @@ int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) + &aer_event_tab); + #endif + +- ras->db_priv = priv; ++#ifdef HAVE_MCE ++ rc = ras_mc_create_table(priv, &mce_record_tab); ++ if (rc == SQLITE_OK) ++ rc = ras_mc_prepare_stmt(priv, &priv->stmt_mce_record, ++ &mce_record_tab); ++#endif ++ ++ ras->db_priv = priv; + return 0; + } +diff --git a/ras-record.h b/ras-record.h +index 5008906..6f146a8 100644 +--- a/ras-record.h ++++ b/ras-record.h +@@ -40,6 +40,10 @@ struct ras_aer_event { + const char *msg; + }; + ++struct ras_mc_event; ++struct ras_aer_event; ++struct mce_event; ++ + #ifdef HAVE_SQLITE3 + + #include +@@ -50,16 +54,21 @@ struct sqlite3_priv { + #ifdef HAVE_AER + sqlite3_stmt *stmt_aer_event; + #endif ++#ifdef HAVE_MCE ++ sqlite3_stmt *stmt_mce_record; ++#endif + }; + + int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras); + int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev); + int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev); ++int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev); + + #else + static inline int ras_mc_event_opendb(unsigned cpu, struct ras_events *ras) { return 0; }; + static inline int ras_store_mc_event(struct ras_events *ras, struct ras_mc_event *ev) { return 0; }; + static inline int ras_store_aer_event(struct ras_events *ras, struct ras_aer_event *ev) { return 0; }; ++static inline int ras_store_mce_record(struct ras_events *ras, struct mce_event *ev) { return 0; }; + + #endif + +-- +1.7.1 + diff --git a/SOURCES/0008-ras-mc-ctl-add-summary-for-MCE-and-PCIe-AER-errors.patch b/SOURCES/0008-ras-mc-ctl-add-summary-for-MCE-and-PCIe-AER-errors.patch new file mode 100644 index 0000000..18d1dad --- /dev/null +++ b/SOURCES/0008-ras-mc-ctl-add-summary-for-MCE-and-PCIe-AER-errors.patch @@ -0,0 +1,85 @@ +From 2925cc92d73065dab3bbf7de83404d6e0e141dc6 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 14:57:54 -0300 +Subject: [PATCH 08/32] ras-mc-ctl: add summary for MCE and PCIe AER errors + +Report the summary also for MCE and PCIe errors. + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 50 ++++++++++++++++++++++++++++++++++++++++++++------ + 1 files changed, 44 insertions(+), 6 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index 5b1ca4d..118af7b 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -824,21 +824,59 @@ sub find_prog + sub summary + { + require DBI; ++ my ($query, $query_handle, $out); ++ my ($err_type, $label, $mc, $top, $mid, $low, $count, $msg); + + my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {}); + +- my $query = "select label, mc, top_layer,middle_layer,lower_layer, count(*) from mc_event group by label,mc,top_layer,middle_layer,lower_layer"; +- my $query_handle = $dbh->prepare($query); ++ # Memory controller mc_event errors ++ $query = "select err_type, label, mc, top_layer,middle_layer,lower_layer, count(*) from mc_event group by err_type, label, mc, top_layer, middle_layer, lower_layer"; ++ $query_handle = $dbh->prepare($query); + $query_handle->execute(); ++ $query_handle->bind_columns(\($err_type, $label, $mc, $top, $mid, $low, $count)); ++ $out = ""; ++ while($query_handle->fetch()) { ++ $out .= "\t$err_type on DIMM Label(s): '$label' location: $mc:$top:$mid:$low errors: $count\n"; ++ } ++ if ($out ne "") { ++ print "Memory controller events summary:\n$out\n"; ++ } else { ++ print "No Memory errors.\n\n"; ++ } ++ $query_handle->finish; + +- $query_handle->bind_columns(\my($label, $mc, $top, $mid, $low, $count)); +- +- print "Memory controller events summary:\n"; ++ # PCIe AER aer_event errors ++ $query = "select err_type, err_msg, count(*) from aer_event group by err_type, err_msg"; ++ $query_handle = $dbh->prepare($query); ++ $query_handle->execute(); ++ $query_handle->bind_columns(\($err_type, $msg, $count)); ++ $out = ""; + while($query_handle->fetch()) { +- print "DIMM Label(s): '$label' location: $mc:$top:$mid:$low errors: $count\n"; ++ $out .= "\t$count $err_type errors: $msg\n"; + } ++ if ($out ne "") { ++ print "PCIe AER events summary:\n$out\n"; ++ } else { ++ print "No PCIe AER errors.\n\n"; ++ } ++ $query_handle->finish; + ++ # MCE mce_record errors ++ $query = "select error_msg, count(*) from mce_record group by error_msg"; ++ $query_handle = $dbh->prepare($query); ++ $query_handle->execute(); ++ $query_handle->bind_columns(\($msg, $count)); ++ $out = ""; ++ while($query_handle->fetch()) { ++ $out .= "\t$count $msg errors\n"; ++ } ++ if ($out ne "") { ++ print "MCE records summary:\n$out"; ++ } else { ++ print "No MCE errors.\n"; ++ } + $query_handle->finish; ++ + undef($dbh); + } + +-- +1.7.1 + diff --git a/SOURCES/0009-ras-mc-ctl-report-errors-also-for-PCIe-AER-and-MCE.patch b/SOURCES/0009-ras-mc-ctl-report-errors-also-for-PCIe-AER-and-MCE.patch new file mode 100644 index 0000000..fda9b46 --- /dev/null +++ b/SOURCES/0009-ras-mc-ctl-report-errors-also-for-PCIe-AER-and-MCE.patch @@ -0,0 +1,108 @@ +From 4b64649eb5740027f58377f6c29d1554d9792b97 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 16:16:44 -0300 +Subject: [PATCH 09/32] ras-mc-ctl: report errors also for PCIe AER and MCE + +Show also PCIe AER and MCE when used with --errors parameter. + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 73 +++++++++++++++++++++++++++++++++++++++++++++++----- + 1 files changed, 66 insertions(+), 7 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index 118af7b..30d3078 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -883,22 +883,81 @@ sub summary + sub errors + { + require DBI; ++ my ($query, $query_handle, $id, $time, $count, $type, $msg, $label, $mc, $top, $mid, $low, $addr, $grain, $syndrome, $detail, $out); ++ my ($mcgcap,$mcgstatus, $status, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location); + + my $dbh = DBI->connect("dbi:SQLite:dbname=$dbname", "", "", {}); + +- my $query = "select id, timestamp, err_count, err_type, err_msg, label, mc, top_layer,middle_layer,lower_layer, address, grain, syndrome, driver_detail from mc_event order by id"; +- +- my $query_handle = $dbh->prepare($query); ++ # Memory controller mc_event errors ++ $query = "select id, timestamp, err_count, err_type, err_msg, label, mc, top_layer,middle_layer,lower_layer, address, grain, syndrome, driver_detail from mc_event order by id"; ++ $query_handle = $dbh->prepare($query); + $query_handle->execute(); ++ $query_handle->bind_columns(\($id, $time, $count, $type, $msg, $label, $mc, $top, $mid, $low, $addr, $grain, $syndrome, $detail)); ++ $out = ""; ++ while($query_handle->fetch()) { ++ $out .= "$id $time $count $type error(s): $msg at $label location: $mc:$top:$mid:$low, addr $addr, grain $grain, syndrome $syndrome $detail\n"; ++ } ++ if ($out ne "") { ++ print "PCIe AER events:\n$out\n"; ++ } else { ++ print "No PCIe AER errors.\n\n"; ++ } ++ $query_handle->finish; + +- $query_handle->bind_columns(\my($id, $time, $count, $type, $msg, $label, $mc, $top, $mid, $low, $addr, $grain, $syndrome, $detail)); +- +- print "Memory controller events:\n"; ++ # PCIe AER aer_event errors ++ $query = "select id, timestamp, err_type, err_msg from aer_event order by id"; ++ $query_handle = $dbh->prepare($query); ++ $query_handle->execute(); ++ $query_handle->bind_columns(\($id, $time, $type, $msg)); ++ $out = ""; + while($query_handle->fetch()) { +- print "$id $time $count $type error(s): $msg at $label location: $mc:$top:$mid:$low, addr $addr, grain $grain, syndrome $syndrome $detail\n"; ++ $out .= "$id $time $type error: $msg\n"; + } ++ if ($out ne "") { ++ print "MCE events:\n$out\n"; ++ } else { ++ print "No MCE errors.\n\n"; ++ } ++ $query_handle->finish; + ++ # MCE mce_record errors ++ $query = "select id, timestamp, mcgcap, mcgstatus, status, addr, misc, ip, tsc, walltime, cpu, cpuid, apicid, socketid, cs, bank, cpuvendor, bank_name, error_msg, mcgstatus_msg, mcistatus_msg, user_action, mc_location from mce_record order by id"; ++ $query_handle = $dbh->prepare($query); ++ $query_handle->execute(); ++ $query_handle->bind_columns(\($id, $time, $mcgcap,$mcgstatus, $status, $addr, $misc, $ip, $tsc, $walltime, $cpu, $cpuid, $apicid, $socketid, $cs, $bank, $cpuvendor, $bank_name, $msg, $mcgstatus_msg, $mcistatus_msg, $user_action, $mc_location)); ++ $out = ""; ++ while($query_handle->fetch()) { ++ $out .= "$id $time error: $msg"; ++ $out .= ", CPU $cpuvendor" if ($cpuvendor); ++ $out .= ", bank $bank_name" if ($bank_name); ++ $out .= ", mcg $mcgstatus_msg" if ($mcgstatus_msg); ++ $out .= ", mci $mcistatus_msg" if ($mcistatus_msg); ++ $out .= ", $mc_location" if ($mc_location); ++ $out .= ", $user_action" if ($user_action); ++ $out .= sprintf ", mcgcap=0x%08x", $mcgcap if ($mcgcap); ++ $out .= sprintf ", mcgstatus=0x%08x", $mcgstatus if ($mcgstatus); ++ $out .= sprintf ", status=0x%08x", $status if ($status); ++ $out .= sprintf ", addr=0x%08x", $addr if ($addr); ++ $out .= sprintf ", misc=0x%08x", $misc if ($misc); ++ $out .= sprintf ", ip=0x%08x", $ip if ($ip); ++ $out .= sprintf ", tsc=0x%08x", $tsc if ($tsc); ++ $out .= sprintf ", walltime=0x%08x", $walltime if ($walltime); ++ $out .= sprintf ", cpu=0x%08x", $cpu if ($cpu); ++ $out .= sprintf ", cpuid=0x%08x", $cpuid if ($cpuid); ++ $out .= sprintf ", apicid=0x%08x", $apicid if ($apicid); ++ $out .= sprintf ", socketid=0x%08x", $socketid if ($socketid); ++ $out .= sprintf ", cs=0x%08x", $cs if ($cs); ++ $out .= sprintf ", bank=0x%08x", $bank if ($bank); ++ ++ $out .= "\n"; ++ } ++ if ($out ne "") { ++ print "Memory controller events:\n$out\n"; ++ } else { ++ print "No Memory errors.\n\n"; ++ } + $query_handle->finish; ++ + undef($dbh); + } + +-- +1.7.1 + diff --git a/SOURCES/0010-ras-mc-ctl-Fix-the-name-of-the-error-table-data.patch b/SOURCES/0010-ras-mc-ctl-Fix-the-name-of-the-error-table-data.patch new file mode 100644 index 0000000..5500798 --- /dev/null +++ b/SOURCES/0010-ras-mc-ctl-Fix-the-name-of-the-error-table-data.patch @@ -0,0 +1,53 @@ +From dc811f88b1bd5ac33faa1606c3a3ce4d3bc0b7ed Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Fri, 31 May 2013 16:40:40 -0300 +Subject: [PATCH 10/32] ras-mc-ctl: Fix the name of the error table data + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 12 ++++++------ + 1 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index 30d3078..48d9b00 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -898,9 +898,9 @@ sub errors + $out .= "$id $time $count $type error(s): $msg at $label location: $mc:$top:$mid:$low, addr $addr, grain $grain, syndrome $syndrome $detail\n"; + } + if ($out ne "") { +- print "PCIe AER events:\n$out\n"; ++ print "Memory controller events:\n$out\n"; + } else { +- print "No PCIe AER errors.\n\n"; ++ print "No Memory errors.\n\n"; + } + $query_handle->finish; + +@@ -914,9 +914,9 @@ sub errors + $out .= "$id $time $type error: $msg\n"; + } + if ($out ne "") { +- print "MCE events:\n$out\n"; ++ print "PCIe AER events:\n$out\n"; + } else { +- print "No MCE errors.\n\n"; ++ print "No PCIe AER errors.\n\n"; + } + $query_handle->finish; + +@@ -952,9 +952,9 @@ sub errors + $out .= "\n"; + } + if ($out ne "") { +- print "Memory controller events:\n$out\n"; ++ print "MCE events:\n$out\n"; + } else { +- print "No Memory errors.\n\n"; ++ print "No MCE errors.\n\n"; + } + $query_handle->finish; + +-- +1.7.1 + diff --git a/SOURCES/0013-ras-mc-ctl-Improve-parser.patch b/SOURCES/0013-ras-mc-ctl-Improve-parser.patch new file mode 100644 index 0000000..7900f18 --- /dev/null +++ b/SOURCES/0013-ras-mc-ctl-Improve-parser.patch @@ -0,0 +1,36 @@ +From 099af4056912faa28bf1385fffa77e7bbb468b93 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Thu, 15 Aug 2013 12:43:02 -0300 +Subject: [PATCH 13/32] ras-mc-ctl: Improve parser + +Accept either . or : as layers separator at config files. + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index 48d9b00..f5a8ce5 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -481,14 +481,14 @@ sub parse_dimm_labels_file + + next unless (my ($label, $info) = ($str =~ /^(.*)\s*:\s*(.*)$/i)); + +- unless ($info =~ /\d+(?:\.\d+)*/) { ++ unless ($info =~ /\d+(?:[\.\:]\d+)*/) { + log_error ("$file: $line: Invalid syntax, ignoring: \"$_\"\n"); + next; + } + + for my $target (split (/[, ]+/, $info)) { + my $n; +- my ($mc, $top, $mid, $low, $extra) = ($target =~ /(\d+)(?:\.(\d+)){0,1}(?:\.(\d+)){0,1}(?:\.(\d+)){0,1}(?:\.(\d+)){0,1}/); ++ my ($mc, $top, $mid, $low, $extra) = ($target =~ /(\d+)(?:[\.\:](\d+)){0,1}(?:[\.\:](\d+)){0,1}(?:[\.\:](\d+)){0,1}(?:[\.\:](\d+)){0,1}/); + + if (defined($extra)) { + die ("Error: Only up to 3 layers are currently supported on label db \"$file\"\n"); +-- +1.7.1 + diff --git a/SOURCES/0014-ras-mc-ctl-Fix-label-register-with-2-layers.patch b/SOURCES/0014-ras-mc-ctl-Fix-label-register-with-2-layers.patch new file mode 100644 index 0000000..6274324 --- /dev/null +++ b/SOURCES/0014-ras-mc-ctl-Fix-label-register-with-2-layers.patch @@ -0,0 +1,77 @@ +From 0d53728f9cbdca5a1bd32c51a121dd1162f50e95 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Thu, 15 Aug 2013 12:45:18 -0300 +Subject: [PATCH 14/32] ras-mc-ctl: Fix label register with 2 layers + +When there aren't 3 layers, label print/register weren't working. + +Signed-off-by: Mauro Carvalho Chehab +--- + util/ras-mc-ctl.in | 19 +++++++++++++------ + 1 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/util/ras-mc-ctl.in b/util/ras-mc-ctl.in +index f5a8ce5..a7137be 100755 +--- a/util/ras-mc-ctl.in ++++ b/util/ras-mc-ctl.in +@@ -508,7 +508,6 @@ sub parse_dimm_labels_file + } + map { $lh->{$vendor}{lc $_}{$mc}{$top}{$mid}{$low} = $label } + @models; +- $n = 3; + } + if (!$num) { + $num = $n; +@@ -542,9 +541,13 @@ sub parse_dimm_labels + + sub read_dimm_label + { +- my ($mc, $top, $mid, $low) = @_; ++ my ($num_layers, $mc, $top, $mid, $low) = @_; + my $sysfs = "/sys/devices/system/edac/mc"; +- my $pos = "$mc:$top:$mid:$low"; ++ my $pos; ++ ++ $pos = "$mc:$top:$mid:$low" if ($num_layers == 3); ++ $pos = "$mc:$top:$mid" if ($num_layers == 2); ++ $pos = "$mc:$top" if ($num_layers == 1); + + if (!defined($dimm_node{$pos})) { + my $label = "$pos missing"; +@@ -574,10 +577,14 @@ sub read_dimm_label + + sub get_dimm_label_node + { +- my ($mc, $top, $mid, $low) = @_; ++ my ($num_layers, $mc, $top, $mid, $low) = @_; + my $sysfs = "/sys/devices/system/edac/mc"; + my $pos = "$mc:$top:$mid:$low"; + ++ $pos = "$mc:$top:$mid:$low" if ($num_layers == 3); ++ $pos = "$mc:$top:$mid" if ($num_layers == 2); ++ $pos = "$mc:$top" if ($num_layers == 1); ++ + return "" if (!defined($dimm_node{$pos})); + + my $dimm = $dimm_node{$pos}; +@@ -611,7 +618,7 @@ sub print_dimm_labels + for my $mid (sort keys %{$$lref{$vendor}{$model}{$mc}{$top}}) { + for my $low (sort keys %{$$lref{$vendor}{$model}{$mc}{$top}{$mid}}) { + my $label = $$lref{$vendor}{$model}{$mc}{$top}{$mid}{$low}; +- my ($rlabel,$loc) = read_dimm_label ($mc, $top, $mid, $low); ++ my ($rlabel,$loc) = read_dimm_label ($$num_layers{$vendor}{$model}, $mc, $top, $mid, $low); + + printf $fh $format, $loc, $label, $rlabel; + } +@@ -645,7 +652,7 @@ sub register_dimm_labels + for my $mid (sort keys %{$$lref{$vendor}{$model}{$mc}{$top}}) { + for my $low (sort keys %{$$lref{$vendor}{$model}{$mc}{$top}{$mid}}) { + +- my $file = get_dimm_label_node($mc, $top, $mid, $low); ++ my $file = get_dimm_label_node($$num_layers{$vendor}{$model}, $mc, $top, $mid, $low); + + # Ignore sysfs files that don't exist. Might just be + # unpopulated bank. +-- +1.7.1 + diff --git a/SOURCES/0015-Add-an-example-of-labels-file.patch b/SOURCES/0015-Add-an-example-of-labels-file.patch new file mode 100644 index 0000000..f7e64b7 --- /dev/null +++ b/SOURCES/0015-Add-an-example-of-labels-file.patch @@ -0,0 +1,44 @@ +From 74d84ba18f4f1d7097b47ce1c2e41e332d197dfb Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Thu, 15 Aug 2013 12:58:02 -0300 +Subject: [PATCH 15/32] Add an example of labels file + +This is an example of a labels file for a Dell Power Edge T620. + +For now, only DIMMs A1 and B1 are tested here. + +Signed-off-by: Mauro Carvalho Chehab +--- + labels/dell | 20 ++++++++++++++++++++ + 1 files changed, 20 insertions(+), 0 deletions(-) + create mode 100644 labels/dell + +diff --git a/labels/dell b/labels/dell +new file mode 100644 +index 0000000..e1a09a7 +--- /dev/null ++++ b/labels/dell +@@ -0,0 +1,20 @@ ++# RASDAEMON Motherboard DIMM labels Database file. ++# ++# Vendor-name and model-name are found from the program 'dmidecode' ++# labels are found from the silk screen on the motherboard. ++# ++#Vendor: ++# Model: ++#