From 86f04500ae027dc66e91519a006388e56df4ceff Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 12 Sep 2018 16:08:01 -0700 Subject: [PATCH] vcl: keep track of unexpected events If sessions are marked as blocking, events for other sessions received while waiting for the blocking sessions, are added to a pending list and processed later. Change-Id: Ia6c71006b1c2bcb78af708390da0cd436af397cc Signed-off-by: Florin Coras --- src/vcl/sock_test_common.h | 2 +- src/vcl/vcl_private.c | 2 + src/vcl/vcl_private.h | 3 + src/vcl/vppcom.c | 544 ++++++++++++++++++++----------------- src/vnet/session/segment_manager.c | 5 +- src/vnet/session/session.c | 4 +- 6 files changed, 303 insertions(+), 257 deletions(-) diff --git a/src/vcl/sock_test_common.h b/src/vcl/sock_test_common.h index 7fbe52d0a93..8206fa2264c 100644 --- a/src/vcl/sock_test_common.h +++ b/src/vcl/sock_test_common.h @@ -46,7 +46,7 @@ #define SOCK_TEST_CFG_TXBUF_SIZE_DEF 8192 #define SOCK_TEST_CFG_RXBUF_SIZE_DEF (64*SOCK_TEST_CFG_TXBUF_SIZE_DEF) #define SOCK_TEST_CFG_BUF_SIZE_MIN 128 -#define SOCK_TEST_CFG_MAX_TEST_SCKTS 5 +#define SOCK_TEST_CFG_MAX_TEST_SCKTS 32 typedef enum { diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c index 0b8c2da45db..d159a49a89c 100644 --- a/src/vcl/vcl_private.c +++ b/src/vcl/vcl_private.c @@ -274,6 +274,8 @@ vcl_worker_alloc_and_init () vec_validate (wrk->mq_events, 64); vec_validate (wrk->mq_msg_vector, 128); vec_reset_length (wrk->mq_msg_vector); + vec_validate (wrk->unhandled_evts_vector, 128); + vec_reset_length (wrk->unhandled_evts_vector); if (wrk->wrk_index == 0) { diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 5f3c1ecd63f..29508415cbe 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -259,6 +259,9 @@ typedef struct vcl_worker_ /** Vector acting as buffer for mq messages */ svm_msg_q_msg_t *mq_msg_vector; + /** Vector of unhandled events */ + session_event_t *unhandled_evts_vector; + /** Used also as a thread stop key buffer */ pthread_t thread_id; } vcl_worker_t; diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index df8f4cae964..cf3a770f045 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -478,8 +478,8 @@ vcl_session_bound_handler (vcl_worker_t * wrk, session_bound_msg_t * mp) return sid; } -int -vcl_handle_mq_ctrl_event (vcl_worker_t * wrk, session_event_t * e) +static int +vcl_handle_mq_event (vcl_worker_t * wrk, session_event_t * e) { session_accepted_msg_t *accepted_msg; session_disconnected_msg_t *disconnected_msg; @@ -491,9 +491,10 @@ vcl_handle_mq_ctrl_event (vcl_worker_t * wrk, session_event_t * e) switch (e->event_type) { case FIFO_EVENT_APP_RX: - clib_warning ("unhandled rx: sid %u (0x%x)", - e->fifo->client_session_index, - e->fifo->client_session_index); + case FIFO_EVENT_APP_TX: + case SESSION_IO_EVT_CT_RX: + case SESSION_IO_EVT_CT_TX: + vec_add1 (wrk->unhandled_evts_vector, *e); break; case SESSION_CTRL_EVT_ACCEPTED: accepted_msg = (session_accepted_msg_t *) e->data; @@ -524,7 +525,7 @@ vcl_handle_mq_ctrl_event (vcl_worker_t * wrk, session_event_t * e) break; } session->session_state = STATE_DISCONNECT; - VDBG (0, "disconnected handle 0xllx, sid %u", disconnected_msg->handle, + VDBG (0, "disconnected handle 0x%llx, sid %u", disconnected_msg->handle, sid); break; case SESSION_CTRL_EVT_RESET: @@ -569,7 +570,7 @@ vppcom_wait_for_session_state_change (u32 session_index, if (svm_msg_q_sub (wrk->app_event_queue, &msg, SVM_Q_NOWAIT, 0)) continue; e = svm_msg_q_msg_data (wrk->app_event_queue, &msg); - vcl_handle_mq_ctrl_event (wrk, e); + vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (wrk->app_event_queue, &msg); } while (clib_time_now (&wrk->clib_time) < timeout); @@ -1313,7 +1314,7 @@ vppcom_session_read_internal (uint32_t session_handle, void *buf, int n, svm_msg_q_unlock (mq); if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) { - vcl_handle_mq_ctrl_event (wrk, e); + vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); continue; } @@ -1406,7 +1407,7 @@ vppcom_session_read_segments (uint32_t session_handle, svm_msg_q_unlock (mq); if (!vcl_is_rx_evt_for_session (e, s->session_index, is_ct)) { - vcl_handle_mq_ctrl_event (wrk, e); + vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); continue; } @@ -1559,7 +1560,7 @@ vppcom_session_write (uint32_t session_handle, void *buf, size_t n) if (!vcl_is_tx_evt_for_session (e, s->session_index, s->our_evt_q != 0)) - vcl_handle_mq_ctrl_event (wrk, e); + vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, &msg); } } @@ -1680,21 +1681,124 @@ if (PREDICT_FALSE (svm_fifo_is_empty (_fifo))) \ break; \ } \ -static int -vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, - unsigned long n_bits, unsigned long *read_map, - unsigned long *write_map, unsigned long *except_map, - double time_to_wait, u32 * bits_set) +static void +vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, + unsigned long n_bits, unsigned long *read_map, + unsigned long *write_map, + unsigned long *except_map, u32 * bits_set) { session_disconnected_msg_t *disconnected_msg; session_connected_msg_t *connected_msg; session_accepted_msg_t *accepted_msg; vcl_session_msg_t *vcl_msg; vcl_session_t *session; + u64 handle; + u32 sid; + + switch (e->event_type) + { + case FIFO_EVENT_APP_RX: + vcl_fifo_rx_evt_valid_or_break (e->fifo); + sid = e->fifo->client_session_index; + session = vcl_session_get (wrk, sid); + if (!session) + break; + if (sid < n_bits && read_map) + { + clib_bitmap_set_no_check (read_map, sid, 1); + *bits_set += 1; + } + break; + case FIFO_EVENT_APP_TX: + sid = e->fifo->client_session_index; + session = vcl_session_get (wrk, sid); + if (!session) + break; + if (sid < n_bits && write_map) + { + clib_bitmap_set_no_check (write_map, sid, 1); + *bits_set += 1; + } + break; + case SESSION_IO_EVT_CT_TX: + vcl_fifo_rx_evt_valid_or_break (e->fifo); + session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0); + if (!session) + break; + sid = session->session_index; + if (sid < n_bits && read_map) + { + clib_bitmap_set_no_check (read_map, sid, 1); + *bits_set += 1; + } + break; + case SESSION_IO_EVT_CT_RX: + session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1); + if (!session) + break; + sid = session->session_index; + if (sid < n_bits && write_map) + { + clib_bitmap_set_no_check (write_map, sid, 1); + *bits_set += 1; + } + break; + case SESSION_CTRL_EVT_ACCEPTED: + accepted_msg = (session_accepted_msg_t *) e->data; + handle = accepted_msg->listener_handle; + session = vcl_session_table_lookup_listener (wrk, handle); + if (!session) + { + clib_warning ("VCL<%d>: ERROR: couldn't find listen session:" + "listener handle %llx", getpid (), handle); + break; + } + + clib_fifo_add2 (session->accept_evts_fifo, vcl_msg); + vcl_msg->accepted_msg = *accepted_msg; + sid = session->session_index; + if (sid < n_bits && read_map) + { + clib_bitmap_set_no_check (read_map, sid, 1); + *bits_set += 1; + } + break; + case SESSION_CTRL_EVT_CONNECTED: + connected_msg = (session_connected_msg_t *) e->data; + vcl_session_connected_handler (wrk, connected_msg); + break; + case SESSION_CTRL_EVT_DISCONNECTED: + disconnected_msg = (session_disconnected_msg_t *) e->data; + sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle); + if (sid < n_bits && except_map) + { + clib_bitmap_set_no_check (except_map, sid, 1); + *bits_set += 1; + } + break; + case SESSION_CTRL_EVT_RESET: + sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data); + if (sid < n_bits && except_map) + { + clib_bitmap_set_no_check (except_map, sid, 1); + *bits_set += 1; + } + break; + default: + clib_warning ("unhandled: %u", e->event_type); + break; + } +} + +static int +vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, + unsigned long n_bits, unsigned long *read_map, + unsigned long *write_map, unsigned long *except_map, + double time_to_wait, u32 * bits_set) +{ svm_msg_q_msg_t *msg; session_event_t *e; - u32 i, sid; - u64 handle; + u32 i; svm_msg_q_lock (mq); if (svm_msg_q_is_empty (mq)) @@ -1730,104 +1834,10 @@ vcl_select_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, { msg = vec_elt_at_index (wrk->mq_msg_vector, i); e = svm_msg_q_msg_data (mq, msg); - switch (e->event_type) - { - case FIFO_EVENT_APP_RX: - vcl_fifo_rx_evt_valid_or_break (e->fifo); - sid = e->fifo->client_session_index; - session = vcl_session_get (wrk, sid); - if (!session) - break; - if (sid < n_bits && read_map) - { - clib_bitmap_set_no_check (read_map, sid, 1); - *bits_set += 1; - } - break; - case FIFO_EVENT_APP_TX: - sid = e->fifo->client_session_index; - session = vcl_session_get (wrk, sid); - if (!session) - break; - if (sid < n_bits && write_map) - { - clib_bitmap_set_no_check (write_map, sid, 1); - *bits_set += 1; - } - break; - case SESSION_IO_EVT_CT_TX: - vcl_fifo_rx_evt_valid_or_break (e->fifo); - session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0); - if (!session) - break; - sid = session->session_index; - if (sid < n_bits && read_map) - { - clib_bitmap_set_no_check (read_map, sid, 1); - *bits_set += 1; - } - break; - case SESSION_IO_EVT_CT_RX: - session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1); - if (!session) - break; - sid = session->session_index; - if (sid < n_bits && write_map) - { - clib_bitmap_set_no_check (write_map, sid, 1); - *bits_set += 1; - } - break; - case SESSION_CTRL_EVT_ACCEPTED: - accepted_msg = (session_accepted_msg_t *) e->data; - handle = accepted_msg->listener_handle; - session = vcl_session_table_lookup_listener (wrk, handle); - if (!session) - { - clib_warning ("VCL<%d>: ERROR: couldn't find listen session:" - "listener handle %llx", getpid (), handle); - break; - } - - clib_fifo_add2 (session->accept_evts_fifo, vcl_msg); - vcl_msg->accepted_msg = *accepted_msg; - sid = session->session_index; - if (sid < n_bits && read_map) - { - clib_bitmap_set_no_check (read_map, sid, 1); - *bits_set += 1; - } - break; - case SESSION_CTRL_EVT_CONNECTED: - connected_msg = (session_connected_msg_t *) e->data; - vcl_session_connected_handler (wrk, connected_msg); - break; - case SESSION_CTRL_EVT_DISCONNECTED: - disconnected_msg = (session_disconnected_msg_t *) e->data; - sid = vcl_session_index_from_vpp_handle (wrk, - disconnected_msg->handle); - if (sid < n_bits && except_map) - { - clib_bitmap_set_no_check (except_map, sid, 1); - *bits_set += 1; - } - break; - case SESSION_CTRL_EVT_RESET: - sid = vcl_session_reset_handler (wrk, - (session_reset_msg_t *) e->data); - if (sid < n_bits && except_map) - { - clib_bitmap_set_no_check (except_map, sid, 1); - *bits_set += 1; - } - break; - default: - clib_warning ("unhandled: %u", e->event_type); - break; - } + vcl_select_handle_mq_event (wrk, e, n_bits, read_map, write_map, + except_map, bits_set); svm_msg_q_free_msg (mq, msg); } - vec_reset_length (wrk->mq_msg_vector); return *bits_set; } @@ -1898,7 +1908,7 @@ vppcom_select (unsigned long n_bits, unsigned long *read_map, u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0; vcl_worker_t *wrk = vcl_worker_get_current (); vcl_session_t *session = 0; - int rv; + int rv, i; ASSERT (sizeof (clib_bitmap_t) == sizeof (long int)); @@ -1972,6 +1982,13 @@ check_rd: check_mq: + for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++) + { + vcl_select_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], n_bits, + read_map, write_map, except_map, &bits_set); + } + vec_reset_length (wrk->unhandled_evts_vector); + if (vcm->cfg.use_mq_eventfd) vppcom_select_eventfd (wrk, n_bits, read_map, write_map, except_map, time_to_wait, &bits_set); @@ -2275,10 +2292,9 @@ done: return rv; } -static int -vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, - struct epoll_event *events, u32 maxevents, - double wait_for_time, u32 * num_ev) +static inline void +vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, + struct epoll_event *events, u32 * num_ev) { session_disconnected_msg_t *disconnected_msg; session_connected_msg_t *connected_msg; @@ -2287,9 +2303,131 @@ vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, u32 sid = ~0, session_events; vcl_session_msg_t *vcl_msg; vcl_session_t *session; + u8 add_event = 0; + + switch (e->event_type) + { + case FIFO_EVENT_APP_RX: + ASSERT (e->fifo->client_thread_index == vcl_get_worker_index ()); + vcl_fifo_rx_evt_valid_or_break (e->fifo); + sid = e->fifo->client_session_index; + session = vcl_session_get (wrk, sid); + session_events = session->vep.ev.events; + if (!(EPOLLIN & session->vep.ev.events)) + break; + add_event = 1; + events[*num_ev].events |= EPOLLIN; + session_evt_data = session->vep.ev.data.u64; + break; + case FIFO_EVENT_APP_TX: + sid = e->fifo->client_session_index; + session = vcl_session_get (wrk, sid); + session_events = session->vep.ev.events; + if (!(EPOLLOUT & session_events)) + break; + add_event = 1; + events[*num_ev].events |= EPOLLOUT; + session_evt_data = session->vep.ev.data.u64; + break; + case SESSION_IO_EVT_CT_TX: + vcl_fifo_rx_evt_valid_or_break (e->fifo); + session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0); + sid = session->session_index; + session_events = session->vep.ev.events; + if (!(EPOLLIN & session->vep.ev.events)) + break; + add_event = 1; + events[*num_ev].events |= EPOLLIN; + session_evt_data = session->vep.ev.data.u64; + break; + case SESSION_IO_EVT_CT_RX: + session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1); + sid = session->session_index; + session_events = session->vep.ev.events; + if (!(EPOLLOUT & session_events)) + break; + add_event = 1; + events[*num_ev].events |= EPOLLOUT; + session_evt_data = session->vep.ev.data.u64; + break; + case SESSION_CTRL_EVT_ACCEPTED: + accepted_msg = (session_accepted_msg_t *) e->data; + handle = accepted_msg->listener_handle; + session = vcl_session_table_lookup_listener (wrk, handle); + if (!session) + { + clib_warning ("VCL<%d>: ERROR: couldn't find listen session:" + "listener handle %llx", getpid (), handle); + break; + } + + clib_fifo_add2 (session->accept_evts_fifo, vcl_msg); + vcl_msg->accepted_msg = *accepted_msg; + session_events = session->vep.ev.events; + if (!(EPOLLIN & session_events)) + break; + + add_event = 1; + events[*num_ev].events |= EPOLLIN; + session_evt_data = session->vep.ev.data.u64; + break; + case SESSION_CTRL_EVT_CONNECTED: + connected_msg = (session_connected_msg_t *) e->data; + vcl_session_connected_handler (wrk, connected_msg); + /* Generate EPOLLOUT because there's no connected event */ + sid = vcl_session_index_from_vpp_handle (wrk, connected_msg->handle); + session = vcl_session_get (wrk, sid); + session_events = session->vep.ev.events; + if (EPOLLOUT & session_events) + { + add_event = 1; + events[*num_ev].events |= EPOLLOUT; + session_evt_data = session->vep.ev.data.u64; + } + break; + case SESSION_CTRL_EVT_DISCONNECTED: + disconnected_msg = (session_disconnected_msg_t *) e->data; + sid = vcl_session_index_from_vpp_handle (wrk, disconnected_msg->handle); + if (!(session = vcl_session_get (wrk, sid))) + break; + add_event = 1; + events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP; + session_evt_data = session->vep.ev.data.u64; + session_events = session->vep.ev.events; + break; + case SESSION_CTRL_EVT_RESET: + sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data); + if (!(session = vcl_session_get (wrk, sid))) + break; + add_event = 1; + events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP; + session_evt_data = session->vep.ev.data.u64; + session_events = session->vep.ev.events; + break; + default: + VDBG (0, "unhandled: %u", e->event_type); + break; + } + + if (add_event) + { + events[*num_ev].data.u64 = session_evt_data; + if (EPOLLONESHOT & session_events) + { + session = vcl_session_get (wrk, sid); + session->vep.ev.events = 0; + } + *num_ev += 1; + } +} + +static int +vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, + struct epoll_event *events, u32 maxevents, + double wait_for_time, u32 * num_ev) +{ svm_msg_q_msg_t *msg; session_event_t *e; - u8 add_event; int i; svm_msg_q_lock (mq); @@ -2320,141 +2458,26 @@ vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, { msg = vec_elt_at_index (wrk->mq_msg_vector, i); e = svm_msg_q_msg_data (mq, msg); - add_event = 0; - switch (e->event_type) - { - case FIFO_EVENT_APP_RX: - ASSERT (e->fifo->client_thread_index == vcl_get_worker_index ()); - vcl_fifo_rx_evt_valid_or_break (e->fifo); - sid = e->fifo->client_session_index; - session = vcl_session_get (wrk, sid); - session_events = session->vep.ev.events; - if (!(EPOLLIN & session->vep.ev.events)) - break; - add_event = 1; - events[*num_ev].events |= EPOLLIN; - session_evt_data = session->vep.ev.data.u64; - break; - case FIFO_EVENT_APP_TX: - sid = e->fifo->client_session_index; - session = vcl_session_get (wrk, sid); - session_events = session->vep.ev.events; - if (!(EPOLLOUT & session_events)) - break; - add_event = 1; - events[*num_ev].events |= EPOLLOUT; - session_evt_data = session->vep.ev.data.u64; - break; - case SESSION_IO_EVT_CT_TX: - vcl_fifo_rx_evt_valid_or_break (e->fifo); - session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 0); - sid = session->session_index; - session_events = session->vep.ev.events; - if (!(EPOLLIN & session->vep.ev.events)) - break; - add_event = 1; - events[*num_ev].events |= EPOLLIN; - session_evt_data = session->vep.ev.data.u64; - break; - case SESSION_IO_EVT_CT_RX: - session = vcl_ct_session_get_from_fifo (wrk, e->fifo, 1); - sid = session->session_index; - session_events = session->vep.ev.events; - if (!(EPOLLOUT & session_events)) - break; - add_event = 1; - events[*num_ev].events |= EPOLLOUT; - session_evt_data = session->vep.ev.data.u64; - break; - case SESSION_CTRL_EVT_ACCEPTED: - accepted_msg = (session_accepted_msg_t *) e->data; - handle = accepted_msg->listener_handle; - session = vcl_session_table_lookup_listener (wrk, handle); - if (!session) - { - clib_warning ("VCL<%d>: ERROR: couldn't find listen session:" - "listener handle %llx", getpid (), handle); - break; - } - - clib_fifo_add2 (session->accept_evts_fifo, vcl_msg); - vcl_msg->accepted_msg = *accepted_msg; - session_events = session->vep.ev.events; - if (!(EPOLLIN & session_events)) - break; - - add_event = 1; - events[*num_ev].events |= EPOLLIN; - session_evt_data = session->vep.ev.data.u64; - break; - case SESSION_CTRL_EVT_CONNECTED: - connected_msg = (session_connected_msg_t *) e->data; - vcl_session_connected_handler (wrk, connected_msg); - /* Generate EPOLLOUT because there's no connected event */ - sid = vcl_session_index_from_vpp_handle (wrk, - connected_msg->handle); - session = vcl_session_get (wrk, sid); - session_events = session->vep.ev.events; - if (EPOLLOUT & session_events) - { - add_event = 1; - events[*num_ev].events |= EPOLLOUT; - session_evt_data = session->vep.ev.data.u64; - } - break; - case SESSION_CTRL_EVT_DISCONNECTED: - disconnected_msg = (session_disconnected_msg_t *) e->data; - sid = vcl_session_index_from_vpp_handle (wrk, - disconnected_msg->handle); - if (!(session = vcl_session_get (wrk, sid))) - break; - add_event = 1; - events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP; - session_evt_data = session->vep.ev.data.u64; - session_events = session->vep.ev.events; - break; - case SESSION_CTRL_EVT_RESET: - sid = vcl_session_reset_handler (wrk, - (session_reset_msg_t *) e->data); - if (!(session = vcl_session_get (wrk, sid))) - break; - add_event = 1; - events[*num_ev].events |= EPOLLHUP | EPOLLRDHUP; - session_evt_data = session->vep.ev.data.u64; - session_events = session->vep.ev.events; - break; - default: - VDBG (0, "unhandled: %u", e->event_type); - svm_msg_q_free_msg (mq, msg); - continue; - } + vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev); svm_msg_q_free_msg (mq, msg); - - if (add_event) + if (*num_ev == maxevents) { - events[*num_ev].data.u64 = session_evt_data; - if (EPOLLONESHOT & session_events) - { - session = vcl_session_get (wrk, sid); - session->vep.ev.events = 0; - } - *num_ev += 1; - if (*num_ev == maxevents) - break; + i += 1; + break; } } - vec_reset_length (wrk->mq_msg_vector); + vec_delete (wrk->mq_msg_vector, i, 0); + return *num_ev; } static int vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events, - int maxevents, double wait_for_time) + int maxevents, u32 n_evts, double wait_for_time) { vcl_cut_through_registration_t *cr; double total_wait = 0, wait_slice; - u32 num_ev = 0; int rv; wait_for_time = (wait_for_time == -1) ? (double) 10e9 : wait_for_time; @@ -2465,31 +2488,30 @@ vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events, vcl_ct_registration_lock (wrk); /* *INDENT-OFF* */ pool_foreach (cr, wrk->cut_through_registrations, ({ - vcl_epoll_wait_handle_mq (wrk, cr->mq, events, maxevents, 0, &num_ev); + vcl_epoll_wait_handle_mq (wrk, cr->mq, events, maxevents, 0, &n_evts); })); /* *INDENT-ON* */ vcl_ct_registration_unlock (wrk); rv = vcl_epoll_wait_handle_mq (wrk, wrk->app_event_queue, events, - maxevents, num_ev ? 0 : wait_slice, - &num_ev); + maxevents, n_evts ? 0 : wait_slice, + &n_evts); if (rv) total_wait += wait_slice; - if (num_ev) - return num_ev; + if (n_evts) + return n_evts; } while (total_wait < wait_for_time); - return (int) num_ev; + return n_evts; } static int vppcom_epoll_wait_eventfd (vcl_worker_t * wrk, struct epoll_event *events, - int maxevents, double wait_for_time) + int maxevents, u32 n_evts, double wait_for_time) { vcl_mq_evt_conn_t *mqc; int __clib_unused n_read; int n_mq_evts, i; - u32 n_evts = 0; u64 buf; vec_validate (wrk->mq_events, pool_elts (wrk->mq_evt_conns)); @@ -2511,6 +2533,8 @@ vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events, { vcl_worker_t *wrk = vcl_worker_get_current (); vcl_session_t *vep_session; + u32 n_evts = 0; + int i; if (PREDICT_FALSE (maxevents <= 0)) { @@ -2532,10 +2556,28 @@ vppcom_epoll_wait (uint32_t vep_handle, struct epoll_event *events, memset (events, 0, sizeof (*events) * maxevents); + if (vec_len (wrk->unhandled_evts_vector)) + { + for (i = 0; i < vec_len (wrk->unhandled_evts_vector); i++) + { + vcl_epoll_wait_handle_mq_event (wrk, &wrk->unhandled_evts_vector[i], + events, &n_evts); + if (n_evts == maxevents) + { + i += 1; + break; + } + } + + vec_delete (wrk->unhandled_evts_vector, i, 0); + } + if (vcm->cfg.use_mq_eventfd) - return vppcom_epoll_wait_eventfd (wrk, events, maxevents, wait_for_time); + return vppcom_epoll_wait_eventfd (wrk, events, maxevents, n_evts, + wait_for_time); - return vppcom_epoll_wait_condvar (wrk, events, maxevents, wait_for_time); + return vppcom_epoll_wait_condvar (wrk, events, maxevents, n_evts, + wait_for_time); } int diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index 83d196358f3..0c19293ce3b 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -193,7 +193,7 @@ segment_manager_add_segment (segment_manager_t * sm, u32 segment_size) if (props->segment_type != SSVM_SEGMENT_PRIVATE) { seg_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0); - alloc_size = segment_size + rnd_margin; + alloc_size = (uword) segment_size + rnd_margin; baseva = clib_valloc_alloc (&smm->va_allocator, alloc_size, 0); if (!baseva) { @@ -253,8 +253,7 @@ segment_manager_init (segment_manager_t * sm, u32 first_seg_size, { u32 rx_fifo_size, tx_fifo_size, pair_size; u32 rx_rounded_data_size, tx_rounded_data_size; - u64 approx_total_size, max_seg_size = - ((u64) 1 << 32) - clib_mem_get_page_size (); + u64 approx_total_size, max_seg_size = ((u64) 1 << 32) - (128 << 10); segment_manager_properties_t *props; svm_fifo_segment_private_t *segment; u32 approx_segment_count; diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 472b38baae1..133c91ca198 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -390,7 +390,7 @@ session_enqueue_stream_connection (transport_connection_t * tc, { s->enqueue_epoch = enqueue_epoch; vec_add1 (smm->session_to_enqueue[tc->proto][thread_index], - s - smm->sessions[thread_index]); + s->session_index); } } @@ -431,7 +431,7 @@ session_enqueue_dgram_connection (stream_session_t * s, { s->enqueue_epoch = enqueue_epoch; vec_add1 (smm->session_to_enqueue[proto][thread_index], - s - smm->sessions[thread_index]); + s->session_index); } } return enqueued; -- 2.16.6