vcl: improve read and fifo event handling 64/14764/9
authorFlorin Coras <fcoras@cisco.com>
Tue, 11 Sep 2018 07:10:41 +0000 (00:10 -0700)
committerMarco Varlese <marco.varlese@suse.de>
Wed, 12 Sep 2018 09:13:16 +0000 (09:13 +0000)
Change-Id: Ic1c51818b8aa8dbd164e70bb3b7471868e5af6f6
Signed-off-by: Florin Coras <fcoras@cisco.com>
src/svm/message_queue.c
src/svm/svm_fifo.h
src/vcl/CMakeLists.txt
src/vcl/vcl_test_server.c
src/vcl/vppcom.c
src/vnet/CMakeLists.txt
src/vnet/session/application.c
src/vnet/session/application_interface.c
src/vnet/session/session_api.c

index d6a77e7..a73a56d 100644 (file)
@@ -173,8 +173,7 @@ svm_msg_q_free_msg (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
 {
   svm_msg_q_ring_t *ring;
 
-  if (vec_len (mq->rings) <= msg->ring_index)
-    return;
+  ASSERT (vec_len (mq->rings) > msg->ring_index);
   ring = &mq->rings[msg->ring_index];
   if (msg->elt_index == ring->head)
     {
@@ -182,6 +181,7 @@ svm_msg_q_free_msg (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
     }
   else
     {
+      clib_warning ("message out of order");
       /* for now, expect messages to be processed in order */
       ASSERT (0);
     }
index 4024261..a8aea00 100644 (file)
@@ -140,22 +140,26 @@ svm_fifo_has_ooo_data (svm_fifo_t * f)
 /**
  * Sets fifo event flag.
  *
+ * Also acts as a release barrier.
+ *
  * @return 1 if flag was not set.
  */
 always_inline u8
 svm_fifo_set_event (svm_fifo_t * f)
 {
-  /* Probably doesn't need to be atomic. Still, better avoid surprises */
-  return __sync_lock_test_and_set (&f->has_event, 1) == 0;
+//  return __sync_lock_test_and_set (&f->has_event, 1) == 0;
+//  return __sync_bool_compare_and_swap (&f->has_event, 0, 1);
+  return !__atomic_exchange_n (&f->has_event, 1, __ATOMIC_RELEASE);
 }
 
 /**
  * Unsets fifo event flag.
+ *
+ * Also acts as a release barrier.
  */
 always_inline void
 svm_fifo_unset_event (svm_fifo_t * f)
 {
-  /* Probably doesn't need to be atomic. Still, better avoid surprises */
   __sync_lock_release (&f->has_event);
 }
 
index ba19ced..c86f40b 100644 (file)
@@ -24,6 +24,9 @@ add_vpp_library(vppcom
 
   LINK_LIBRARIES
   vppinfra svm vlibmemoryclient rt pthread
+
+  DEPENDS
+  api_headers
 )
 
 add_vpp_library(vcl_ldpreload
index 5c8656c..7c1bef6 100644 (file)
@@ -575,8 +575,8 @@ vts_worker_loop (void *arg)
                    }
                  continue;
                }
-             else if ((conn->cfg.test == SOCK_TEST_TYPE_UNI)
-                      || (conn->cfg.test == SOCK_TEST_TYPE_BI))
+             if ((conn->cfg.test == SOCK_TEST_TYPE_UNI)
+                 || (conn->cfg.test == SOCK_TEST_TYPE_BI))
                {
                  vts_server_rx (conn, rx_bytes);
                  if (vppcom_session_attr (conn->fd, VPPCOM_ATTR_GET_NREAD, 0,
@@ -584,7 +584,7 @@ vts_worker_loop (void *arg)
                    goto read_again;
                  continue;
                }
-             else if (isascii (conn->buf[0]))
+             if (isascii (conn->buf[0]))
                {
                  vts_server_echo (conn, rx_bytes);
                }
index 3acd1c4..6d6e7d0 100644 (file)
@@ -1268,7 +1268,7 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
   svm_msg_q_msg_t msg;
   session_event_t *e;
   svm_msg_q_t *mq;
-  u8 is_full;
+  u8 is_ct;
 
   if (PREDICT_FALSE (!buf))
     return VPPCOM_EINVAL;
@@ -1299,18 +1299,19 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
       return rv;
     }
 
-  mq = vcl_session_is_ct (s) ? s->our_evt_q : wrk->app_event_queue;
-  svm_fifo_unset_event (rx_fifo);
-  is_full = svm_fifo_is_full (rx_fifo);
+  is_ct = vcl_session_is_ct (s);
+  mq = is_ct ? s->our_evt_q : wrk->app_event_queue;
 
   if (svm_fifo_is_empty (rx_fifo))
     {
       if (is_nonblocking)
        {
+         svm_fifo_unset_event (rx_fifo);
          return VPPCOM_OK;
        }
-      while (1)
+      while (svm_fifo_is_empty (rx_fifo))
        {
+         svm_fifo_unset_event (rx_fifo);
          svm_msg_q_lock (mq);
          if (svm_msg_q_is_empty (mq))
            svm_msg_q_wait (mq);
@@ -1318,20 +1319,16 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
          svm_msg_q_sub_w_lock (mq, &msg);
          e = svm_msg_q_msg_data (mq, &msg);
          svm_msg_q_unlock (mq);
-         if (!vcl_is_rx_evt_for_session (e, s->session_index,
-                                         s->our_evt_q != 0))
+         if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct))
            {
              vcl_handle_mq_ctrl_event (wrk, e);
              svm_msg_q_free_msg (mq, &msg);
              continue;
            }
-         svm_fifo_unset_event (rx_fifo);
          svm_msg_q_free_msg (mq, &msg);
+
          if (PREDICT_FALSE (s->session_state == STATE_CLOSE_ON_EMPTY))
            return 0;
-         if (svm_fifo_is_empty (rx_fifo))
-           continue;
-         break;
        }
     }
 
@@ -1340,7 +1337,10 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n,
   else
     n_read = app_recv_stream_raw (rx_fifo, buf, n, 0, peek);
 
-  if (vcl_session_is_ct (s) && is_full)
+  if (svm_fifo_is_empty (rx_fifo))
+    svm_fifo_unset_event (rx_fifo);
+
+  if (is_ct && n_read + svm_fifo_max_dequeue (rx_fifo) == rx_fifo->nitems)
     {
       /* If the peer is not polling send notification */
       if (!svm_fifo_has_event (s->rx_fifo))
@@ -1593,7 +1593,7 @@ if (PREDICT_FALSE (svm_fifo_is_empty (_fifo)))                    \
   {                                                            \
     svm_fifo_unset_event (_fifo);                              \
     if (svm_fifo_is_empty (_fifo))                             \
-       break;                                                  \
+      break;                                                   \
   }                                                            \
 
 static int
index 549b3ac..9906a40 100644 (file)
@@ -1341,6 +1341,10 @@ list(APPEND VNET_HEADERS
 
 list(APPEND VNET_API_FILES bier/bier.api)
 
+##############################################################################
+# VNET Library
+##############################################################################
+
 add_vpp_library(vnet
   SOURCES ${VNET_SOURCES}
   MULTIARCH_SOURCES ${VNET_MULTIARCH_SOURCES}
@@ -1349,3 +1353,25 @@ add_vpp_library(vnet
   LINK_LIBRARIES vppinfra svm vlib ${OPENSSL_LIBRARIES}
   DEPENDS api_headers
 )
+
+##############################################################################
+# Session echo apps
+##############################################################################
+
+option(VPP_BUILD_SESSION_ECHO_APPS "Build session echo apps." ON)
+if(VPP_BUILD_SESSION_ECHO_APPS)
+  add_vpp_executable(tcp_echo
+    SOURCES ../tests/vnet/session/tcp_echo.c
+    LINK_LIBRARIES vlibmemoryclient svm vppinfra pthread m rt
+    DEPENDS api_headers
+    NO_INSTALL
+    )
+  add_vpp_executable(udp_echo
+    SOURCES ../tests/vnet/session/udp_echo.c
+    LINK_LIBRARIES vlibmemoryclient svm vppinfra pthread m rt
+    DEPENDS api_headers
+    NO_INSTALL
+    )
+endif(VPP_BUILD_SESSION_ECHO_APPS)
+
+##############################################################################
\ No newline at end of file
index b58e73e..7d0fd55 100644 (file)
@@ -1267,9 +1267,10 @@ app_send_io_evt_rx (app_worker_t * app_wrk, stream_session_t * s, u8 lock)
   evt->fifo = s->server_rx_fifo;
   evt->event_type = FIFO_EVENT_APP_RX;
 
+  (void) svm_fifo_set_event (s->server_rx_fifo);
+
   if (app_enqueue_evt (mq, &msg, lock))
     return -1;
-  (void) svm_fifo_set_event (s->server_rx_fifo);
   return 0;
 }
 
index 6b012bb..1f094ef 100644 (file)
@@ -546,6 +546,7 @@ vnet_bind_uri (vnet_bind_args_t * a)
   rv = parse_uri (a->uri, &sep);
   if (rv)
     return rv;
+  sep.app_wrk_index = 0;
   clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
   return vnet_bind_inline (a);
 }
index 05b3bb8..b88438c 100755 (executable)
@@ -964,6 +964,7 @@ vl_api_connect_uri_t_handler (vl_api_connect_uri_t * mp)
   app = application_lookup (mp->client_index);
   if (app)
     {
+      memset (a, 0, sizeof (*a));
       a->uri = (char *) mp->uri;
       a->api_context = mp->context;
       a->app_index = app->app_index;