[ovs-dev] [RFC PATCH 20/21] keepalive: Display extended Keepalive status.

Bhanuprakash Bodireddy bhanuprakash.bodireddy at intel.com
Wed Jun 7 16:15:16 UTC 2017


This commit adds support to display the extended keepalive statistics
stored in SHM block. The status can be displayed as follows.

  $ ovs-appctl keepalive/pmd-xstats-show

  keepAlive Status  : Enabled
  keepAlive Interval: 1000 ms

  CORE: 0
      PMD thread id       : 1269 [ACTIVE]
      PMD heartbeats      : enabled
      PMD thread state    : ALIVE
      Last seen timestamp : 9123706507798853
      PMD failure cnt     : 0

  CORE: 1
      PMD thread id       : 1270 [ACTIVE]
      PMD heartbeats      : enabled
      PMD thread state    : ALIVE
      Last seen timestamp : 9123706507801627
      PMD failure cnt     : 0

  CORE: 2
      PMD thread id       : 1271 [ACTIVE]
      PMD heartbeats      : enabled
      PMD thread state    : ALIVE
      Last seen timestamp : 9125112827794550
      PMD failure cnt     : 0
      PMD health check    : enabled
      Packet Stats
          Port dpdk0, Queue: 1, Link status: up
          rx_packets : 1801284454
          tx_packets : 0
      Cycle Stats
          Polling cycles : 35426111637
          Processing cycles : 10123697085

  Datapath status   : HEALTHY

For PMD on core 2, on a heartbeat failure, health checks are enabled
and additional stats(pkt stats, cpu cycles) are displayed as above.

Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy at intel.com>
---
 lib/keepalive.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)

diff --git a/lib/keepalive.c b/lib/keepalive.c
index 3b00d01..15ca400 100644
--- a/lib/keepalive.c
+++ b/lib/keepalive.c
@@ -28,6 +28,7 @@
 #include "openvswitch/dynamic-string.h"
 #include "openvswitch/vlog.h"
 #include "ovs-thread.h"
+#include "process.h"
 #include "unixctl.h"
 
 VLOG_DEFINE_THIS_MODULE(keepalive);
@@ -625,6 +626,126 @@ ka_unixctl_status(struct unixctl_conn *conn, int argc OVS_UNUSED,
     ds_destroy(&ds);
 }
 
+static void
+ka_unixctl_pmd_xstats_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                       const char *argv[] OVS_UNUSED, void *ka_shm_)
+{
+    struct keepalive_shm *ka_shm = (struct keepalive_shm *)ka_shm_;
+    if (!ka_shm) {
+        VLOG_ERR_RL(&rl, "KeepAlive: Invalid shared memory block\n");
+        return;
+    }
+
+    struct ds ds = DS_EMPTY_INITIALIZER;
+    ds_put_format(&ds,
+                  "\t\tKeepalive xstats\n");
+
+    ds_put_format(&ds, "keepAlive Status: %s\n",
+                  is_ka_enabled() ? "Enabled" : "Disabled");
+    ds_put_format(&ds, "keepAlive Interval: %"PRIu32" ms\n",
+                  get_ka_interval());
+
+    int datapath_failure = 0;
+    for (int idx_core = 0; idx_core < KEEPALIVE_MAXCORES; idx_core++) {
+        char *state = NULL;
+        if (ka_shm->core_state[idx_core] == KA_STATE_UNUSED ||
+             ka_shm->core_state[idx_core] == KA_STATE_SLEEP)
+            continue;
+
+        switch (ka_shm->core_state[idx_core]) {
+        case KA_STATE_ALIVE:
+            state = "ALIVE";
+            break;
+        case KA_STATE_MISSING:
+            state = "MISSING";
+            break;
+        case KA_STATE_DEAD:
+            state = "DEAD";
+            break;
+        case KA_STATE_GONE:
+            state = "GONE";
+            datapath_failure++;
+            break;
+        case KA_STATE_DOZING:
+            state = "DOZING";
+            break;
+        case KA_STATE_SLEEP:
+            state = "SLEEP";
+            break;
+        case KA_STATE_CHECK:
+            state = "HEALTH_CHECK_RUNNING";
+            break;
+        case KA_STATE_UNUSED:
+            break;
+        }
+
+        ds_put_format(&ds, "\n");
+        ds_put_format(&ds, "CORE: %d\n", idx_core);
+
+        int pstate;
+        int err = get_process_status(ka_shm->thread_id[idx_core], &pstate);
+        char *tid_state = NULL;
+        if (!err) {
+            switch (pstate) {
+            case ACTIVE_STATE:
+                tid_state = "ACTIVE";
+                break;
+            case STOPPED_STATE:
+            case TRACED_STATE:
+            case DEFUNC_STATE:
+            case UNINTERRUPTIBLE_SLEEP_STATE:
+                tid_state = "INACTIVE";
+                break;
+            }
+        } else {
+            tid_state = "UNKNOWN";
+        }
+
+        ds_put_format(&ds, "\tPMD thread-id       : %d [%s]\n",
+                      ka_shm->thread_id[idx_core], tid_state);
+        ds_put_format(&ds, "\tPMD heartbeats      : %s\n",
+                      is_ka_enabled() ? "enabled" : "disabled");
+        ds_put_format(&ds, "\tPMD thread state    : %s\n", state);
+        ds_put_format(&ds, "\tLast seen timestamp : %"PRIu64"\n",
+                      ka_shm->core_last_seen_times[idx_core]);
+
+        ds_put_format(&ds, "\tPMD failure cnt     : %d\n",
+                      ka_shm->core_failures[idx_core]);
+
+        int health_check = ka_is_pmdhealth_check_needed(idx_core);
+        if (health_check) {
+            ds_put_format(&ds, "\tPMD health check    : %s\n",
+                      health_check ? "enabled" : "disabled");
+            ds_put_format(&ds, "\tPacket Stats\n");
+
+            int n = ka_shm->ext_stats[idx_core].num_poll_ports;
+            for (int idx = 0; idx < n; idx++) {
+                    ds_put_format(&ds, "\t\tPort %s, Queue: %d, Link status: %s\n",
+                                    ka_shm->ext_stats[idx_core].port_stats[idx].port,
+                                    ka_shm->ext_stats[idx_core].port_stats[idx].qid,
+                                    ka_shm->ext_stats[idx_core].port_stats[idx].link_state);
+                    ds_put_format(&ds, "\t\trx_packets : %"PRIu64"\n",
+                                    ka_shm->ext_stats[idx_core].port_stats[idx].stats.rx_packets);
+                    ds_put_format(&ds, "\t\ttx_packets : %"PRIu64"\n",
+                                    ka_shm->ext_stats[idx_core].port_stats[idx].stats.tx_packets);
+            }
+
+            ds_put_format(&ds, "\tCycle Stats\n");
+
+            ds_put_format(&ds, "\t\tPolling cycles : %"PRIu64"\n",
+                           ka_shm->ext_stats[idx_core].cycles[PMD_CYCLES_POLLING]);
+            ds_put_format(&ds, "\t\tProcessing cycles : %"PRIu64"\n",
+                           ka_shm->ext_stats[idx_core].cycles[PMD_CYCLES_PROCESSING]);
+        }
+    }
+
+    ds_put_format(&ds, "\n");
+    ds_put_format(&ds, "Datapath Status   : %s\n",
+                   datapath_failure ? "BAD" : "HEALTHY");
+
+    unixctl_command_reply(conn, ds_cstr(&ds));
+}
+
 static int
 ka_init__(void)
 {
@@ -663,6 +784,9 @@ ka_init(const struct smap *ovs_other_config)
 
                 unixctl_command_register("keepalive/pmd-health-show", "", 0, 0,
                                       ka_unixctl_pmd_health_show, ka_shm);
+
+                unixctl_command_register("keepalive/pmd-xstats-show", "", 0, 0,
+                                      ka_unixctl_pmd_xstats_show, ka_shm);
             } else {
                 VLOG_ERR("keepalive_shm_create() failed.");
             }
-- 
2.4.11



More information about the dev mailing list