summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/session/segment_manager.c24
-rw-r--r--src/vnet/session/segment_manager.h3
-rw-r--r--src/vnet/session/session.c54
3 files changed, 71 insertions, 10 deletions
diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c
index 716f2a39a4e..b40675ad56f 100644
--- a/src/vnet/session/segment_manager.c
+++ b/src/vnet/session/segment_manager.c
@@ -743,6 +743,30 @@ segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo)
segment_manager_segment_reader_unlock (sm);
}
+void
+segment_manager_detach_fifo (segment_manager_t * sm, svm_fifo_t * f)
+{
+ fifo_segment_t *fs;
+
+ fs = segment_manager_get_segment_w_lock (sm, f->segment_index);
+ fifo_segment_detach_fifo (fs, f);
+ segment_manager_segment_reader_unlock (sm);
+}
+
+void
+segment_manager_attach_fifo (segment_manager_t * sm, svm_fifo_t * f,
+ session_t * s)
+{
+ fifo_segment_t *fs;
+
+ fs = segment_manager_get_segment_w_lock (sm, f->segment_index);
+ fifo_segment_attach_fifo (fs, f, s->thread_index);
+ segment_manager_segment_reader_unlock (sm);
+
+ f->master_session_index = s->session_index;
+ f->master_thread_index = s->thread_index;
+}
+
u32
segment_manager_evt_q_expected_size (u32 q_len)
{
diff --git a/src/vnet/session/segment_manager.h b/src/vnet/session/segment_manager.h
index cd02d5480ae..13b1fffa1e2 100644
--- a/src/vnet/session/segment_manager.h
+++ b/src/vnet/session/segment_manager.h
@@ -125,6 +125,9 @@ int segment_manager_try_alloc_fifos (fifo_segment_t * fs,
svm_fifo_t ** tx_fifo);
void segment_manager_dealloc_fifos (svm_fifo_t * rx_fifo,
svm_fifo_t * tx_fifo);
+void segment_manager_detach_fifo (segment_manager_t * sm, svm_fifo_t * f);
+void segment_manager_attach_fifo (segment_manager_t * sm, svm_fifo_t * f,
+ session_t * s);
void segment_manager_set_watermarks (segment_manager_t * sm,
u8 high_watermark, u8 low_watermark);
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index 9d531240f27..1fa787217f3 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -809,6 +809,31 @@ session_ho_stream_connect_notify (transport_connection_t * tc,
return session_stream_connect_notify_inline (tc, err, SESSION_STATE_OPENED);
}
+static void
+session_switch_pool_reply (void *arg)
+{
+ u32 session_index = pointer_to_uword (arg);
+ segment_manager_t *sm;
+ app_worker_t *app_wrk;
+ session_t *s;
+
+ s = session_get_if_valid (session_index, vlib_get_thread_index ());
+ if (!s)
+ return;
+
+ app_wrk = app_worker_get_if_valid (s->app_wrk_index);
+ if (!app_wrk)
+ return;
+
+ /* Attach fifos to the right session and segment slice */
+ sm = app_worker_get_connect_segment_manager (app_wrk);
+ segment_manager_attach_fifo (sm, s->rx_fifo, s);
+ segment_manager_attach_fifo (sm, s->tx_fifo, s);
+
+ /* Notify app that it has data on the new session */
+ session_enqueue_notify (s);
+}
+
typedef struct _session_switch_pool_args
{
u32 session_index;
@@ -824,28 +849,38 @@ static void
session_switch_pool (void *cb_args)
{
session_switch_pool_args_t *args = (session_switch_pool_args_t *) cb_args;
+ session_handle_t new_sh;
+ segment_manager_t *sm;
app_worker_t *app_wrk;
session_t *s;
+ void *rargs;
ASSERT (args->thread_index == vlib_get_thread_index ());
s = session_get (args->session_index, args->thread_index);
- s->tx_fifo->master_session_index = args->new_session_index;
- s->tx_fifo->master_thread_index = args->new_thread_index;
+
transport_cleanup (session_get_transport_proto (s), s->connection_index,
s->thread_index);
+ new_sh = session_make_handle (args->new_session_index,
+ args->new_thread_index);
+
app_wrk = app_worker_get_if_valid (s->app_wrk_index);
if (app_wrk)
{
- session_handle_t new_sh;
- new_sh = session_make_handle (args->new_session_index,
- args->new_thread_index);
- app_worker_migrate_notify (app_wrk, s, new_sh);
+ /* Cleanup fifo segment slice state for fifos */
+ sm = app_worker_get_connect_segment_manager (app_wrk);
+ segment_manager_detach_fifo (sm, s->rx_fifo);
+ segment_manager_detach_fifo (sm, s->tx_fifo);
- /* Trigger app read on the new thread */
- session_enqueue_notify_thread (new_sh);
+ /* Notify app, using old session, about the migration event */
+ app_worker_migrate_notify (app_wrk, s, new_sh);
}
+ /* Trigger app read and fifo updates on the new thread */
+ rargs = uword_to_pointer (args->new_session_index, void *);
+ session_send_rpc_evt_to_thread (args->new_thread_index,
+ session_switch_pool_reply, rargs);
+
session_free (s);
clib_mem_free (cb_args);
}
@@ -865,10 +900,9 @@ session_dgram_connect_notify (transport_connection_t * tc,
*/
new_s = session_clone_safe (tc->s_index, old_thread_index);
new_s->connection_index = tc->c_index;
- new_s->rx_fifo->master_session_index = new_s->session_index;
- new_s->rx_fifo->master_thread_index = new_s->thread_index;
new_s->session_state = SESSION_STATE_READY;
new_s->flags |= SESSION_F_IS_MIGRATING;
+
session_lookup_add_connection (tc, session_handle (new_s));
/*