session vcl: refactor builtin tx event for main tx
[vpp.git] / src / vnet / session / session.c
index a56ff9f..93bdf6c 100644 (file)
@@ -59,7 +59,7 @@ session_send_evt_to_thread (void *data, void *args, u32 thread_index,
       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);
@@ -334,15 +334,15 @@ void
 session_half_open_delete_notify (transport_connection_t *tc)
 {
   /* Notification from ctrl thread accepted without rpc */
-  if (!tc->thread_index)
+  if (tc->thread_index == transport_cl_thread ())
     {
       session_half_open_free (ho_session_get (tc->s_index));
     }
   else
     {
       void *args = uword_to_pointer ((uword) tc->s_index, void *);
-      session_send_rpc_evt_to_thread_force (0, session_half_open_free_rpc,
-                                           args);
+      session_send_rpc_evt_to_thread_force (transport_cl_thread (),
+                                           session_half_open_free_rpc, args);
     }
 }
 
@@ -728,8 +728,10 @@ session_enqueue_notify_inline (session_t * s)
   app_worker_t *app_wrk;
   u32 session_index;
   u8 n_subscribers;
+  u32 thread_index;
 
   session_index = s->session_index;
+  thread_index = s->thread_index;
   n_subscribers = svm_fifo_n_subscribers (s->rx_fifo);
 
   app_wrk = app_worker_get_if_valid (s->app_wrk_index);
@@ -753,7 +755,7 @@ session_enqueue_notify_inline (session_t * s)
 
   if (PREDICT_FALSE (n_subscribers))
     {
-      s = session_get (session_index, vlib_get_thread_index ());
+      s = session_get (session_index, thread_index);
       return session_notify_subscribers (app_wrk->app_index, s,
                                         s->rx_fifo, SESSION_IO_EVT_RX);
     }
@@ -1526,9 +1528,15 @@ session_half_close (session_t *s)
 void
 session_close (session_t * s)
 {
-  if (!s)
+  if (!s || (s->flags & SESSION_F_APP_CLOSED))
     return;
 
+  /* Transports can close and delete their state independent of app closes
+   * and transport initiated state transitions can hide app closes. Instead
+   * of extending the state machine to support separate tracking of app and
+   * transport initiated closes, use a flag. */
+  s->flags |= SESSION_F_APP_CLOSED;
+
   if (s->session_state >= SESSION_STATE_CLOSING)
     {
       /* Session will only be removed once both app and transport
@@ -1539,8 +1547,11 @@ session_close (session_t * s)
       return;
     }
 
-  /* App closed so stop propagating dequeue notifications */
-  svm_fifo_clear_deq_ntf (s->tx_fifo);
+  /* App closed so stop propagating dequeue notifications.
+   * App might disconnect session before connected, in this case,
+   * tx_fifo may not be setup yet, so clear only it's inited. */
+  if (s->tx_fifo)
+    svm_fifo_clear_deq_ntf (s->tx_fifo);
   session_set_state (s, SESSION_STATE_CLOSING);
   session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_CLOSE);
 }
@@ -1553,8 +1564,11 @@ session_reset (session_t * s)
 {
   if (s->session_state >= SESSION_STATE_CLOSING)
     return;
-  /* Drop all outstanding tx data */
-  svm_fifo_dequeue_drop_all (s->tx_fifo);
+  /* Drop all outstanding tx data
+   * App might disconnect session before connected, in this case,
+   * tx_fifo may not be setup yet, so clear only it's inited. */
+  if (s->tx_fifo)
+    svm_fifo_dequeue_drop_all (s->tx_fifo);
   session_set_state (s, SESSION_STATE_CLOSING);
   session_program_transport_ctrl_evt (s, SESSION_CTRL_EVT_RESET);
 }
@@ -2009,6 +2023,7 @@ session_dma_completion_cb (vlib_main_t *vm, struct vlib_dma_batch *batch)
 static void
 session_prepare_dma_args (vlib_dma_config_t *args)
 {
+  args->max_batches = 16;
   args->max_transfers = DMA_TRANS_SIZE;
   args->max_transfer_size = 65536;
   args->features = 0;