Skip to content

Commit e979918

Browse files
Florian Westphaldavem330
authored andcommitted
tcp: make undo_cwnd mandatory for congestion modules
The undo_cwnd fallback in the stack doubles cwnd based on ssthresh, which un-does reno halving behaviour. It seems more appropriate to let congctl algorithms pair .ssthresh and .undo_cwnd properly. Add a 'tcp_reno_undo_cwnd' function and wire it up for all congestion algorithms that used to rely on the fallback. Cc: Eric Dumazet <edumazet@google.com> Cc: Yuchung Cheng <ycheng@google.com> Cc: Neal Cardwell <ncardwell@google.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 85f7e75 commit e979918

File tree

8 files changed

+19
-6
lines changed

8 files changed

+19
-6
lines changed

include/net/tcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,7 @@ u32 tcp_slow_start(struct tcp_sock *tp, u32 acked);
958958
void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked);
959959

960960
u32 tcp_reno_ssthresh(struct sock *sk);
961+
u32 tcp_reno_undo_cwnd(struct sock *sk);
961962
void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked);
962963
extern struct tcp_congestion_ops tcp_reno;
963964

net/ipv4/tcp_cong.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ int tcp_register_congestion_control(struct tcp_congestion_ops *ca)
6868
{
6969
int ret = 0;
7070

71-
/* all algorithms must implement ssthresh and cong_avoid ops */
72-
if (!ca->ssthresh || !(ca->cong_avoid || ca->cong_control)) {
71+
/* all algorithms must implement these */
72+
if (!ca->ssthresh || !ca->undo_cwnd ||
73+
!(ca->cong_avoid || ca->cong_control)) {
7374
pr_err("%s does not implement required ops\n", ca->name);
7475
return -EINVAL;
7576
}
@@ -441,10 +442,19 @@ u32 tcp_reno_ssthresh(struct sock *sk)
441442
}
442443
EXPORT_SYMBOL_GPL(tcp_reno_ssthresh);
443444

445+
u32 tcp_reno_undo_cwnd(struct sock *sk)
446+
{
447+
const struct tcp_sock *tp = tcp_sk(sk);
448+
449+
return max(tp->snd_cwnd, tp->snd_ssthresh << 1);
450+
}
451+
EXPORT_SYMBOL_GPL(tcp_reno_undo_cwnd);
452+
444453
struct tcp_congestion_ops tcp_reno = {
445454
.flags = TCP_CONG_NON_RESTRICTED,
446455
.name = "reno",
447456
.owner = THIS_MODULE,
448457
.ssthresh = tcp_reno_ssthresh,
449458
.cong_avoid = tcp_reno_cong_avoid,
459+
.undo_cwnd = tcp_reno_undo_cwnd,
450460
};

net/ipv4/tcp_dctcp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ static struct tcp_congestion_ops dctcp __read_mostly = {
342342
static struct tcp_congestion_ops dctcp_reno __read_mostly = {
343343
.ssthresh = tcp_reno_ssthresh,
344344
.cong_avoid = tcp_reno_cong_avoid,
345+
.undo_cwnd = tcp_reno_undo_cwnd,
345346
.get_info = dctcp_get_info,
346347
.owner = THIS_MODULE,
347348
.name = "dctcp-reno",

net/ipv4/tcp_hybla.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 acked)
166166
static struct tcp_congestion_ops tcp_hybla __read_mostly = {
167167
.init = hybla_init,
168168
.ssthresh = tcp_reno_ssthresh,
169+
.undo_cwnd = tcp_reno_undo_cwnd,
169170
.cong_avoid = hybla_cong_avoid,
170171
.set_state = hybla_state,
171172

net/ipv4/tcp_input.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,10 +2394,7 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss)
23942394
if (tp->prior_ssthresh) {
23952395
const struct inet_connection_sock *icsk = inet_csk(sk);
23962396

2397-
if (icsk->icsk_ca_ops->undo_cwnd)
2398-
tp->snd_cwnd = icsk->icsk_ca_ops->undo_cwnd(sk);
2399-
else
2400-
tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh << 1);
2397+
tp->snd_cwnd = icsk->icsk_ca_ops->undo_cwnd(sk);
24012398

24022399
if (tp->prior_ssthresh > tp->snd_ssthresh) {
24032400
tp->snd_ssthresh = tp->prior_ssthresh;

net/ipv4/tcp_lp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ static void tcp_lp_pkts_acked(struct sock *sk, const struct ack_sample *sample)
316316
static struct tcp_congestion_ops tcp_lp __read_mostly = {
317317
.init = tcp_lp_init,
318318
.ssthresh = tcp_reno_ssthresh,
319+
.undo_cwnd = tcp_reno_undo_cwnd,
319320
.cong_avoid = tcp_lp_cong_avoid,
320321
.pkts_acked = tcp_lp_pkts_acked,
321322

net/ipv4/tcp_vegas.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ EXPORT_SYMBOL_GPL(tcp_vegas_get_info);
307307
static struct tcp_congestion_ops tcp_vegas __read_mostly = {
308308
.init = tcp_vegas_init,
309309
.ssthresh = tcp_reno_ssthresh,
310+
.undo_cwnd = tcp_reno_undo_cwnd,
310311
.cong_avoid = tcp_vegas_cong_avoid,
311312
.pkts_acked = tcp_vegas_pkts_acked,
312313
.set_state = tcp_vegas_state,

net/ipv4/tcp_westwood.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ static struct tcp_congestion_ops tcp_westwood __read_mostly = {
278278
.init = tcp_westwood_init,
279279
.ssthresh = tcp_reno_ssthresh,
280280
.cong_avoid = tcp_reno_cong_avoid,
281+
.undo_cwnd = tcp_reno_undo_cwnd,
281282
.cwnd_event = tcp_westwood_event,
282283
.in_ack_event = tcp_westwood_ack,
283284
.get_info = tcp_westwood_info,

0 commit comments

Comments
 (0)