Commit ede656e8 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

tcp_cubic: make Hystart aware of pacing

For years we disabled Hystart ACK train detection at Google
because it was fooled by TCP pacing.

ACK train detection uses a simple heuristic, detecting if
we receive ACK past half the RTT, to exit slow start before
hitting the bottleneck and experience massive drops.

But pacing by design might delay packets up to RTT/2,
so we need to tweak the Hystart logic to be aware of this
extra delay.

Tested:
 Added a 100 usec delay at receiver.

Before:
nstat -n;for f in {1..10}; do ./super_netperf 1 -H lpaa24 -l -4000000; done;nstat|egrep "Hystart"
   9117
   7057
   9553
   8300
   7030
   6849
   9533
  10126
   6876
   8473
TcpExtTCPHystartTrainDetect     10                 0.0
TcpExtTCPHystartTrainCwnd       1230               0.0

After :
nstat -n;for f in {1..10}; do ./super_netperf 1 -H lpaa24 -l -4000000; done;nstat|egrep "Hystart"
   9845
  10103
  10866
  11096
  11936
  11487
  11773
  12188
  11066
  11894
TcpExtTCPHystartTrainDetect     10                 0.0
TcpExtTCPHystartTrainCwnd       6462               0.0

Disabling Hystart ACK Train detection gives similar numbers

echo 2 >/sys/module/tcp_cubic/parameters/hystart_detect
nstat -n;for f in {1..10}; do ./super_netperf 1 -H lpaa24 -l -4000000; done;nstat|egrep "Hystart"
  11173
  10954
  12455
  10627
  11578
  11583
  11222
  10880
  10665
  11366
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarNeal Cardwell <ncardwell@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 42f3a8aa
...@@ -376,6 +376,7 @@ static void hystart_update(struct sock *sk, u32 delay) ...@@ -376,6 +376,7 @@ static void hystart_update(struct sock *sk, u32 delay)
{ {
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
struct bictcp *ca = inet_csk_ca(sk); struct bictcp *ca = inet_csk_ca(sk);
u32 threshold;
if (hystart_detect & HYSTART_ACK_TRAIN) { if (hystart_detect & HYSTART_ACK_TRAIN) {
u32 now = bictcp_clock_us(sk); u32 now = bictcp_clock_us(sk);
...@@ -383,7 +384,17 @@ static void hystart_update(struct sock *sk, u32 delay) ...@@ -383,7 +384,17 @@ static void hystart_update(struct sock *sk, u32 delay)
/* first detection parameter - ack-train detection */ /* first detection parameter - ack-train detection */
if ((s32)(now - ca->last_ack) <= hystart_ack_delta_us) { if ((s32)(now - ca->last_ack) <= hystart_ack_delta_us) {
ca->last_ack = now; ca->last_ack = now;
if ((s32)(now - ca->round_start) > ca->delay_min >> 1) {
threshold = ca->delay_min;
/* Hystart ack train triggers if we get ack past
* ca->delay_min/2.
* Pacing might have delayed packets up to RTT/2
* during slow start.
*/
if (sk->sk_pacing_status == SK_PACING_NONE)
threshold >>= 1;
if ((s32)(now - ca->round_start) > threshold) {
ca->found = 1; ca->found = 1;
NET_INC_STATS(sock_net(sk), NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPHYSTARTTRAINDETECT); LINUX_MIB_TCPHYSTARTTRAINDETECT);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment