|
52 | 52 | enum bbr_pacing_gain_phase { |
53 | 53 | BBR_BW_PROBE_UP = 0, /* push up inflight to probe for bw/vol */ |
54 | 54 | @@ -235,26 +235,30 @@ |
55 | | - BBR_BW_PROBE_REFILL = 3, /* v2: refill the pipe again to 100% */ |
| 55 | + BBR_BW_PROBE_REFILL = 3, /* refill the pipe again to 100% */ |
56 | 56 | }; |
57 | 57 |
|
58 | 58 | +/* Avoid over pacing when app-limited in STARTUP, but still try to probe for more bandwidth. |
|
185 | 185 |
|
186 | 186 | /* Use fast path if app-limited, no loss/ECN, and target cwnd was reached? */ |
187 | 187 | static const bool bbr_fast_path = true; |
188 | | -@@ -466,10 +470,17 @@ |
| 188 | +@@ -469,10 +473,17 @@ |
189 | 189 | struct bbr *bbr = inet_csk_ca(sk); |
190 | 190 | unsigned long rate = bbr_bw_to_pacing_rate(sk, bw, gain); |
191 | 191 |
|
|
204 | 204 | } |
205 | 205 |
|
206 | 206 | /* Return the number of segments BBR would like in a TSO/GSO skb, given a |
207 | | -@@ -590,6 +601,26 @@ |
| 207 | +@@ -576,6 +587,7 @@ |
| 208 | + struct bbr *bbr = inet_csk_ca(sk); |
| 209 | + u32 bdp; |
| 210 | + u64 w; |
| 211 | ++ u32 minrtt = bbr->min_rtt_us; |
| 212 | + |
| 213 | + /* If we've never had a valid RTT sample, cap cwnd at the initial |
| 214 | + * default. This should only happen when the connection is not using TCP |
| 215 | +@@ -583,16 +595,36 @@ |
| 216 | + * ACKed so far. In this case, an RTO can cut cwnd to 1, in which |
| 217 | + * case we need to slow-start up toward something safe: initial cwnd. |
| 218 | + */ |
| 219 | +- if (unlikely(bbr->min_rtt_us == ~0U)) /* no valid RTT samples yet? */ |
| 220 | ++ if (unlikely(minrtt == ~0U)) /* no valid RTT samples yet? */ |
| 221 | + return bbr->init_cwnd; /* be safe: cap at initial cwnd */ |
| 222 | + |
| 223 | +- w = (u64)bw * bbr->min_rtt_us; |
| 224 | ++ w = (u64)bw * minrtt; |
| 225 | + |
| 226 | + /* Apply a gain to the given value, remove the BW_SCALE shift, and |
| 227 | + * round the value up to avoid a negative feedback loop. |
208 | 228 | */ |
209 | 229 | bdp = (((w * gain) >> BBR_SCALE) + BW_UNIT - 1) / BW_UNIT; |
210 | 230 |
|
211 | | -+ if(bbr->min_rtt_us >= 180 * USEC_PER_MSEC) { |
| 231 | ++ if(minrtt >= 180 * USEC_PER_MSEC) { |
212 | 232 | + bdp += 8; |
213 | 233 | + bdp += bw >= 44738 ? 6 : 3; |
214 | | -+ } else if(bbr->min_rtt_us >= 140 * USEC_PER_MSEC) { |
| 234 | ++ } else if(minrtt >= 140 * USEC_PER_MSEC) { |
215 | 235 | + bdp += 6; |
216 | 236 | + bdp += bw >= 44738 ? 5 : 2; |
217 | | -+ } else if(bbr->min_rtt_us >= 90 * USEC_PER_MSEC) { |
| 237 | ++ } else if(minrtt >= 90 * USEC_PER_MSEC) { |
218 | 238 | + bdp += 5; |
219 | 239 | + bdp += bw >= 44738 ? 4 : 1; |
220 | | -+ } else if(bbr->min_rtt_us >= 31 * USEC_PER_MSEC) { |
| 240 | ++ } else if(minrtt >= 31 * USEC_PER_MSEC) { |
221 | 241 | + bdp += 4; |
222 | 242 | + bdp += bw >= 44738 ? 3 : 1; |
223 | | -+ } else if(bbr->min_rtt_us >= 16 * USEC_PER_MSEC) { |
| 243 | ++ } else if(minrtt >= 16 * USEC_PER_MSEC) { |
224 | 244 | + bdp += 2; |
225 | 245 | + bdp += bw >= 44738 ? 2 : 0; |
226 | | -+ } else if(bbr->min_rtt_us >= 6 * USEC_PER_MSEC) { |
| 246 | ++ } else if(minrtt >= 6 * USEC_PER_MSEC) { |
227 | 247 | + bdp += 1; |
228 | 248 | + bdp += bw >= 44738 ? 1 : 0; |
229 | 249 | + } |
230 | 250 | + |
231 | 251 | return bdp; |
232 | 252 | } |
233 | 253 |
|
234 | | -@@ -712,18 +743,27 @@ |
| 254 | +@@ -715,18 +747,27 @@ |
235 | 255 | /* Update cwnd and enable fast path if cwnd reaches target_cwnd. */ |
236 | 256 | bbr->try_fast_path = 0; |
237 | 257 | if (bbr_full_bw_reached(sk)) { /* only cut cwnd if we filled the pipe */ |
|
261 | 281 | done: |
262 | 282 | tcp_snd_cwnd_set(tp, min(cwnd, tp->snd_cwnd_clamp)); /* global cap */ |
263 | 283 | if (bbr->mode == BBR_PROBE_RTT) /* drain queue, refresh min_rtt */ |
264 | | -@@ -942,10 +982,11 @@ |
| 284 | +@@ -945,10 +986,11 @@ |
265 | 285 | static void bbr_update_gains(struct sock *sk) |
266 | 286 | { |
267 | 287 | struct bbr *bbr = inet_csk_ca(sk); |
|
270 | 290 | switch (bbr->mode) { |
271 | 291 | case BBR_STARTUP: |
272 | 292 | - bbr->pacing_gain = bbr_param(sk, startup_pacing_gain); |
273 | | -+ bbr->pacing_gain = READ_ONCE(tp->app_limited) ? bbr_param(sk, limited_pacing_gain) : bbr_param(sk, startup_pacing_gain); |
| 293 | ++ bbr->pacing_gain = tp->app_limited ? bbr_param(sk, limited_pacing_gain) : bbr_param(sk, startup_pacing_gain); |
274 | 294 | bbr->cwnd_gain = bbr_param(sk, startup_cwnd_gain); |
275 | 295 | break; |
276 | 296 | case BBR_DRAIN: |
277 | | -@@ -1078,8 +1119,8 @@ |
| 297 | +@@ -1081,8 +1123,8 @@ |
278 | 298 | /* See if we should use ECN sender logic for this connection. */ |
279 | 299 | if (!bbr->ecn_eligible && bbr_can_use_ecn(sk) && |
280 | 300 | !!bbr_param(sk, ecn_factor) && |
|
0 commit comments