Skip to content

Commit 9cd981d

Browse files
nealcardwelldavem330
authored andcommitted
tcp: fix stretch ACK bugs in CUBIC
Change CUBIC to properly handle stretch ACKs in additive increase mode by passing in the count of ACKed packets to tcp_cong_avoid_ai(). In addition, because we are now precisely accounting for stretch ACKs, including delayed ACKs, we can now remove the delayed ACK tracking and estimation code that tracked recent delayed ACK behavior in ca->delayed_ack. Reported-by: Eyal Perry <eyalpe@mellanox.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent c22bdca commit 9cd981d

File tree

1 file changed

+9
-22
lines changed

1 file changed

+9
-22
lines changed

net/ipv4/tcp_cubic.c

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ struct bictcp {
9393
u32 epoch_start; /* beginning of an epoch */
9494
u32 ack_cnt; /* number of acks */
9595
u32 tcp_cwnd; /* estimated tcp cwnd */
96-
#define ACK_RATIO_SHIFT 4
97-
#define ACK_RATIO_LIMIT (32u << ACK_RATIO_SHIFT)
98-
u16 delayed_ack; /* estimate the ratio of Packets/ACKs << 4 */
96+
u16 unused;
9997
u8 sample_cnt; /* number of samples to decide curr_rtt */
10098
u8 found; /* the exit point is found? */
10199
u32 round_start; /* beginning of each round */
@@ -114,7 +112,6 @@ static inline void bictcp_reset(struct bictcp *ca)
114112
ca->bic_K = 0;
115113
ca->delay_min = 0;
116114
ca->epoch_start = 0;
117-
ca->delayed_ack = 2 << ACK_RATIO_SHIFT;
118115
ca->ack_cnt = 0;
119116
ca->tcp_cwnd = 0;
120117
ca->found = 0;
@@ -205,12 +202,12 @@ static u32 cubic_root(u64 a)
205202
/*
206203
* Compute congestion window to use.
207204
*/
208-
static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
205+
static inline void bictcp_update(struct bictcp *ca, u32 cwnd, u32 acked)
209206
{
210207
u32 delta, bic_target, max_cnt;
211208
u64 offs, t;
212209

213-
ca->ack_cnt++; /* count the number of ACKs */
210+
ca->ack_cnt += acked; /* count the number of ACKed packets */
214211

215212
if (ca->last_cwnd == cwnd &&
216213
(s32)(tcp_time_stamp - ca->last_time) <= HZ / 32)
@@ -221,7 +218,7 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
221218

222219
if (ca->epoch_start == 0) {
223220
ca->epoch_start = tcp_time_stamp; /* record beginning */
224-
ca->ack_cnt = 1; /* start counting */
221+
ca->ack_cnt = acked; /* start counting */
225222
ca->tcp_cwnd = cwnd; /* syn with cubic */
226223

227224
if (ca->last_max_cwnd <= cwnd) {
@@ -301,7 +298,6 @@ static inline void bictcp_update(struct bictcp *ca, u32 cwnd)
301298
}
302299
}
303300

304-
ca->cnt = (ca->cnt << ACK_RATIO_SHIFT) / ca->delayed_ack;
305301
if (ca->cnt == 0) /* cannot be zero */
306302
ca->cnt = 1;
307303
}
@@ -317,11 +313,12 @@ static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked)
317313
if (tp->snd_cwnd <= tp->snd_ssthresh) {
318314
if (hystart && after(ack, ca->end_seq))
319315
bictcp_hystart_reset(sk);
320-
tcp_slow_start(tp, acked);
321-
} else {
322-
bictcp_update(ca, tp->snd_cwnd);
323-
tcp_cong_avoid_ai(tp, ca->cnt, 1);
316+
acked = tcp_slow_start(tp, acked);
317+
if (!acked)
318+
return;
324319
}
320+
bictcp_update(ca, tp->snd_cwnd, acked);
321+
tcp_cong_avoid_ai(tp, ca->cnt, acked);
325322
}
326323

327324
static u32 bictcp_recalc_ssthresh(struct sock *sk)
@@ -411,20 +408,10 @@ static void hystart_update(struct sock *sk, u32 delay)
411408
*/
412409
static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
413410
{
414-
const struct inet_connection_sock *icsk = inet_csk(sk);
415411
const struct tcp_sock *tp = tcp_sk(sk);
416412
struct bictcp *ca = inet_csk_ca(sk);
417413
u32 delay;
418414

419-
if (icsk->icsk_ca_state == TCP_CA_Open) {
420-
u32 ratio = ca->delayed_ack;
421-
422-
ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT;
423-
ratio += cnt;
424-
425-
ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT);
426-
}
427-
428415
/* Some calls are for duplicates without timetamps */
429416
if (rtt_us < 0)
430417
return;

0 commit comments

Comments
 (0)