svm: allow mq attachments at random offsets
[vpp.git] / src / plugins / hs_apps / sapi / vpp_echo_bapi.c
index c643cec..6ad825d 100644 (file)
@@ -264,12 +264,12 @@ echo_segment_detach (u64 segment_handle)
 
 int
 echo_attach_session (uword segment_handle, uword rxf_offset, uword txf_offset,
-                    echo_session_t *s)
+                    uword mq_offset, echo_session_t *s)
 {
   svm_fifo_shared_t *rx_fifo, *tx_fifo;
   echo_main_t *em = &echo_main;
+  u32 fs_index, eqs_index;
   fifo_segment_t *fs;
-  u32 fs_index;
 
   fs_index = echo_segment_lookup (segment_handle);
   if (fs_index == (u32) ~0)
@@ -279,6 +279,12 @@ echo_attach_session (uword segment_handle, uword rxf_offset, uword txf_offset,
       return -1;
     }
 
+  if (mq_offset != (uword) ~0)
+    {
+      eqs_index = echo_segment_lookup (ECHO_MQ_SEG_HANDLE);
+      ASSERT (eqs_index != (u32) ~0);
+    }
+
   rx_fifo = uword_to_pointer (rxf_offset, svm_fifo_shared_t *);
   tx_fifo = uword_to_pointer (txf_offset, svm_fifo_shared_t *);
   rx_fifo->client_session_index = s->session_index;
@@ -290,6 +296,39 @@ echo_attach_session (uword segment_handle, uword rxf_offset, uword txf_offset,
   s->rx_fifo = fifo_segment_alloc_fifo_w_shared (fs, rx_fifo);
   s->tx_fifo = fifo_segment_alloc_fifo_w_shared (fs, tx_fifo);
 
+  if (mq_offset != (uword) ~0)
+    {
+      fs = fifo_segment_get_segment (&em->segment_main, eqs_index);
+      s->vpp_evt_q =
+       fifo_segment_msg_q_attach (fs, mq_offset, rx_fifo->slice_index);
+    }
+
+  clib_spinlock_unlock (&em->segment_handles_lock);
+
+  return 0;
+}
+
+int
+echo_segment_attach_mq (uword segment_handle, uword mq_offset, u32 mq_index,
+                       svm_msg_q_t **mq)
+{
+  echo_main_t *em = &echo_main;
+  fifo_segment_t *fs;
+  u32 fs_index;
+
+  fs_index = echo_segment_lookup (segment_handle);
+  if (fs_index == (u32) ~0)
+    {
+      ECHO_LOG (0, "ERROR: mq segment %lx for is not attached!",
+               segment_handle);
+      return -1;
+    }
+
+  clib_spinlock_lock (&em->segment_handles_lock);
+
+  fs = fifo_segment_get_segment (&em->segment_main, fs_index);
+  *mq = fifo_segment_msg_q_attach (fs, mq_offset, mq_index);
+
   clib_spinlock_unlock (&em->segment_handles_lock);
 
   return 0;
@@ -338,8 +377,6 @@ static void
   em->state = STATE_CLEANED_CERT_KEY;
 }
 
-#define ECHO_MQ_SEG_HANDLE ((u64) ~0 - 1)
-
 static void
 vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
 {
@@ -364,8 +401,6 @@ vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
       ECHO_FAIL (ECHO_FAIL_VL_API_NULL_APP_MQ, "NULL app_mq");
       return;
     }
-  em->app_mq = uword_to_pointer (mp->app_mq, svm_msg_q_t *);
-  em->ctrl_mq = uword_to_pointer (mp->vpp_ctrl_mq, svm_msg_q_t *);
 
   if (mp->n_fds)
     {
@@ -385,6 +420,8 @@ vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
                       "svm_fifo_segment_attach failed on SSVM_SEGMENT_MEMFD");
            goto failed;
          }
+      echo_segment_attach_mq (ECHO_MQ_SEG_HANDLE, mp->vpp_ctrl_mq,
+                             mp->vpp_ctrl_mq_thread, &em->ctrl_mq);
 
       if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
        {
@@ -401,6 +438,7 @@ vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
            }
          vec_free (segment_name);
        }
+      echo_segment_attach_mq (segment_handle, mp->app_mq, 0, &em->app_mq);
 
       if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
        svm_msg_q_set_consumer_eventfd (em->app_mq, fds[n_fds++]);