From 7e78119c257579731c8902556b4a197c3fc3e92e Mon Sep 17 00:00:00 2001 From: liuyacan Date: Mon, 14 Jun 2021 18:09:01 +0800 Subject: [PATCH] tcp: prevent timer handler being called frequently 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 Change-Id: Ia11d693fe46119c5dc16b24ca93c30c31109057a --- src/vnet/tcp/tcp.c | 1 + src/vnet/tcp/tcp.h | 3 +++ src/vnet/tcp/tcp_cli.c | 2 ++ src/vnet/tcp/tcp_output.c | 18 ++++++++++++------ 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index 0ceac828d2d..c70a44cae90 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -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 */ diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index 2561e439794..1e6cf8a9ae8 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -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; diff --git a/src/vnet/tcp/tcp_cli.c b/src/vnet/tcp/tcp_cli.c index 6d7b7c8ce40..c11b154cebf 100644 --- a/src/vnet/tcp/tcp_cli.c +++ b/src/vnet/tcp/tcp_cli.c @@ -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 diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index bde06da87ed..0ba349c2a62 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -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; } -- 2.16.6