Lines Matching +full:no +full:- +full:idle +full:- +full:on +full:- +full:init
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2008-2010 Lawrence Stewart <lstewart@freebsd.org>
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * based on the Internet Draft "draft-rhee-tcpm-cubic-02" by Rhee, Xu and Ha.
111 * 1 - rtt_thresh in flex1, checking to see if RTT is to great.
112 * 2 - rtt is too great, rtt_thresh in flex1.
113 * 3 - CSS is active incr in flex1
114 * 4 - A new round is beginning flex1 is round count
115 * 5 - A new RTT measurement flex1 is the new measurement.
116 * 6 - We enter CA ssthresh is also in flex1.
117 * 7 - Socket option to change hystart executed opt.val in flex1.
118 * 8 - Back out of CSS into SS, flex1 is the css_baseline_minrtt
119 * 9 - We enter CA, via an ECN mark.
120 * 10 - We enter CA, via a loss.
121 * 11 - We have slipped out of SS into CA via cwnd growth.
122 * 12 - After idle has re-enabled hystart++
128 tp = ccv->tp;
135 log.u_bbr.flex2 = cubicd->css_current_round_minrtt;
136 log.u_bbr.flex3 = cubicd->css_lastround_minrtt;
137 log.u_bbr.flex4 = cubicd->css_rttsample_count;
138 log.u_bbr.flex5 = cubicd->css_entered_at_round;
139 log.u_bbr.flex6 = cubicd->css_baseline_minrtt;
141 log.u_bbr.flex7 = cubicd->flags & 0x0000ffff;
143 log.u_bbr.epoch = cubicd->css_current_round;
145 log.u_bbr.lt_epoch = cubicd->css_fas_at_css_entry;
146 log.u_bbr.pkts_out = cubicd->css_last_fas;
147 log.u_bbr.delivered = cubicd->css_lowrtt_fas;
148 log.u_bbr.pkt_epoch = ccv->flags;
150 &tptosocket(tp)->so_rcv,
151 &tptosocket(tp)->so_snd,
161 * In slow-start with ABC enabled and no RTO in sight?
163 * an RTO. On RTO, snd_nxt = snd_una, so the
168 * doesn't rely on tcpcb vars.
171 uint32_t mss = tcp_fixed_maxseg(ccv->tp);
175 cubicd->flags |= CUBICFLAG_IN_SLOWSTART;
176 if (ccv->flags & CCF_USE_LOCAL_ABC)
177 abc_val = ccv->labc;
180 if ((ccv->flags & CCF_HYSTART_ALLOWED) &&
181 (cubicd->flags & CUBICFLAG_HYSTART_ENABLED) &&
182 ((cubicd->flags & CUBICFLAG_HYSTART_IN_CSS) == 0)) {
185 * in CSS. Lets check to see if we can make a decision on
188 if ((cubicd->css_rttsample_count >= hystart_n_rttsamples) &&
189 (cubicd->css_current_round_minrtt != 0xffffffff) &&
190 (cubicd->css_lastround_minrtt != 0xffffffff)) {
194 rtt_thresh = (cubicd->css_lastround_minrtt >> 3);
201 if (cubicd->css_current_round_minrtt >= (cubicd->css_lastround_minrtt + rtt_thresh)) {
203 cubicd->flags |= CUBICFLAG_HYSTART_IN_CSS;
204 cubicd->css_fas_at_css_entry = cubicd->css_lowrtt_fas;
209 * issues on exiting early. We will leave the draft version for now
212 cubicd->css_baseline_minrtt = cubicd->css_current_round_minrtt;
213 cubicd->css_entered_at_round = cubicd->css_current_round;
219 incr = min(ccv->bytes_this_ack,
220 ccv->nsegs * abc_val * mss);
222 incr = min(ccv->bytes_this_ack, mss);
225 if (cubicd->flags & CUBICFLAG_HYSTART_IN_CSS) {
229 /* ABC is on by default, so incr equals 0 frequently. */
241 uint32_t mss = tcp_fixed_maxseg(ccv->tp);
243 cubic_data = ccv->cc_data;
251 (ccv->flags & CCF_CWND_LIMITED)) {
254 cubic_data->min_rtt_usecs == TCPTV_SRTTBASE) {
257 if (cubic_data->flags & CUBICFLAG_HYSTART_IN_CSS) {
263 cubic_data->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
264 /* Disable use of CSS in the future except long idle */
265 cubic_data->flags &= ~CUBICFLAG_HYSTART_ENABLED;
268 if ((cubic_data->flags & CUBICFLAG_RTO_EVENT) &&
269 (cubic_data->flags & CUBICFLAG_IN_SLOWSTART)) {
271 cubic_data->flags &= ~(CUBICFLAG_RTO_EVENT |
273 cubic_data->W_max = CCV(ccv, snd_cwnd);
274 cubic_data->t_epoch = ticks;
275 cubic_data->K = 0;
276 } else if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART |
278 cubic_data->flags &= ~(CUBICFLAG_IN_SLOWSTART |
280 cubic_data->t_epoch = ticks;
281 cubic_data->K = cubic_k(cubic_data->W_max / mss);
283 usecs_since_epoch = (ticks - cubic_data->t_epoch) * tick;
289 cubic_data->t_epoch = ticks - INT_MAX;
296 * the I-D.
299 cubic_data->mean_rtt_usecs,
300 cubic_data->W_max,
301 tcp_fixed_maxseg(ccv->tp),
302 cubic_data->K);
306 * TCP-friendly region, follow tf
310 cubic_data->flags |= CUBICFLAG_IN_TF;
318 cubic_data->flags &= ~CUBICFLAG_IN_TF;
328 if (((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) &&
329 cubic_data->W_max < CCV(ccv, snd_cwnd)) {
330 cubic_data->W_max = CCV(ccv, snd_cwnd);
331 cubic_data->K = cubic_k(cubic_data->W_max /
332 tcp_fixed_maxseg(ccv->tp));
336 !(ccv->flags & CCF_CWND_LIMITED)) {
337 cubic_data->flags |= CUBICFLAG_IN_APPLIMIT;
343 * - Reset cwnd by calling New Reno implementation of after_idle.
344 * - Reset t_epoch.
351 cubic_data = ccv->cc_data;
353 cubic_data->W_max = ulmax(cubic_data->W_max, CCV(ccv, snd_cwnd));
354 cubic_data->K = cubic_k(cubic_data->W_max / tcp_fixed_maxseg(ccv->tp));
355 if ((cubic_data->flags & CUBICFLAG_HYSTART_ENABLED) == 0) {
357 * Re-enable hystart if we have been idle.
359 cubic_data->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
360 cubic_data->flags |= CUBICFLAG_HYSTART_ENABLED;
364 cubic_data->t_epoch = ticks;
370 free(ccv->cc_data, M_CC_MEM);
384 INP_WLOCK_ASSERT(tptoinpcb(ccv->tp));
392 /* Init some key variables with sensible defaults. */
393 cubic_data->t_epoch = ticks;
394 cubic_data->min_rtt_usecs = TCPTV_SRTTBASE;
395 cubic_data->mean_rtt_usecs = 1;
397 ccv->cc_data = cubic_data;
398 cubic_data->flags = CUBICFLAG_HYSTART_ENABLED;
399 /* At init set both to infinity */
400 cubic_data->css_lastround_minrtt = 0xffffffff;
401 cubic_data->css_current_round_minrtt = 0xffffffff;
402 cubic_data->css_current_round = 0;
403 cubic_data->css_baseline_minrtt = 0xffffffff;
404 cubic_data->css_rttsample_count = 0;
405 cubic_data->css_entered_at_round = 0;
406 cubic_data->css_fas_at_css_entry = 0;
407 cubic_data->css_lowrtt_fas = 0;
408 cubic_data->css_last_fas = 0;
422 cubic_data = ccv->cc_data;
423 mss = tcp_fixed_maxseg(ccv->tp);
427 if (cubic_data->flags & CUBICFLAG_HYSTART_ENABLED) {
429 cubic_data->flags &= ~CUBICFLAG_HYSTART_ENABLED;
430 cubic_data->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
436 cubic_data->flags |= CUBICFLAG_CONG_EVENT;
437 cubic_data->t_epoch = ticks;
438 cubic_data->K = cubic_k(cubic_data->W_max / mss);
445 if (cubic_data->flags & CUBICFLAG_HYSTART_ENABLED) {
447 cubic_data->flags &= ~CUBICFLAG_HYSTART_ENABLED;
448 cubic_data->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
453 cubic_data->flags |= CUBICFLAG_CONG_EVENT;
454 cubic_data->t_epoch = ticks;
455 cubic_data->K = cubic_k(cubic_data->W_max / mss);
470 cubic_data->undo_t_epoch = cubic_data->t_epoch;
471 cubic_data->undo_cwnd_epoch = cubic_data->cwnd_epoch;
472 cubic_data->undo_W_est = cubic_data->W_est;
473 cubic_data->undo_cwnd_prior = cubic_data->cwnd_prior;
474 cubic_data->undo_W_max = cubic_data->W_max;
475 cubic_data->undo_K = cubic_data->K;
477 pipe = tcp_compute_pipe(ccv->tp);
479 pipe = CCV(ccv, snd_max) -
487 cubic_data->flags |= CUBICFLAG_CONG_EVENT | CUBICFLAG_RTO_EVENT;
488 cubic_data->undo_W_max = cubic_data->W_max;
493 cubic_data->flags &= ~(CUBICFLAG_CONG_EVENT | CUBICFLAG_RTO_EVENT);
494 cubic_data->K = cubic_data->undo_K;
495 cubic_data->cwnd_prior = cubic_data->undo_cwnd_prior;
496 cubic_data->W_max = cubic_data->undo_W_max;
497 cubic_data->W_est = cubic_data->undo_W_est;
498 cubic_data->cwnd_epoch = cubic_data->undo_cwnd_epoch;
499 cubic_data->t_epoch = cubic_data->undo_t_epoch;
511 cubic_data = ccv->cc_data;
518 cubic_data->W_max = CCV(ccv, snd_cwnd);
535 uint32_t mss = tcp_fixed_maxseg(ccv->tp);
537 cubic_data = ccv->cc_data;
549 pipe = tcp_compute_pipe(ccv->tp);
551 pipe = CCV(ccv, snd_max) - ccv->curack;
560 /* Update cwnd based on beta and adjusted W_max. */
561 CCV(ccv, snd_cwnd) = max(((uint64_t)cubic_data->W_max *
567 if (cubic_data->epoch_ack_count > 0 &&
568 cubic_data->sum_rtt_usecs >= cubic_data->epoch_ack_count) {
569 cubic_data->mean_rtt_usecs = (int)(cubic_data->sum_rtt_usecs /
570 cubic_data->epoch_ack_count);
573 cubic_data->epoch_ack_count = 0;
574 cubic_data->sum_rtt_usecs = 0;
588 cubic_data = ccv->cc_data;
589 t_srtt_usecs = tcp_get_srtt(ccv->tp,
598 if ((t_srtt_usecs < cubic_data->min_rtt_usecs ||
599 cubic_data->min_rtt_usecs == TCPTV_SRTTBASE)) {
602 cubic_data->min_rtt_usecs = max(tick >> TCP_RTT_SHIFT,
611 if (cubic_data->min_rtt_usecs >
612 cubic_data->mean_rtt_usecs)
613 cubic_data->mean_rtt_usecs =
614 cubic_data->min_rtt_usecs;
618 cubic_data->sum_rtt_usecs += t_srtt_usecs;
619 cubic_data->epoch_ack_count++;
633 cubic_data = ccv->cc_data;
637 if (cwnd < cubic_data->W_max) {
640 cubic_data->undo_W_max = cubic_data->W_max;
641 cubic_data->W_max = cwnd;
643 if (cubic_data->flags & CUBICFLAG_IN_TF) {
647 } else if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) {
649 * On the first congestion event, set ssthresh to cwnd * 0.5
654 cubic_data->W_max = ((uint64_t)cwnd * CUBIC_BETA) >> CUBIC_SHIFT;
657 * On subsequent congestion events, set ssthresh to cwnd * beta.
669 cubicd = ccv->cc_data;
672 * Only look at RTT's that are non-ambiguous.
676 cubicd->css_rttsample_count++;
677 cubicd->css_last_fas = fas;
678 if (cubicd->css_current_round_minrtt > usec_rtt) {
679 cubicd->css_current_round_minrtt = usec_rtt;
680 cubicd->css_lowrtt_fas = cubicd->css_last_fas;
682 if ((cubicd->css_rttsample_count >= hystart_n_rttsamples) &&
683 (cubicd->css_current_round_minrtt != 0xffffffff) &&
684 (cubicd->css_current_round_minrtt < cubicd->css_baseline_minrtt) &&
685 (cubicd->css_lastround_minrtt != 0xffffffff)) {
690 cubicd->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
691 cubic_log_hystart_event(ccv, cubicd, 8, cubicd->css_baseline_minrtt);
692 cubicd->css_baseline_minrtt = 0xffffffff;
694 if (cubicd->flags & CUBICFLAG_HYSTART_ENABLED)
703 cubicd = ccv->cc_data;
705 cubicd->css_lastround_minrtt = cubicd->css_current_round_minrtt;
706 cubicd->css_current_round_minrtt = 0xffffffff;
707 cubicd->css_rttsample_count = 0;
708 cubicd->css_current_round = round_cnt;
709 if ((cubicd->flags & CUBICFLAG_HYSTART_IN_CSS) &&
710 ((round_cnt - cubicd->css_entered_at_round) >= hystart_css_rounds)) {
712 if (ccv->flags & CCF_HYSTART_CAN_SH_CWND) {
719 if (ccv->flags & CCF_HYSTART_CONS_SSTH) {
720 CCV(ccv, snd_ssthresh) = ((cubicd->css_lowrtt_fas + cubicd->css_fas_at_css_entry) / 2);
722 CCV(ccv, snd_ssthresh) = cubicd->css_lowrtt_fas;
724 CCV(ccv, snd_cwnd) = cubicd->css_fas_at_css_entry;
725 cubicd->css_entered_at_round = round_cnt;
729 cubicd->flags &= ~CUBICFLAG_HYSTART_IN_CSS;
730 /* Disable use of CSS in the future except long idle */
731 cubicd->flags &= ~CUBICFLAG_HYSTART_ENABLED;
735 if (cubicd->flags & CUBICFLAG_HYSTART_ENABLED)