session: Add mq debug cli

Type: feature

This add a `show app message queue` cli command
that shows mq size per app & thread.

Change-Id: I5c6ce024b149fb7a47d899bc514c5a4887429982
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
diff --git a/src/svm/message_queue.c b/src/svm/message_queue.c
index 6113450..10266a8 100644
--- a/src/svm/message_queue.c
+++ b/src/svm/message_queue.c
@@ -15,6 +15,7 @@
 
 #include <svm/message_queue.h>
 #include <vppinfra/mem.h>
+#include <vppinfra/format.h>
 #include <sys/eventfd.h>
 
 static inline svm_msg_q_ring_t *
@@ -265,6 +266,19 @@
   return 0;
 }
 
+u8 *
+format_svm_msg_q (u8 * s, va_list * args)
+{
+  svm_msg_q_t *mq = va_arg (*args, svm_msg_q_t *);
+  s = format (s, " [Q:%d/%d]", mq->q->cursize, mq->q->maxsize);
+  for (u32 i = 0; i < vec_len (mq->rings); i++)
+    {
+      s = format (s, " [R%d:%d/%d]", i, mq->rings[i].cursize,
+		  mq->rings[i].nitems);
+    }
+  return s;
+}
+
 /*
  * fd.io coding-style-patch-verification: ON
  *
diff --git a/src/svm/message_queue.h b/src/svm/message_queue.h
index 7226560..37293fc 100644
--- a/src/svm/message_queue.h
+++ b/src/svm/message_queue.h
@@ -247,6 +247,12 @@
  */
 int svm_msg_q_alloc_producer_eventfd (svm_msg_q_t * mq);
 
+
+/**
+ * Format message queue, shows msg count for each ring
+ */
+u8 *format_svm_msg_q (u8 * s, va_list * args);
+
 /**
  * Check if message queue is full
  */
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c
index 42c5136..8d8e17c 100644
--- a/src/vnet/session/application.c
+++ b/src/vnet/session/application.c
@@ -1379,9 +1379,8 @@
   if (ckpair->cert_key_index == 0)
     s = format (s, "DEFAULT (cert:%d, key:%d)", cert_len, key_len);
   else
-    s =
-      format (s, "%d (cert:%d, key:%d)", ckpair->cert_key_index, cert_len,
-	      key_len);
+    s = format (s, "%d (cert:%d, key:%d)", ckpair->cert_key_index,
+		cert_len, key_len);
   return s;
 }
 
@@ -1428,9 +1427,8 @@
 format_crypto_context (u8 * s, va_list * args)
 {
   crypto_context_t *crctx = va_arg (*args, crypto_context_t *);
-  s =
-    format (s, "[0x%x][sub%d,ckpair%x]", crctx->ctx_index,
-	    crctx->n_subscribers, crctx->ckpair_index);
+  s = format (s, "[0x%x][sub%d,ckpair%x]", crctx->ctx_index,
+	      crctx->n_subscribers, crctx->ckpair_index);
   s = format (s, "[%U]", format_crypto_engine, crctx->crypto_engine);
   return s;
 }
@@ -1534,11 +1532,48 @@
   return 0;
 }
 
+static inline void
+appliction_format_app_mq (vlib_main_t * vm, application_t * app)
+{
+  app_worker_map_t *map;
+  app_worker_t *wrk;
+  /* *INDENT-OFF* */
+  pool_foreach (map, app->worker_maps, ({
+    wrk = app_worker_get (map->wrk_index);
+    vlib_cli_output (vm, "[A%d][%d]%U", app->app_index,
+		     map->wrk_index, format_svm_msg_q,
+		     wrk->event_queue);
+  }));
+  /* *INDENT-ON* */
+}
+
+static clib_error_t *
+appliction_format_all_app_mq (vlib_main_t * vm)
+{
+  application_t *app;
+  int i, n_threads;
+
+  n_threads = vec_len (vlib_mains);
+
+  for (i = 0; i < n_threads; i++)
+    {
+      vlib_cli_output (vm, "[Ctrl%d]%U", i, format_svm_msg_q,
+		       session_main_get_vpp_event_queue (i));
+    }
+
+  /* *INDENT-OFF* */
+  pool_foreach (app, app_main.app_pool, ({
+      appliction_format_app_mq (vm, app);
+  }));
+  /* *INDENT-ON* */
+  return 0;
+}
+
 static clib_error_t *
 show_app_command_fn (vlib_main_t * vm, unformat_input_t * input,
 		     vlib_cli_command_t * cmd)
 {
-  int do_server = 0, do_client = 0;
+  int do_server = 0, do_client = 0, do_mq = 0;
   application_t *app;
   u32 app_index = ~0;
   int verbose = 0;
@@ -1551,6 +1586,8 @@
 	do_server = 1;
       else if (unformat (input, "client"))
 	do_client = 1;
+      else if (unformat (input, "mq"))
+	do_mq = 1;
       else if (unformat (input, "%u", &app_index))
 	;
       else if (unformat (input, "verbose"))
@@ -1560,6 +1597,22 @@
 				  format_unformat_error, input);
     }
 
+  if (do_mq && app_index != ~0)
+    {
+      app = application_get_if_valid (app_index);
+      if (!app)
+	return clib_error_return (0, "No app with index %u", app_index);
+
+      appliction_format_app_mq (vm, app);
+      return 0;
+    }
+
+  if (do_mq)
+    {
+      appliction_format_all_app_mq (vm);
+      return 0;
+    }
+
   if (do_server)
     {
       application_format_all_listeners (vm, verbose);
@@ -1688,7 +1741,7 @@
 VLIB_CLI_COMMAND (show_app_command, static) =
 {
   .path = "show app",
-  .short_help = "show app [server|client] [verbose]",
+  .short_help = "show app [app_id] [server|client] [mq] [verbose]",
   .function = show_app_command_fn,
 };