| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * YeAH TCP |
|---|
| .. | .. |
|---|
| 35 | 36 | |
|---|
| 36 | 37 | u32 reno_count; |
|---|
| 37 | 38 | u32 fast_count; |
|---|
| 38 | | - |
|---|
| 39 | | - u32 pkts_acked; |
|---|
| 40 | 39 | }; |
|---|
| 41 | 40 | |
|---|
| 42 | 41 | static void tcp_yeah_init(struct sock *sk) |
|---|
| .. | .. |
|---|
| 56 | 55 | tp->snd_cwnd_clamp = min_t(u32, tp->snd_cwnd_clamp, 0xffffffff/128); |
|---|
| 57 | 56 | } |
|---|
| 58 | 57 | |
|---|
| 59 | | -static void tcp_yeah_pkts_acked(struct sock *sk, |
|---|
| 60 | | - const struct ack_sample *sample) |
|---|
| 61 | | -{ |
|---|
| 62 | | - const struct inet_connection_sock *icsk = inet_csk(sk); |
|---|
| 63 | | - struct yeah *yeah = inet_csk_ca(sk); |
|---|
| 64 | | - |
|---|
| 65 | | - if (icsk->icsk_ca_state == TCP_CA_Open) |
|---|
| 66 | | - yeah->pkts_acked = sample->pkts_acked; |
|---|
| 67 | | - |
|---|
| 68 | | - tcp_vegas_pkts_acked(sk, sample); |
|---|
| 69 | | -} |
|---|
| 70 | | - |
|---|
| 71 | 58 | static void tcp_yeah_cong_avoid(struct sock *sk, u32 ack, u32 acked) |
|---|
| 72 | 59 | { |
|---|
| 73 | 60 | struct tcp_sock *tp = tcp_sk(sk); |
|---|
| .. | .. |
|---|
| 76 | 63 | if (!tcp_is_cwnd_limited(sk)) |
|---|
| 77 | 64 | return; |
|---|
| 78 | 65 | |
|---|
| 79 | | - if (tcp_in_slow_start(tp)) |
|---|
| 80 | | - tcp_slow_start(tp, acked); |
|---|
| 66 | + if (tcp_in_slow_start(tp)) { |
|---|
| 67 | + acked = tcp_slow_start(tp, acked); |
|---|
| 68 | + if (!acked) |
|---|
| 69 | + goto do_vegas; |
|---|
| 70 | + } |
|---|
| 81 | 71 | |
|---|
| 82 | | - else if (!yeah->doing_reno_now) { |
|---|
| 72 | + if (!yeah->doing_reno_now) { |
|---|
| 83 | 73 | /* Scalable */ |
|---|
| 84 | | - |
|---|
| 85 | | - tp->snd_cwnd_cnt += yeah->pkts_acked; |
|---|
| 86 | | - if (tp->snd_cwnd_cnt > min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT)) { |
|---|
| 87 | | - if (tp->snd_cwnd < tp->snd_cwnd_clamp) |
|---|
| 88 | | - tp->snd_cwnd++; |
|---|
| 89 | | - tp->snd_cwnd_cnt = 0; |
|---|
| 90 | | - } |
|---|
| 91 | | - |
|---|
| 92 | | - yeah->pkts_acked = 1; |
|---|
| 93 | | - |
|---|
| 74 | + tcp_cong_avoid_ai(tp, min(tp->snd_cwnd, TCP_SCALABLE_AI_CNT), |
|---|
| 75 | + acked); |
|---|
| 94 | 76 | } else { |
|---|
| 95 | 77 | /* Reno */ |
|---|
| 96 | | - tcp_cong_avoid_ai(tp, tp->snd_cwnd, 1); |
|---|
| 78 | + tcp_cong_avoid_ai(tp, tp->snd_cwnd, acked); |
|---|
| 97 | 79 | } |
|---|
| 98 | 80 | |
|---|
| 99 | 81 | /* The key players are v_vegas.beg_snd_una and v_beg_snd_nxt. |
|---|
| .. | .. |
|---|
| 117 | 99 | * of bytes we send in an RTT is often less than our cwnd will allow. |
|---|
| 118 | 100 | * So we keep track of our cwnd separately, in v_beg_snd_cwnd. |
|---|
| 119 | 101 | */ |
|---|
| 120 | | - |
|---|
| 102 | +do_vegas: |
|---|
| 121 | 103 | if (after(ack, yeah->vegas.beg_snd_nxt)) { |
|---|
| 122 | 104 | /* We do the Vegas calculations only if we got enough RTT |
|---|
| 123 | 105 | * samples that we can be reasonably sure that we got |
|---|
| .. | .. |
|---|
| 231 | 213 | .set_state = tcp_vegas_state, |
|---|
| 232 | 214 | .cwnd_event = tcp_vegas_cwnd_event, |
|---|
| 233 | 215 | .get_info = tcp_vegas_get_info, |
|---|
| 234 | | - .pkts_acked = tcp_yeah_pkts_acked, |
|---|
| 216 | + .pkts_acked = tcp_vegas_pkts_acked, |
|---|
| 235 | 217 | |
|---|
| 236 | 218 | .owner = THIS_MODULE, |
|---|
| 237 | 219 | .name = "yeah", |
|---|