From: Florin Coras Date: Tue, 11 Sep 2018 07:10:41 +0000 (-0700) Subject: vcl: improve read and fifo event handling X-Git-Tag: v18.10-rc1~215 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=41c9e04be0ca3a081926045e78dc969dab563532 vcl: improve read and fifo event handling Change-Id: Ic1c51818b8aa8dbd164e70bb3b7471868e5af6f6 Signed-off-by: Florin Coras --- diff --git a/src/svm/message_queue.c b/src/svm/message_queue.c index d6a77e783e3..a73a56d8044 100644 --- a/src/svm/message_queue.c +++ b/src/svm/message_queue.c @@ -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); } diff --git a/src/svm/svm_fifo.h b/src/svm/svm_fifo.h index 40242614829..a8aea00996e 100644 --- a/src/svm/svm_fifo.h +++ b/src/svm/svm_fifo.h @@ -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); } diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt index ba19ced27a6..c86f40bb0f2 100644 --- a/src/vcl/CMakeLists.txt +++ b/src/vcl/CMakeLists.txt @@ -24,6 +24,9 @@ add_vpp_library(vppcom LINK_LIBRARIES vppinfra svm vlibmemoryclient rt pthread + + DEPENDS + api_headers ) add_vpp_library(vcl_ldpreload diff --git a/src/vcl/vcl_test_server.c b/src/vcl/vcl_test_server.c index 5c8656c9603..7c1bef62d6d 100644 --- a/src/vcl/vcl_test_server.c +++ b/src/vcl/vcl_test_server.c @@ -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); } diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 3acd1c41e70..6d6e7d08797 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -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 diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 549b3ac3c4a..9906a40fcc4 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -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 diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index b58e73eb4f8..7d0fd5567a3 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -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; } diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c index 6b012bb845d..1f094ef126b 100644 --- a/src/vnet/session/application_interface.c +++ b/src/vnet/session/application_interface.c @@ -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); } diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 05b3bb89f0c..b88438c267f 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -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;