aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2018-09-11 00:10:41 -0700
committerMarco Varlese <marco.varlese@suse.de>2018-09-12 09:13:16 +0000
commit41c9e04be0ca3a081926045e78dc969dab563532 (patch)
tree2b0e666792415ebd8fc3fed5847652321231e4a8
parentffb14b9554afa1e58c3657e0c91dda3135008274 (diff)
vcl: improve read and fifo event handling
Change-Id: Ic1c51818b8aa8dbd164e70bb3b7471868e5af6f6 Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/svm/message_queue.c4
-rw-r--r--src/svm/svm_fifo.h10
-rw-r--r--src/vcl/CMakeLists.txt3
-rw-r--r--src/vcl/vcl_test_server.c6
-rw-r--r--src/vcl/vppcom.c26
-rw-r--r--src/vnet/CMakeLists.txt26
-rw-r--r--src/vnet/session/application.c3
-rw-r--r--src/vnet/session/application_interface.c1
-rwxr-xr-xsrc/vnet/session/session_api.c1
9 files changed, 58 insertions, 22 deletions
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;