diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vcl/vppcom.c | 39 | ||||
-rw-r--r-- | src/vnet/session/application_interface.h | 8 | ||||
-rw-r--r-- | src/vnet/session/session_api.c | 23 | ||||
-rw-r--r-- | src/vnet/session/session_types.h | 1 |
4 files changed, 70 insertions, 1 deletions
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 5eea71e143f..15313fd286c 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -629,6 +629,36 @@ vcl_session_unlisten_reply_handler (vcl_worker_t * wrk, void *data) vcl_session_free (wrk, s); } +static void +vcl_session_migrated_handler (vcl_worker_t * wrk, void *data) +{ + session_migrated_msg_t *mp = (session_migrated_msg_t *) data; + vcl_session_t *s; + + s = vcl_session_get_w_vpp_handle (wrk, mp->handle); + if (!s) + { + VDBG (0, "Migrated notification with wrong handle %llx", mp->handle); + return; + } + + s->vpp_thread_index = mp->vpp_thread_index; + s->vpp_evt_q = uword_to_pointer (mp->vpp_evt_q, svm_msg_q_t *); + + vec_validate (wrk->vpp_event_queues, s->vpp_thread_index); + wrk->vpp_event_queues[s->vpp_thread_index] = s->vpp_evt_q; + + vcl_session_table_del_vpp_handle (wrk, mp->handle); + vcl_session_table_add_vpp_handle (wrk, mp->new_handle, s->session_index); + + /* Generate new tx event if we have outstanding data */ + if (svm_fifo_has_event (s->tx_fifo)) + app_send_io_evt_to_vpp (s->vpp_evt_q, s->tx_fifo->master_session_index, + SESSION_IO_EVT_TX, SVM_Q_WAIT); + + VDBG (0, "Migrated 0x%x to thread %u", mp->handle, s->vpp_thread_index); +} + static vcl_session_t * vcl_session_accepted (vcl_worker_t * wrk, session_accepted_msg_t * msg) { @@ -812,6 +842,9 @@ vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) case SESSION_CTRL_EVT_UNLISTEN_REPLY: vcl_session_unlisten_reply_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_MIGRATED: + vcl_session_migrated_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_REQ_WORKER_UPDATE: vcl_session_req_worker_update_handler (wrk, e->data); break; @@ -2127,6 +2160,9 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_CTRL_EVT_UNLISTEN_REPLY: vcl_session_unlisten_reply_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_MIGRATED: + vcl_session_migrated_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_WORKER_UPDATE_REPLY: vcl_session_worker_update_reply_handler (wrk, e->data); break; @@ -2739,6 +2775,9 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_CTRL_EVT_UNLISTEN_REPLY: vcl_session_unlisten_reply_handler (wrk, e->data); break; + case SESSION_CTRL_EVT_MIGRATED: + vcl_session_migrated_handler (wrk, e->data); + break; case SESSION_CTRL_EVT_REQ_WORKER_UPDATE: vcl_session_req_worker_update_handler (wrk, e->data); break; diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 2e850a98e57..a6641477f12 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -502,6 +502,14 @@ typedef struct app_unmap_segment_msg_ u64 segment_handle; } session_app_del_segment_msg_t; +typedef struct session_migrate_msg_ +{ + uword vpp_evt_q; + session_handle_t handle; + session_handle_t new_handle; + u32 vpp_thread_index; +} __clib_packed session_migrated_msg_t; + typedef struct app_session_event_ { svm_msg_q_msg_t msg; diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index 153c528059c..c6eeacfea18 100644 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -470,7 +470,28 @@ mq_send_unlisten_reply (app_worker_t * app_wrk, session_handle_t sh, static void mq_send_session_migrate_cb (session_t * s, session_handle_t new_sh) { - clib_warning ("not supported"); + svm_msg_q_msg_t _msg, *msg = &_msg; + session_migrated_msg_t *mp; + svm_msg_q_t *vpp_evt_q; + app_worker_t *app_wrk; + session_event_t *evt; + svm_msg_q_t *app_mq; + + app_wrk = app_worker_get (s->app_wrk_index); + app_mq = app_wrk->event_queue; + if (mq_try_lock_and_alloc_msg (app_mq, msg)) + return; + + evt = svm_msg_q_msg_data (app_mq, msg); + clib_memset (evt, 0, sizeof (*evt)); + evt->event_type = SESSION_CTRL_EVT_MIGRATED; + mp = (session_migrated_msg_t *) evt->data; + mp->handle = session_handle (s); + mp->new_handle = new_sh; + mp->vpp_thread_index = session_thread_from_handle (new_sh); + vpp_evt_q = session_main_get_vpp_event_queue (mp->vpp_thread_index); + mp->vpp_evt_q = pointer_to_uword (vpp_evt_q); + svm_msg_q_add_and_unlock (app_mq, msg); } static int diff --git a/src/vnet/session/session_types.h b/src/vnet/session/session_types.h index ce593b0b38c..60d5e4d823c 100644 --- a/src/vnet/session/session_types.h +++ b/src/vnet/session/session_types.h @@ -336,6 +336,7 @@ typedef enum SESSION_CTRL_EVT_APP_DETACH, SESSION_CTRL_EVT_APP_ADD_SEGMENT, SESSION_CTRL_EVT_APP_DEL_SEGMENT, + SESSION_CTRL_EVT_MIGRATED, } session_evt_type_t; #define foreach_session_ctrl_evt \ |