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.bodire...@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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev