tcp: dynamic max timers per loop 88/25288/10
authorFlorin Coras <fcoras@cisco.com>
Thu, 20 Feb 2020 05:45:31 +0000 (05:45 +0000)
committerFlorin Coras <florin.coras@gmail.com>
Mon, 24 Feb 2020 21:30:51 +0000 (21:30 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: If0a634c277d4f8e4d32321f52253721a990bdb1d

src/vnet/tcp/tcp.c
src/vnet/tcp/tcp.h

index c4da23c..e243f5a 100644 (file)
@@ -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
index e7b53b8..bef7edb 100644 (file)
@@ -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];