X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvlib%2Funix%2Finput.c;h=8be0770bfd389fae469a3b19e6cf8016205f309a;hb=a25def7807fb46bd48462be3ec5c598fc79e2a13;hp=321e443dee9ab5cf817d2343a7ad08f5ce18b2c3;hpb=eb987d3a09f669787014b1553f032219522149e1;p=vpp.git diff --git a/src/vlib/unix/input.c b/src/vlib/unix/input.c index 321e443dee9..8be0770bfd3 100644 --- a/src/vlib/unix/input.c +++ b/src/vlib/unix/input.c @@ -148,9 +148,27 @@ linux_epoll_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, int timeout_ms = 0, max_timeout_ms = 10; f64 vector_rate = vlib_last_vectors_per_main_loop (vm); + /* + * If we've been asked for a fixed-sleep between main loop polls, + * do so right away. + */ + if (PREDICT_FALSE (is_main && um->poll_sleep_usec)) + { + struct timespec ts, tsrem; + timeout = 0; + timeout_ms = 0; + node->input_main_loops_per_call = 0; + ts.tv_sec = 0; + ts.tv_nsec = 1000 * um->poll_sleep_usec; + + while (nanosleep (&ts, &tsrem) < 0) + { + ts = tsrem; + } + } /* If we're not working very hard, decide how long to sleep */ - if (is_main && vector_rate < 2 && vm->api_queue_nonempty == 0 - && nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] == 0) + else if (is_main && vector_rate < 2 && vm->api_queue_nonempty == 0 + && nm->input_node_counts_by_state[VLIB_NODE_STATE_POLLING] == 0) { ticks_until_expiration = TW (tw_timer_first_expires_in_ticks) ((TWT (tw_timer_wheel) *) nm->timing_wheel); @@ -229,11 +247,40 @@ linux_epoll_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, for (e = em->epoll_events; e < em->epoll_events + n_fds_ready; e++) { u32 i = e->data.u32; - clib_file_t *f = pool_elt_at_index (fm->file_pool, i); + clib_file_t *f = fm->file_pool + i; clib_error_t *errors[4]; int n_errors = 0; - if (PREDICT_TRUE (!(e->events & EPOLLERR))) + if (PREDICT_FALSE (pool_is_free (fm->file_pool, f))) + { + /* + * Under rare scenerop, epoll may still post us events for the + * deleted file descriptor. We just deal with it and throw away the + * events for the corresponding file descriptor. + */ + if (e->events & EPOLLIN) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLIN dropped due " + "to free index %u", i); + n_errors++; + } + if (e->events & EPOLLOUT) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLOUT dropped due " + "to free index %u", i); + n_errors++; + } + if (e->events & EPOLLERR) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLERR dropped due " + "to free index %u", i); + n_errors++; + } + } + else if (PREDICT_TRUE (!(e->events & EPOLLERR))) { if (e->events & EPOLLIN) {