diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/tcp/tcp.c | 22 | ||||
-rw-r--r-- | src/vnet/tcp/tcp.h | 3 |
2 files changed, 22 insertions, 3 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index c4da23c957b..e243f5a3673 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -1392,7 +1392,7 @@ tcp_dispatch_pending_timers (tcp_worker_ctx_t * wrk) return; thread_index = wrk->vm->thread_index; - for (i = 0; i < clib_min (n_timers, 32); i++) + for (i = 0; i < clib_min (n_timers, wrk->max_timers_per_loop); i++) { clib_fifo_sub1 (wrk->pending_timers, timer_handle); connection_index = timer_handle & 0x0FFFFFFF; @@ -1412,6 +1412,10 @@ tcp_dispatch_pending_timers (tcp_worker_ctx_t * wrk) (*timer_expiration_handlers[timer_id]) (tc); } + + if (thread_index == 0 && clib_fifo_elts (wrk->pending_timers)) + vlib_process_signal_event_mt (wrk->vm, session_queue_process_node.index, + SESSION_Q_PROCESS_FLUSH_FRAMES, 0); } /** @@ -1511,8 +1515,8 @@ tcp_connection_tx_pacer_reset (tcp_connection_t * tc, u32 window, static void tcp_expired_timers_dispatch (u32 * expired_timers) { - u32 thread_index = vlib_get_thread_index (); - u32 connection_index, timer_id, n_expired; + u32 thread_index = vlib_get_thread_index (), n_left, max_per_loop; + u32 connection_index, timer_id, n_expired, max_loops; tcp_worker_ctx_t *wrk; tcp_connection_t *tc; int i; @@ -1520,6 +1524,7 @@ tcp_expired_timers_dispatch (u32 * expired_timers) wrk = tcp_get_worker (thread_index); n_expired = vec_len (expired_timers); tcp_workerp_stats_inc (wrk, timer_expirations, n_expired); + n_left = clib_fifo_elts (wrk->pending_timers); /* * Invalidate all timer handles before dispatching. This avoids dangling @@ -1541,6 +1546,16 @@ tcp_expired_timers_dispatch (u32 * expired_timers) } clib_fifo_add (wrk->pending_timers, expired_timers, n_expired); + + max_loops = clib_max (1, 0.5 * TCP_TIMER_TICK * wrk->vm->loops_per_second); + max_per_loop = clib_max ((n_left + n_expired) / max_loops, 10); + max_per_loop = clib_min (max_per_loop, VLIB_FRAME_SIZE); + wrk->max_timers_per_loop = clib_max (n_left ? wrk->max_timers_per_loop : 0, + max_per_loop); + + if (thread_index == 0) + vlib_process_signal_event_mt (wrk->vm, session_queue_process_node.index, + SESSION_Q_PROCESS_FLUSH_FRAMES, 0); } static void @@ -1612,6 +1627,7 @@ tcp_main_enable (vlib_main_t * vm) vec_reset_length (wrk->pending_disconnects); vec_reset_length (wrk->pending_resets); wrk->vm = vlib_mains[thread]; + wrk->max_timers_per_loop = 10; /* * Preallocate connections. Assume that thread 0 won't diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index e7b53b8ec42..bef7edbd411 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -544,6 +544,9 @@ typedef struct tcp_worker_ctx_ /** worker time */ u32 time_now; + /* Max timers to be handled per dispatch loop */ + u32 max_timers_per_loop; + /** tx frames for ip 4/6 lookup nodes */ vlib_frame_t *ip_lookup_tx_frames[2]; |