]> www.infradead.org Git - users/mchehab/rasdaemon.git/commitdiff
Add devlink filter and net_dev_xmit_timeout
authorCong Wang <xiyou.wangcong@gmail.com>
Sun, 2 Jun 2019 00:16:54 +0000 (17:16 -0700)
committerCong Wang <xiyou.wangcong@gmail.com>
Sun, 2 Jun 2019 04:00:20 +0000 (21:00 -0700)
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
ras-devlink-handler.c
ras-devlink-handler.h
ras-events.c
ras-events.h
ras-record.h

index 0fe46d2d82c3810b16a5ed7b386184b4e8a375a9..2699291c646ca10c275a0cdef305f66dbe4f13ec 100644 (file)
@@ -15,6 +15,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
+#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "ras-logger.h"
 #include "ras-report.h"
 
+int ras_net_xmit_timeout_handler(struct trace_seq *s,
+                                struct pevent_record *record,
+                                struct event_format *event, void *context)
+{
+       unsigned long long val;
+       int len;
+       struct ras_events *ras = context;
+       time_t now;
+       struct tm *tm;
+       struct devlink_event ev;
+
+       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);
+       trace_seq_printf(s, "%s ", ev.timestamp);
+
+       ev.bus_name = "";
+       ev.reporter_name = "";
+
+       ev.dev_name = pevent_get_field_raw(s, event, "name",
+                                          record, &len, 1);
+       if (!ev.dev_name)
+               return -1;
+
+       ev.driver_name = pevent_get_field_raw(s, event, "driver",
+                                          record, &len, 1);
+       if (!ev.driver_name)
+               return -1;
+
+       if (pevent_get_field_val(s, event, "queue_index", record, &val, 1) < 0)
+               return -1;
+       if (asprintf(&ev.msg, "TX timeout on queue: %d\n", (int)val) < 0)
+               return -1;
+
+       /* Insert data into the SGBD */
+#ifdef HAVE_SQLITE3
+       ras_store_devlink_event(ras, &ev);
+#endif
+
+#ifdef HAVE_ABRT_REPORT
+       /* Report event to ABRT */
+       ras_report_devlink_event(ras, &ev);
+#endif
+
+       free(ev.msg);
+       return 0;
+
+}
+
 int ras_devlink_event_handler(struct trace_seq *s,
                              struct pevent_record *record,
                              struct event_format *event, void *context)
@@ -35,6 +91,8 @@ int ras_devlink_event_handler(struct trace_seq *s,
        struct tm *tm;
        struct devlink_event ev;
 
+       if (ras->filter && pevent_filter_match(ras->filter, record) == FILTER_MATCH)
+               return 0;
        /*
         * Newer kernels (3.10-rc1 or upper) provide an uptime clock.
         * On previous kernels, the way to properly generate an event would
index 29b64f799a2cae8c6fad56d8514bfb2d82f3e824..ca9a1b7f239ca79da56228428488aaf4bebf4c87 100644 (file)
 #include "ras-events.h"
 #include "libtrace/event-parse.h"
 
+int ras_net_xmit_timeout_handler(struct trace_seq *s,
+                                struct pevent_record *record,
+                                struct event_format *event, void *context);
+
 int ras_devlink_event_handler(struct trace_seq *s,
                              struct pevent_record *record,
                              struct event_format *event, void *context);
index a75f97978363b9aa1033093332f030face234b47..4e7b81529d5d7a1702dc002042600a38a429c55e 100644 (file)
@@ -570,10 +570,11 @@ static int select_tracing_timestamp(struct ras_events *ras)
 
 static int add_event_handler(struct ras_events *ras, struct pevent *pevent,
                             unsigned page_size, char *group, char *event,
-                            pevent_event_handler_func func)
+                            pevent_event_handler_func func, char *filter_str)
 {
        int fd, size, rc;
        char *page, fname[MAX_PATH + 1];
+       struct event_filter * filter = NULL;
 
        snprintf(fname, sizeof(fname), "events/%s/%s/format", group, event);
 
@@ -618,6 +619,28 @@ static int add_event_handler(struct ras_events *ras, struct pevent *pevent,
                return EINVAL;
        }
 
+       if (filter_str) {
+               char *error;
+
+               filter = pevent_filter_alloc(pevent);
+               if (!filter) {
+                       log(TERM, LOG_ERR,
+                           "Failed to allocate filter for %s/%s.\n", group, event);
+                       free(page);
+                       return EINVAL;
+               }
+               rc = pevent_filter_add_filter_str(filter, filter_str, &error);
+               if (rc) {
+                       log(TERM, LOG_ERR,
+                           "Failed to install filter for %s/%s: %s\n", group, event, error);
+                       pevent_filter_free(filter);
+                       free(page);
+                       return rc;
+               }
+       }
+
+       ras->filter = filter;
+
        /* Enable RAS events */
        rc = __toggle_ras_mc_event(ras, group, event, 1);
        if (rc < 0) {
@@ -641,6 +664,7 @@ int handle_ras_events(int record_events)
        struct pevent *pevent = NULL;
        struct pthread_data *data = NULL;
        struct ras_events *ras = NULL;
+       char *filter_str = NULL;
 
        ras = calloc(1, sizeof(*ras));
        if (!ras) {
@@ -674,7 +698,7 @@ int handle_ras_events(int record_events)
        ras->record_events = record_events;
 
        rc = add_event_handler(ras, pevent, page_size, "ras", "mc_event",
-                              ras_mc_event_handler);
+                              ras_mc_event_handler, NULL);
        if (!rc)
                num_events++;
        else
@@ -683,7 +707,7 @@ int handle_ras_events(int record_events)
 
 #ifdef HAVE_AER
        rc = add_event_handler(ras, pevent, page_size, "ras", "aer_event",
-                              ras_aer_event_handler);
+                              ras_aer_event_handler, NULL);
        if (!rc)
                num_events++;
        else
@@ -693,7 +717,7 @@ int handle_ras_events(int record_events)
 
 #ifdef HAVE_NON_STANDARD
         rc = add_event_handler(ras, pevent, page_size, "ras", "non_standard_event",
-                               ras_non_standard_event_handler);
+                               ras_non_standard_event_handler, NULL);
         if (!rc)
                 num_events++;
         else
@@ -703,7 +727,7 @@ int handle_ras_events(int record_events)
 
 #ifdef HAVE_ARM
         rc = add_event_handler(ras, pevent, page_size, "ras", "arm_event",
-                               ras_arm_event_handler);
+                               ras_arm_event_handler, NULL);
         if (!rc)
                 num_events++;
         else
@@ -720,7 +744,7 @@ int handle_ras_events(int record_events)
        if (ras->mce_priv) {
                rc = add_event_handler(ras, pevent, page_size,
                                       "mce", "mce_record",
-                                      ras_mce_event_handler);
+                                      ras_mce_event_handler, NULL);
                if (!rc)
                        num_events++;
        else
@@ -731,7 +755,7 @@ int handle_ras_events(int record_events)
 
 #ifdef HAVE_EXTLOG
        rc = add_event_handler(ras, pevent, page_size, "ras", "extlog_mem_event",
-                              ras_extlog_mem_event_handler);
+                              ras_extlog_mem_event_handler, NULL);
        if (!rc) {
                /* tell kernel we are listening, so don't printk to console */
                (void)open("/sys/kernel/debug/ras/daemon_active", 0);
@@ -742,9 +766,15 @@ int handle_ras_events(int record_events)
 #endif
 
 #ifdef HAVE_DEVLINK
+       rc = add_event_handler(ras, pevent, page_size, "net",
+                              "net_dev_xmit_timeout",
+                              ras_net_xmit_timeout_handler, NULL);
+        if (!rc)
+               filter_str = "devlink/devlink_health_report:msg=~\'TX timeout*\'";
+
        rc = add_event_handler(ras, pevent, page_size, "devlink",
                               "devlink_health_report",
-                              ras_devlink_event_handler);
+                              ras_devlink_event_handler, filter_str);
         if (!rc)
                 num_events++;
         else
@@ -801,8 +831,11 @@ err:
        if (pevent)
                pevent_free(pevent);
 
-       if (ras)
+       if (ras) {
+               if (ras->filter)
+                       pevent_filter_free(ras->filter);
                free(ras);
+       }
 
        return rc;
 }
index 1a783909773b8941ed8863417bfde827304f3ad4..2fae2f12a4bab359573e59025c67b2d91759b900 100644 (file)
@@ -50,6 +50,8 @@ struct ras_events {
 
        /* For ABRT socket*/
        int socketfd;
+
+       struct event_filter *filter;
 };
 
 struct pthread_data {
index f230ed22bc31aea65df875a30cb158734ba2a47c..218316790c5c09c5aa5db1cd96c2508832fbe4e6 100644 (file)
@@ -81,7 +81,7 @@ struct devlink_event {
        const char *dev_name;
        const char *driver_name;
        const char *reporter_name;
-       const char *msg;
+       char *msg;
 };
 
 struct ras_mc_event;