[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