X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fsession%2Fapplication.c;h=3e127df3bd2eb14c5997204ee4d9fce0cbab4cfd;hb=993683150202254c6ba8dd43e087a7229edd5d4c;hp=1dc04f0afa73ce6d51493fe6e1c9d75202644066;hpb=52207f1b7b60cb0784d5241f0a4d40eef531c67e;p=vpp.git diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 1dc04f0afa7..3e127df3bd2 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -312,6 +312,12 @@ application_init (application_t * app, u32 api_client_index, u8 * app_name, } else { + if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) + { + clib_warning ("mq eventfds can only be used if socket transport is " + "used for api"); + return VNET_API_ERROR_APP_UNSUPPORTED_CFG; + } seg_type = SSVM_SEGMENT_PRIVATE; } @@ -336,6 +342,8 @@ application_init (application_t * app, u32 api_client_index, u8 * app_name, props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE]; if (options[APP_OPTIONS_EVT_QUEUE_SIZE]) props->evt_q_size = options[APP_OPTIONS_EVT_QUEUE_SIZE]; + if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD) + props->use_mq_eventfd = 1; if (options[APP_OPTIONS_TLS_ENGINE]) app->tls_engine = options[APP_OPTIONS_TLS_ENGINE]; props->segment_type = seg_type; @@ -841,19 +849,20 @@ app_send_io_evt_rx (application_t * app, stream_session_t * s, u8 lock) svm_msg_q_msg_t msg; svm_msg_q_t *mq; - if (PREDICT_FALSE (s->session_state == SESSION_STATE_CLOSED)) + if (PREDICT_FALSE (s->session_state != SESSION_STATE_READY + && s->session_state != SESSION_STATE_LISTENING)) { /* Session is closed so app will never clean up. Flush rx fifo */ - svm_fifo_dequeue_drop_all (s->server_rx_fifo); + if (s->session_state == SESSION_STATE_CLOSED) + svm_fifo_dequeue_drop_all (s->server_rx_fifo); return 0; } - /* Built-in app? Hand event to the callback... */ if (app->cb_fns.builtin_app_rx_callback) return app->cb_fns.builtin_app_rx_callback (s); - /* If no need for event, return */ - if (!svm_fifo_set_event (s->server_rx_fifo)) + if (svm_fifo_has_event (s->server_rx_fifo) + || svm_fifo_is_empty (s->server_rx_fifo)) return 0; mq = app->event_queue; @@ -875,7 +884,10 @@ app_send_io_evt_rx (application_t * app, stream_session_t * s, u8 lock) evt->fifo = s->server_rx_fifo; evt->event_type = FIFO_EVENT_APP_RX; - return app_enqueue_evt (mq, &msg, lock); + if (app_enqueue_evt (mq, &msg, lock)) + return -1; + (void) svm_fifo_set_event (s->server_rx_fifo); + return 0; } static inline int @@ -914,8 +926,9 @@ app_send_io_evt_tx (application_t * app, stream_session_t * s, u8 lock) typedef int (app_send_evt_handler_fn) (application_t *app, stream_session_t *s, u8 lock); -static app_send_evt_handler_fn * const app_send_evt_handler_fns[2] = { +static app_send_evt_handler_fn * const app_send_evt_handler_fns[3] = { app_send_io_evt_rx, + 0, app_send_io_evt_tx, }; /* *INDENT-ON* */ @@ -965,6 +978,8 @@ application_free_local_session (application_t * app, local_session_t * s) local_session_t * application_get_local_session (application_t * app, u32 session_index) { + if (pool_is_free_index (app->local_sessions, session_index)) + return 0; return pool_elt_at_index (app->local_sessions, session_index); } @@ -1073,6 +1088,23 @@ application_stop_local_listen (application_t * server, session_handle_t lh) return 0; } +static void +application_local_session_fix_eventds (svm_msg_q_t * sq, svm_msg_q_t * cq) +{ + int fd; + + /* + * segment manager initializes only the producer eventds, since vpp is + * typically the producer. But for local sessions, we also pass to the + * apps the mqs they listen on for events from peer apps, so they are also + * consumer fds. + */ + fd = svm_msg_q_get_producer_eventfd (sq); + svm_msg_q_set_consumer_eventfd (sq, fd); + fd = svm_msg_q_get_producer_eventfd (cq); + svm_msg_q_set_consumer_eventfd (cq, fd); +} + int application_local_session_connect (u32 table_index, application_t * client, application_t * server, @@ -1080,6 +1112,7 @@ application_local_session_connect (u32 table_index, application_t * client, { u32 seg_size, evt_q_sz, evt_q_elts, margin = 16 << 10; segment_manager_properties_t *props, *cprops; + u32 round_rx_fifo_sz, round_tx_fifo_sz; int rv, has_transport, seg_index; svm_fifo_segment_private_t *seg; segment_manager_t *sm; @@ -1092,7 +1125,9 @@ application_local_session_connect (u32 table_index, application_t * client, cprops = application_segment_manager_properties (client); evt_q_elts = props->evt_q_size + cprops->evt_q_size; evt_q_sz = segment_manager_evt_q_expected_size (evt_q_elts); - seg_size = props->rx_fifo_size + props->tx_fifo_size + evt_q_sz + margin; + round_rx_fifo_sz = 1 << max_log2 (props->rx_fifo_size); + round_tx_fifo_sz = 1 << max_log2 (props->tx_fifo_size); + seg_size = round_rx_fifo_sz + round_tx_fifo_sz + evt_q_sz + margin; has_transport = session_has_transport ((stream_session_t *) ll); if (!has_transport) @@ -1117,8 +1152,12 @@ application_local_session_connect (u32 table_index, application_t * client, return seg_index; } seg = segment_manager_get_segment_w_lock (sm, seg_index); - sq = segment_manager_alloc_queue (seg, props->evt_q_size); - cq = segment_manager_alloc_queue (seg, cprops->evt_q_size); + sq = segment_manager_alloc_queue (seg, props); + cq = segment_manager_alloc_queue (seg, cprops); + + if (props->use_mq_eventfd) + application_local_session_fix_eventds (sq, cq); + ls->server_evt_q = pointer_to_uword (sq); ls->client_evt_q = pointer_to_uword (cq); rv = segment_manager_try_alloc_fifos (seg, props->rx_fifo_size, @@ -1265,7 +1304,7 @@ application_local_session_disconnect (u32 app_index, local_session_t * ls) if (app_index == ls->client_index) { - send_local_session_disconnect_callback (ls->app_index, ls); + mq_send_local_session_disconnected_cb (ls->app_index, ls); } else { @@ -1284,7 +1323,7 @@ application_local_session_disconnect (u32 app_index, local_session_t * ls) } else { - send_local_session_disconnect_callback (client->index, ls); + mq_send_local_session_disconnected_cb (client->index, ls); } }