aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/tcp/tcp.c22
-rw-r--r--src/vnet/tcp/tcp.h3
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];