tcp: add accessors to read/set tp->snd_cwnd
We had various bugs over the years with code
breaking the assumption that tp->snd_cwnd is greater
than zero.
Lately, syzbot reported the WARN_ON_ONCE(!tp->prior_cwnd) added
in commit 8b8a321ff7 ("tcp: fix zero cwnd in tcp_cwnd_reduction")
can trigger, and without a repro we would have to spend
considerable time finding the bug.
Instead of complaining too late, we want to catch where
and when tp->snd_cwnd is set to an illegal value.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Suggested-by: Yuchung Cheng <ycheng@google.com>
Cc: Neal Cardwell <ncardwell@google.com>
Acked-by: Yuchung Cheng <ycheng@google.com>
Link: https://lore.kernel.org/r/20220405233538.947344-1-eric.dumazet@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
487dc3ca60
commit
4057037535
@@ -146,11 +146,11 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
|
||||
|
||||
rtt = veno->minrtt;
|
||||
|
||||
target_cwnd = (u64)tp->snd_cwnd * veno->basertt;
|
||||
target_cwnd = (u64)tcp_snd_cwnd(tp) * veno->basertt;
|
||||
target_cwnd <<= V_PARAM_SHIFT;
|
||||
do_div(target_cwnd, rtt);
|
||||
|
||||
veno->diff = (tp->snd_cwnd << V_PARAM_SHIFT) - target_cwnd;
|
||||
veno->diff = (tcp_snd_cwnd(tp) << V_PARAM_SHIFT) - target_cwnd;
|
||||
|
||||
if (tcp_in_slow_start(tp)) {
|
||||
/* Slow start. */
|
||||
@@ -164,15 +164,15 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
|
||||
/* In the "non-congestive state", increase cwnd
|
||||
* every rtt.
|
||||
*/
|
||||
tcp_cong_avoid_ai(tp, tp->snd_cwnd, acked);
|
||||
tcp_cong_avoid_ai(tp, tcp_snd_cwnd(tp), acked);
|
||||
} else {
|
||||
/* In the "congestive state", increase cwnd
|
||||
* every other rtt.
|
||||
*/
|
||||
if (tp->snd_cwnd_cnt >= tp->snd_cwnd) {
|
||||
if (tp->snd_cwnd_cnt >= tcp_snd_cwnd(tp)) {
|
||||
if (veno->inc &&
|
||||
tp->snd_cwnd < tp->snd_cwnd_clamp) {
|
||||
tp->snd_cwnd++;
|
||||
tcp_snd_cwnd(tp) < tp->snd_cwnd_clamp) {
|
||||
tcp_snd_cwnd_set(tp, tcp_snd_cwnd(tp) + 1);
|
||||
veno->inc = 0;
|
||||
} else
|
||||
veno->inc = 1;
|
||||
@@ -181,10 +181,10 @@ static void tcp_veno_cong_avoid(struct sock *sk, u32 ack, u32 acked)
|
||||
tp->snd_cwnd_cnt += acked;
|
||||
}
|
||||
done:
|
||||
if (tp->snd_cwnd < 2)
|
||||
tp->snd_cwnd = 2;
|
||||
else if (tp->snd_cwnd > tp->snd_cwnd_clamp)
|
||||
tp->snd_cwnd = tp->snd_cwnd_clamp;
|
||||
if (tcp_snd_cwnd(tp) < 2)
|
||||
tcp_snd_cwnd_set(tp, 2);
|
||||
else if (tcp_snd_cwnd(tp) > tp->snd_cwnd_clamp)
|
||||
tcp_snd_cwnd_set(tp, tp->snd_cwnd_clamp);
|
||||
}
|
||||
/* Wipe the slate clean for the next rtt. */
|
||||
/* veno->cntrtt = 0; */
|
||||
@@ -199,10 +199,10 @@ static u32 tcp_veno_ssthresh(struct sock *sk)
|
||||
|
||||
if (veno->diff < beta)
|
||||
/* in "non-congestive state", cut cwnd by 1/5 */
|
||||
return max(tp->snd_cwnd * 4 / 5, 2U);
|
||||
return max(tcp_snd_cwnd(tp) * 4 / 5, 2U);
|
||||
else
|
||||
/* in "congestive state", cut cwnd by 1/2 */
|
||||
return max(tp->snd_cwnd >> 1U, 2U);
|
||||
return max(tcp_snd_cwnd(tp) >> 1U, 2U);
|
||||
}
|
||||
|
||||
static struct tcp_congestion_ops tcp_veno __read_mostly = {
|
||||
|
||||
Reference in New Issue
Block a user