session vcl: refactor builtin tx event for main tx

Rename unused SESSION_IO_EVT_BUILTIN_TX to SESSION_IO_EVT_TX_MAIN and
leverage it for non-connected udp tx.

Non-connected udp sessions are listeners and are therefore allocated on
main thread. Consequently, whenever session queue node is not polling
main, tx events generated by external applications might be missed or
processed with some delay. To solve this, request that apps use
SESSION_IO_EVT_TX_MAIN tx events as opposed to SESSION_IO_EVT_TX and
send that to first worker as opposed to main.

Type: fix

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I5df5ac3dc80c0f192b2eefb1d465e9deefe8786b
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index a3ae427..dabe52c 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -660,6 +660,12 @@
   s->attributes &= ~(1 << attr);
 }
 
+static inline session_evt_type_t
+vcl_session_dgram_tx_evt (vcl_session_t *s, session_evt_type_t et)
+{
+  return (s->flags & VCL_SESSION_F_CONNECTED) ? et : SESSION_IO_EVT_TX_MAIN;
+}
+
 /*
  * Helpers
  */
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 0ba9423..b170b39 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -2281,12 +2281,17 @@
     et = SESSION_IO_EVT_TX_FLUSH;
 
   if (is_dgram)
-    n_write =
-      app_send_dgram_raw_gso (tx_fifo, &s->transport, s->vpp_evt_q, buf, n,
-			      s->gso_size, et, 0 /* do_evt */, SVM_Q_WAIT);
+    {
+      et = vcl_session_dgram_tx_evt (s, et);
+      n_write =
+	app_send_dgram_raw_gso (tx_fifo, &s->transport, s->vpp_evt_q, buf, n,
+				s->gso_size, et, 0 /* do_evt */, SVM_Q_WAIT);
+    }
   else
-    n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
-				   0 /* do_evt */ , SVM_Q_WAIT);
+    {
+      n_write = app_send_stream_raw (tx_fifo, s->vpp_evt_q, buf, n, et,
+				     0 /* do_evt */, SVM_Q_WAIT);
+    }
 
   if (svm_fifo_set_event (s->tx_fifo))
     app_send_io_evt_to_vpp (
@@ -2682,7 +2687,7 @@
   u32 sh = vep_handle;
   vcl_session_t *s;
 
-  if (VPPCOM_DEBUG <= 2)
+  if (VPPCOM_DEBUG <= 3)
     return;
 
   s = vcl_session_get_w_handle (wrk, vep_handle);
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index fe05dd2..93bdf6c 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -59,7 +59,7 @@
       evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
       evt->session_index = *(u32 *) data;
       break;
-    case SESSION_IO_EVT_BUILTIN_TX:
+    case SESSION_IO_EVT_TX_MAIN:
     case SESSION_CTRL_EVT_CLOSE:
     case SESSION_CTRL_EVT_RESET:
       msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index ab92295..456718a 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -333,7 +333,7 @@
 static inline void
 session_evt_ctrl_data_free (session_worker_t * wrk, session_evt_elt_t * elt)
 {
-  ASSERT (elt->evt.event_type > SESSION_IO_EVT_BUILTIN_TX);
+  ASSERT (elt->evt.event_type >= SESSION_CTRL_EVT_RPC);
   pool_put_index (wrk->ctrl_evts_data, elt->evt.ctrl_data_index);
 }
 
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 2502ef6..3481cdf 100644
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -314,6 +314,8 @@
   if (session_transport_service_type (ls) == TRANSPORT_SERVICE_CL &&
       ls->rx_fifo)
     {
+      m.mq_index = transport_cl_thread ();
+      m.vpp_evt_q = fifo_segment_msg_q_offset (eq_seg, m.mq_index);
       m.rx_fifo = fifo_segment_fifo_offset (ls->rx_fifo);
       m.tx_fifo = fifo_segment_fifo_offset (ls->tx_fifo);
       m.segment_handle = session_segment_handle (ls);
diff --git a/src/vnet/session/session_debug.c b/src/vnet/session/session_debug.c
index dba4ef3..39d1752 100644
--- a/src/vnet/session/session_debug.c
+++ b/src/vnet/session/session_debug.c
@@ -280,7 +280,7 @@
     case SESSION_IO_EVT_RX:
     case SESSION_IO_EVT_TX:
     case SESSION_IO_EVT_BUILTIN_RX:
-    case SESSION_IO_EVT_BUILTIN_TX:
+    case SESSION_IO_EVT_TX_MAIN:
     case SESSION_IO_EVT_TX_FLUSH:
       if (e->session_index == f->shr->master_session_index)
 	return 1;
diff --git a/src/vnet/session/session_debug.h b/src/vnet/session/session_debug.h
index 614ffc9..45dd77c 100644
--- a/src/vnet/session/session_debug.h
+++ b/src/vnet/session/session_debug.h
@@ -70,28 +70,28 @@
 #undef _
 } session_evt_to_grp_e;
 
-#define foreach_session_events                         		\
-_(CLK_UPDATE_TIME, 1, 1, "Time Update Time") 			\
-_(CLK_MQ_DEQ, 1, 1, "Time MQ Dequeue") 	          		\
-_(CLK_CTRL_EVTS, 1, 1, "Time Ctrl Events")			\
-_(CLK_NEW_IO_EVTS, 1, 1, "Time New IO Events")			\
-_(CLK_OLD_IO_EVTS, 1, 1, "Time Old IO Events")			\
-_(CLK_TOTAL, 1, 1, "Time Total in Node")			\
-_(CLK_START, 1, 1, "Time Since Last Reset")			\
-								\
-_(CNT_MQ_EVTS, 1, 0, "# of MQ Events Processed" )     		\
-_(CNT_CTRL_EVTS, 1, 0, "# of Ctrl Events Processed" )		\
-_(CNT_NEW_EVTS, 1, 0, "# of New Events Processed" )    		\
-_(CNT_OLD_EVTS, 1, 0, "# of Old Events Processed" )    		\
-_(CNT_IO_EVTS, 1, 0, "# of Events Processed" )      		\
-_(CNT_NODE_CALL, 1, 0, "# of Node Calls")               	\
-								\
-_(BASE_OFFSET_IO_EVTS, 0, 0, "NULL")                  		\
-_(SESSION_IO_EVT_RX, 1, 0, "# of IO Event RX")          	\
-_(SESSION_IO_EVT_TX,  1, 0, "# of IO Event TX")                 \
-_(SESSION_IO_EVT_TX_FLUSH, 1, 0, "# of IO Event TX Flush")      \
-_(SESSION_IO_EVT_BUILTIN_RX, 1, 0, "# of IO Event BuiltIn RX")	\
-_(SESSION_IO_EVT_BUILTIN_TX, 1, 0, "# of IO Event BuiltIn TX")	\
+#define foreach_session_events                                                \
+  _ (CLK_UPDATE_TIME, 1, 1, "Time Update Time")                               \
+  _ (CLK_MQ_DEQ, 1, 1, "Time MQ Dequeue")                                     \
+  _ (CLK_CTRL_EVTS, 1, 1, "Time Ctrl Events")                                 \
+  _ (CLK_NEW_IO_EVTS, 1, 1, "Time New IO Events")                             \
+  _ (CLK_OLD_IO_EVTS, 1, 1, "Time Old IO Events")                             \
+  _ (CLK_TOTAL, 1, 1, "Time Total in Node")                                   \
+  _ (CLK_START, 1, 1, "Time Since Last Reset")                                \
+                                                                              \
+  _ (CNT_MQ_EVTS, 1, 0, "# of MQ Events Processed")                           \
+  _ (CNT_CTRL_EVTS, 1, 0, "# of Ctrl Events Processed")                       \
+  _ (CNT_NEW_EVTS, 1, 0, "# of New Events Processed")                         \
+  _ (CNT_OLD_EVTS, 1, 0, "# of Old Events Processed")                         \
+  _ (CNT_IO_EVTS, 1, 0, "# of Events Processed")                              \
+  _ (CNT_NODE_CALL, 1, 0, "# of Node Calls")                                  \
+                                                                              \
+  _ (BASE_OFFSET_IO_EVTS, 0, 0, "NULL")                                       \
+  _ (SESSION_IO_EVT_RX, 1, 0, "# of IO Event RX")                             \
+  _ (SESSION_IO_EVT_TX, 1, 0, "# of IO Event TX")                             \
+  _ (SESSION_IO_EVT_TX_FLUSH, 1, 0, "# of IO Event TX Flush")                 \
+  _ (SESSION_IO_EVT_BUILTIN_RX, 1, 0, "# of IO Event BuiltIn RX")             \
+  _ (SESSION_IO_EVT_TX_MAIN, 1, 0, "# of IO Event TX Main")
 
 typedef enum
 {
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index f1a0067..c61e89b 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -1776,11 +1776,13 @@
       app_wrk = app_worker_get (s->app_wrk_index);
       app_worker_builtin_rx (app_wrk, s);
       break;
-    case SESSION_IO_EVT_BUILTIN_TX:
-      s = session_get_from_handle_if_valid (e->session_handle);
+    case SESSION_IO_EVT_TX_MAIN:
+      s = session_get_if_valid (e->session_index, 0 /* main thread */);
+      if (PREDICT_FALSE (!s))
+	break;
       wrk->ctx.s = s;
       if (PREDICT_TRUE (s != 0))
-	session_tx_fifo_dequeue_internal (wrk, node, elt, n_tx_packets);
+	(smm->session_tx_fns[s->session_type]) (wrk, node, elt, n_tx_packets);
       break;
     default:
       clib_warning ("unhandled event type %d", e->event_type);
diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h
index 513929a..9ad40fc 100644
--- a/src/vnet/session/session_types.h
+++ b/src/vnet/session/session_types.h
@@ -348,7 +348,7 @@
   SESSION_IO_EVT_TX,
   SESSION_IO_EVT_TX_FLUSH,
   SESSION_IO_EVT_BUILTIN_RX,
-  SESSION_IO_EVT_BUILTIN_TX,
+  SESSION_IO_EVT_TX_MAIN,
   SESSION_CTRL_EVT_RPC,
   SESSION_CTRL_EVT_HALF_CLOSE,
   SESSION_CTRL_EVT_CLOSE,
@@ -413,7 +413,6 @@
 #define FIFO_EVENT_APP_TX SESSION_IO_EVT_TX
 #define FIFO_EVENT_DISCONNECT SESSION_CTRL_EVT_CLOSE
 #define FIFO_EVENT_BUILTIN_RX SESSION_IO_EVT_BUILTIN_RX
-#define FIFO_EVENT_BUILTIN_TX SESSION_IO_EVT_BUILTIN_TX
 
 typedef enum
 {