summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-01-23 09:21:30 -0800
committerDave Barach <openvpp@barachs.net>2019-01-24 21:23:42 +0000
commit5f45e01f5c3ce239eccd9546e2d04fa3141ca5cb (patch)
treee0dbd1254a4e7c325dca5f2738845a9b1aaedcc4
parent8704097b9bd1e2ca717116fa1e7d61b4736c3fbd (diff)
session/vcl: support worker ownership change for listeners
Change-Id: I2ad54b20b96f10b009c3e651b2a2f885577ca5b6 Signed-off-by: Florin Coras <fcoras@cisco.com>
-rw-r--r--src/vcl/vppcom.c21
-rw-r--r--src/vnet/session/application.c29
-rw-r--r--src/vnet/session/session.h7
-rwxr-xr-xsrc/vnet/session/session_api.c5
-rw-r--r--src/vnet/session/session_node.c4
5 files changed, 54 insertions, 12 deletions
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index c91d0f4b8b6..d9012cdaed6 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -30,7 +30,7 @@ vcl_wait_for_segment (u64 segment_handle)
f64 timeout;
if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
- return 1;
+ return 0;
timeout = clib_time_now (&wrk->clib_time) + wait_for_seconds;
while (clib_time_now (&wrk->clib_time) < timeout)
@@ -505,6 +505,10 @@ vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp)
vcl_session_table_add_listener (wrk, mp->handle, sid);
session->session_state = STATE_LISTEN;
+ session->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *);
+ vec_validate (wrk->vpp_event_queues, 0);
+ wrk->vpp_event_queues[0] = session->vpp_evt_q;
+
if (session->is_dgram)
{
svm_fifo_t *rx_fifo, *tx_fifo;
@@ -607,13 +611,16 @@ vcl_session_worker_update_reply_handler (vcl_worker_t * wrk, void *data)
s->session_index);
return;
}
- 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 (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;
+ }
s->session_state = STATE_UPDATED;
VDBG (0, "session %u[0x%llx] moved to worker %u", s->session_index,
diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c
index 85b5f939427..044ab293c7e 100644
--- a/src/vnet/session/application.c
+++ b/src/vnet/session/application.c
@@ -730,6 +730,35 @@ app_worker_own_session (app_worker_t * app_wrk, stream_session_t * s)
segment_manager_t *sm;
svm_fifo_t *rxf, *txf;
+ if (s->session_state == SESSION_STATE_LISTENING)
+ {
+ app_worker_t *old_wrk = app_worker_get (s->app_wrk_index);
+ u64 lsh = listen_session_get_handle (s);
+ app_listener_t *app_listener;
+ application_t *app;
+
+ if (!old_wrk)
+ return -1;
+
+ hash_unset (old_wrk->listeners_table, lsh);
+ if (!(sm = app_worker_alloc_segment_manager (app_wrk)))
+ return -1;
+
+ hash_set (app_wrk->listeners_table, lsh, segment_manager_index (sm));
+ s->app_wrk_index = app_wrk->wrk_index;
+
+ app = application_get (old_wrk->app_index);
+ if (!app)
+ return -1;
+
+ app_listener = app_listener_get (app, s->listener_db_index);
+ app_listener->workers = clib_bitmap_set (app_listener->workers,
+ app_wrk->wrk_map_index, 1);
+ app_listener->workers = clib_bitmap_set (app_listener->workers,
+ old_wrk->wrk_map_index, 0);
+ return 0;
+ }
+
s->app_wrk_index = app_wrk->wrk_index;
rxf = s->server_rx_fifo;
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 2bbc380282c..babb002e07e 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -445,7 +445,12 @@ session_type_from_proto_and_ip (transport_proto_t proto, u8 is_ip4)
always_inline u64
session_segment_handle (stream_session_t * s)
{
- svm_fifo_t *f = s->server_rx_fifo;
+ svm_fifo_t *f;
+
+ if (s->session_state == SESSION_STATE_LISTENING)
+ return SESSION_INVALID_HANDLE;
+
+ f = s->server_rx_fifo;
return segment_manager_make_segment_handle (f->segment_manager,
f->segment_index);
}
diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c
index 2decd9b8a2e..51b8ba91e42 100755
--- a/src/vnet/session/session_api.c
+++ b/src/vnet/session/session_api.c
@@ -719,12 +719,13 @@ mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context,
mp->lcl_is_ip4 = session_type_is_ip4 (local->session_type);
}
+ vpp_evt_q = session_manager_get_vpp_event_queue (0);
+ mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
+
if (ls && session_transport_service_type (ls) == TRANSPORT_SERVICE_CL)
{
mp->rx_fifo = pointer_to_uword (ls->server_rx_fifo);
mp->tx_fifo = pointer_to_uword (ls->server_tx_fifo);
- vpp_evt_q = session_manager_get_vpp_event_queue (0);
- mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
}
done:
diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c
index f5e5efeaf0f..882c591b35a 100644
--- a/src/vnet/session/session_node.c
+++ b/src/vnet/session/session_node.c
@@ -277,10 +277,10 @@ session_mq_worker_update_handler (void *data)
/*
* Retransmit messages that may have been lost
*/
- if (!svm_fifo_is_empty (s->server_tx_fifo))
+ if (s->server_tx_fifo && !svm_fifo_is_empty (s->server_tx_fifo))
session_send_io_evt_to_thread (s->server_tx_fifo, FIFO_EVENT_APP_TX);
- if (!svm_fifo_is_empty (s->server_rx_fifo))
+ if (s->server_rx_fifo && !svm_fifo_is_empty (s->server_rx_fifo))
app_worker_lock_and_send_event (app_wrk, s, FIFO_EVENT_APP_RX);
if (s->session_state >= SESSION_STATE_TRANSPORT_CLOSING)