tcp: prevent timer handler being called frequently 18/32718/3
authorliuyacan <liuyacan@corp.netease.com>
Mon, 14 Jun 2021 10:09:01 +0000 (18:09 +0800)
committerFlorin Coras <florin.coras@gmail.com>
Tue, 15 Jun 2021 05:27:32 +0000 (05:27 +0000)
In the current implement, tcp would start or up an one tick
retransmit timer for that connection if vlib_buffer_alloc()
return 0. Now the tick is 0.1ms, this means that if VPP is
in a buffer shortage state, there would be a large number of
burst timer expirations.

This commit limits the minimum interval of the retransmission
timer to 100ms.

Type: fix

Signed-off-by: liuyacan <liuyacan@corp.netease.com>
Change-Id: Ia11d693fe46119c5dc16b24ca93c30c31109057a

src/vnet/tcp/tcp.c
src/vnet/tcp/tcp.h
src/vnet/tcp/tcp_cli.c
src/vnet/tcp/tcp_output.c

index 0ceac82..c70a44c 100644 (file)
@@ -1590,6 +1590,7 @@ tcp_configuration_init (void)
   tcp_cfg.lastack_time = 300000;       /* 30s */
   tcp_cfg.finwait2_time = 300000;      /* 30s */
   tcp_cfg.closing_time = 300000;       /* 30s */
+  tcp_cfg.alloc_err_timeout = 1000;    /* 100ms */
 
   /* This value is seconds */
   tcp_cfg.cleanup_time = 0.1;  /* 100ms */
index 2561e43..1e6cf8a 100644 (file)
@@ -184,6 +184,9 @@ typedef struct tcp_configuration_
   /** Timer ticks to wait in closing for fin ack */
   u32 closing_time;
 
+  /** Timer ticks to wait for free buffer */
+  u32 alloc_err_timeout;
+
   /** Time to wait (sec) before cleaning up the connection */
   f32 cleanup_time;
 
index 6d7b7c8..c11b154 100644 (file)
@@ -1118,6 +1118,8 @@ tcp_config_fn (vlib_main_t * vm, unformat_input_t * input)
        tcp_cfg.lastack_time = tmp_time / TCP_TIMER_TICK;
       else if (unformat (input, "closing-time %u", &tmp_time))
        tcp_cfg.closing_time = tmp_time / TCP_TIMER_TICK;
+      else if (unformat (input, "alloc-err-timeout %u", &tmp_time))
+       tcp_cfg.alloc_err_timeout = tmp_time / TCP_TIMER_TICK;
       else if (unformat (input, "cleanup-time %u", &tmp_time))
        tcp_cfg.cleanup_time = tmp_time / 1000.0;
       else
index bde06da..0ba349c 100644 (file)
@@ -820,7 +820,8 @@ tcp_send_syn (tcp_connection_t * tc)
 
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
-      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
+      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN,
+                       tcp_cfg.alloc_err_timeout);
       tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
@@ -852,7 +853,8 @@ tcp_send_synack (tcp_connection_t * tc)
 
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
-      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT,
+                       tcp_cfg.alloc_err_timeout);
       tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }
@@ -884,7 +886,8 @@ tcp_send_fin (tcp_connection_t * tc)
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
       /* Out of buffers so program fin retransmit ASAP */
-      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT,
+                       tcp_cfg.alloc_err_timeout);
       if (fin_snt)
        tc->snd_nxt += 1;
       else
@@ -1374,7 +1377,8 @@ tcp_timer_retransmit_handler (tcp_connection_t * tc)
       n_bytes = tcp_prepare_retransmit_segment (wrk, tc, 0, n_bytes, &b);
       if (!n_bytes)
        {
-         tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+         tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT,
+                           tcp_cfg.alloc_err_timeout);
          return;
        }
 
@@ -1416,7 +1420,8 @@ tcp_timer_retransmit_handler (tcp_connection_t * tc)
 
       if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
        {
-         tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT, 1);
+         tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT,
+                           tcp_cfg.alloc_err_timeout);
          tcp_worker_stats_inc (wrk, no_buffer, 1);
          return;
        }
@@ -1481,7 +1486,8 @@ tcp_timer_retransmit_syn_handler (tcp_connection_t * tc)
 
   if (PREDICT_FALSE (!vlib_buffer_alloc (vm, &bi, 1)))
     {
-      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN, 1);
+      tcp_timer_update (&wrk->timer_wheel, tc, TCP_TIMER_RETRANSMIT_SYN,
+                       tcp_cfg.alloc_err_timeout);
       tcp_worker_stats_inc (wrk, no_buffer, 1);
       return;
     }