svm: split fifo into private and shared structs

Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: Id8e77e8b2623be719fd43a95e181eaa5b7df2b6e
diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c
index c5dcd39..ea93811 100644
--- a/src/vcl/vcl_private.c
+++ b/src/vcl/vcl_private.c
@@ -374,6 +374,51 @@
   VDBG (0, "detached segment %u handle %u", segment_index, segment_handle);
 }
 
+int
+vcl_segment_attach_session (uword segment_handle, uword rxf_offset,
+			    uword txf_offset, u8 is_ct, vcl_session_t *s)
+{
+  svm_fifo_shared_t *rxsf, *txsf;
+  svm_fifo_t *rxf, *txf;
+  fifo_segment_t *fs;
+  u32 fs_index;
+
+  fs_index = vcl_segment_table_lookup (segment_handle);
+  if (fs_index == VCL_INVALID_SEGMENT_INDEX)
+    {
+      VDBG (0, "ERROR: segment for session %u is not mounted!",
+	    s->session_index);
+      return -1;
+    }
+
+  rxsf = uword_to_pointer (rxf_offset, svm_fifo_shared_t *);
+  txsf = uword_to_pointer (txf_offset, svm_fifo_shared_t *);
+
+  clib_rwlock_reader_lock (&vcm->segment_table_lock);
+
+  fs = fifo_segment_get_segment (&vcm->segment_main, fs_index);
+  rxf = fifo_segment_alloc_fifo_w_shared (fs, rxsf);
+  txf = fifo_segment_alloc_fifo_w_shared (fs, txsf);
+
+  clib_rwlock_reader_unlock (&vcm->segment_table_lock);
+
+  if (!is_ct)
+    {
+      rxsf->client_session_index = s->session_index;
+      txsf->client_session_index = s->session_index;
+      rxf->client_thread_index = vcl_get_worker_index ();
+      txf->client_thread_index = vcl_get_worker_index ();
+      s->rx_fifo = rxf;
+      s->tx_fifo = txf;
+    }
+  else
+    {
+      s->ct_rx_fifo = rxf;
+      s->ct_tx_fifo = txf;
+    }
+
+  return 0;
+}
 
 /*
  * fd.io coding-style-patch-verification: ON
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index 0d26e64..637581b 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -685,6 +685,9 @@
 void vcl_segment_detach (u64 segment_handle);
 void vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s);
 
+int vcl_segment_attach_session (uword segment_handle, uword rxf_offset,
+				uword txf_offset, u8 is_ct, vcl_session_t *s);
+
 /*
  * VCL Binary API
  */
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 58c13c2..734d062 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -22,21 +22,6 @@
 
 __thread uword __vcl_worker_index = ~0;
 
-static int
-vcl_segment_is_not_mounted (vcl_worker_t * wrk, u64 segment_handle)
-{
-  u32 segment_index;
-
-  if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
-    return 0;
-
-  segment_index = vcl_segment_table_lookup (segment_handle);
-  if (segment_index != VCL_INVALID_SEGMENT_INDEX)
-    return 0;
-
-  return 1;
-}
-
 static inline int
 vcl_mq_dequeue_batch (vcl_worker_t * wrk, svm_msg_q_t * mq, u32 n_max_msg)
 {
@@ -377,7 +362,6 @@
 			      u32 ls_index)
 {
   vcl_session_t *session, *listen_session;
-  svm_fifo_t *rx_fifo, *tx_fifo;
   svm_msg_q_t *evt_q;
 
   session = vcl_session_alloc (wrk);
@@ -390,26 +374,17 @@
       goto error;
     }
 
-  if (vcl_segment_is_not_mounted (wrk, mp->segment_handle))
+  session->vpp_evt_q =
+    uword_to_pointer (mp->vpp_event_queue_address, svm_msg_q_t *);
+
+  if (vcl_segment_attach_session (mp->segment_handle, mp->server_rx_fifo,
+				  mp->server_tx_fifo, 0, session))
     {
-      VDBG (0, "ERROR: segment for session %u is not mounted!",
-	    session->session_index);
+      VDBG (0, "failed to attach fifos for %u", session->session_index);
       goto error;
     }
 
-  rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
-  tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
-  session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
-					 svm_msg_q_t *);
-  rx_fifo->client_session_index = session->session_index;
-  tx_fifo->client_session_index = session->session_index;
-  rx_fifo->client_thread_index = vcl_get_worker_index ();
-  tx_fifo->client_thread_index = vcl_get_worker_index ();
-
   session->vpp_handle = mp->handle;
-  session->rx_fifo = rx_fifo;
-  session->tx_fifo = tx_fifo;
-
   session->session_state = VCL_STATE_READY;
   session->transport.rmt_port = mp->rmt.port;
   session->transport.is_ip4 = mp->rmt.is_ip4;
@@ -448,7 +423,6 @@
 vcl_session_connected_handler (vcl_worker_t * wrk,
 			       session_connected_msg_t * mp)
 {
-  svm_fifo_t *rx_fifo, *tx_fifo;
   vcl_session_t *session = 0;
   u32 session_index;
 
@@ -472,38 +446,28 @@
   session->vpp_handle = mp->handle;
   session->vpp_evt_q = uword_to_pointer (mp->vpp_event_queue_address,
 					 svm_msg_q_t *);
-  rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *);
-  tx_fifo = uword_to_pointer (mp->server_tx_fifo, svm_fifo_t *);
-  if (vcl_segment_is_not_mounted (wrk, mp->segment_handle))
+
+  if (vcl_segment_attach_session (mp->segment_handle, mp->server_rx_fifo,
+				  mp->server_tx_fifo, 0, session))
     {
-      VDBG (0, "segment for session %u is not mounted!",
-	    session->session_index);
+      VDBG (0, "failed to attach fifos for %u", session->session_index);
       session->session_state = VCL_STATE_DETACHED;
       vcl_send_session_disconnect (wrk, session);
       return session_index;
     }
 
-  rx_fifo->client_session_index = session_index;
-  tx_fifo->client_session_index = session_index;
-  rx_fifo->client_thread_index = vcl_get_worker_index ();
-  tx_fifo->client_thread_index = vcl_get_worker_index ();
-
   if (mp->ct_rx_fifo)
     {
-      session->ct_rx_fifo = uword_to_pointer (mp->ct_rx_fifo, svm_fifo_t *);
-      session->ct_tx_fifo = uword_to_pointer (mp->ct_tx_fifo, svm_fifo_t *);
-      if (vcl_segment_is_not_mounted (wrk, mp->ct_segment_handle))
+      if (vcl_segment_attach_session (mp->ct_segment_handle, mp->ct_rx_fifo,
+				      mp->ct_tx_fifo, 1, session))
 	{
-	  VDBG (0, "ct segment for session %u is not mounted!",
-		session->session_index);
+	  VDBG (0, "failed to attach ct fifos for %u", session->session_index);
 	  session->session_state = VCL_STATE_DETACHED;
 	  vcl_send_session_disconnect (wrk, session);
 	  return session_index;
 	}
     }
 
-  session->rx_fifo = rx_fifo;
-  session->tx_fifo = tx_fifo;
   session->transport.is_ip4 = mp->lcl.is_ip4;
   clib_memcpy_fast (&session->transport.lcl_ip, &mp->lcl.ip,
 		    sizeof (session->transport.lcl_ip));
@@ -611,14 +575,13 @@
 
   if (vcl_session_is_cl (session))
     {
-      svm_fifo_t *rx_fifo, *tx_fifo;
-      session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
-      rx_fifo = uword_to_pointer (mp->rx_fifo, svm_fifo_t *);
-      rx_fifo->client_session_index = sid;
-      tx_fifo = uword_to_pointer (mp->tx_fifo, svm_fifo_t *);
-      tx_fifo->client_session_index = sid;
-      session->rx_fifo = rx_fifo;
-      session->tx_fifo = tx_fifo;
+      if (vcl_segment_attach_session (mp->segment_handle, mp->rx_fifo,
+				      mp->tx_fifo, 0, session))
+	{
+	  VDBG (0, "failed to attach fifos for %u", session->session_index);
+	  session->session_state = VCL_STATE_DETACHED;
+	  return VCL_INVALID_SESSION_INDEX;
+	}
     }
 
   VDBG (0, "session %u [0x%llx]: listen succeeded!", sid, mp->handle);
@@ -664,6 +627,7 @@
 {
   session_migrated_msg_t *mp = (session_migrated_msg_t *) data;
   vcl_session_t *s;
+  u32 fs_index;
 
   s = vcl_session_get_w_vpp_handle (wrk, mp->handle);
   if (!s)
@@ -672,6 +636,14 @@
       return;
     }
 
+  fs_index = vcl_segment_table_lookup (mp->segment_handle);
+  if (fs_index == VCL_INVALID_SEGMENT_INDEX)
+    {
+      VDBG (0, "segment for session %u is not mounted!", s->session_index);
+      s->session_state = VCL_STATE_DETACHED;
+      return;
+    }
+
   s->vpp_handle = mp->new_handle;
   s->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
 
@@ -680,7 +652,8 @@
 
   /* Generate new tx event if we have outstanding data */
   if (svm_fifo_has_event (s->tx_fifo))
-    app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index,
+    app_send_io_evt_to_vpp (s->vpp_evt_q,
+			    s->tx_fifo->shr->master_session_index,
 			    SESSION_IO_EVT_TX, SVM_Q_WAIT);
 
   VDBG (0, "Migrated 0x%lx to thread %u 0x%lx", mp->handle,
@@ -879,21 +852,15 @@
       VDBG (0, "unknown handle 0x%llx", msg->handle);
       return;
     }
-  if (vcl_segment_is_not_mounted (wrk, msg->segment_handle))
-    {
-      clib_warning ("segment for session %u is not mounted!",
-		    s->session_index);
-      return;
-    }
 
   if (s->rx_fifo)
     {
-      s->rx_fifo = uword_to_pointer (msg->rx_fifo, svm_fifo_t *);
-      s->tx_fifo = uword_to_pointer (msg->tx_fifo, svm_fifo_t *);
-      s->rx_fifo->client_session_index = s->session_index;
-      s->tx_fifo->client_session_index = s->session_index;
-      s->rx_fifo->client_thread_index = wrk->wrk_index;
-      s->tx_fifo->client_thread_index = wrk->wrk_index;
+      if (vcl_segment_attach_session (msg->segment_handle, msg->rx_fifo,
+				      msg->tx_fifo, 0, s))
+	{
+	  VDBG (0, "failed to attach fifos for %u", s->session_index);
+	  return;
+	}
     }
   s->session_state = VCL_STATE_UPDATED;
 
@@ -1921,7 +1888,8 @@
   if (PREDICT_FALSE (svm_fifo_needs_deq_ntf (rx_fifo, n_read)))
     {
       svm_fifo_clear_deq_ntf (rx_fifo);
-      app_send_io_evt_to_vpp (s->vpp_evt_q, s->rx_fifo->master_session_index,
+      app_send_io_evt_to_vpp (s->vpp_evt_q,
+			      s->rx_fifo->shr->master_session_index,
 			      SESSION_IO_EVT_RX, SVM_Q_WAIT);
     }
 
@@ -2132,8 +2100,8 @@
 				   0 /* do_evt */ , SVM_Q_WAIT);
 
   if (svm_fifo_set_event (s->tx_fifo))
-    app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index,
-			    et, SVM_Q_WAIT);
+    app_send_io_evt_to_vpp (
+      s->vpp_evt_q, s->tx_fifo->shr->master_session_index, et, SVM_Q_WAIT);
 
   /* The underlying fifo segment can run out of memory */
   if (PREDICT_FALSE (n_write < 0))