Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/cc/cc_newreno.c
| Show First 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | struct cc_algo newreno_cc_algo = { | ||||
| .post_recovery = newreno_cc_post_recovery, | .post_recovery = newreno_cc_post_recovery, | ||||
| .ctl_output = newreno_ctl_output, | .ctl_output = newreno_ctl_output, | ||||
| .newround = newreno_newround, | .newround = newreno_newround, | ||||
| .rttsample = newreno_rttsample, | .rttsample = newreno_rttsample, | ||||
| .cb_init = newreno_cb_init, | .cb_init = newreno_cb_init, | ||||
| .cc_data_sz = newreno_data_sz, | .cc_data_sz = newreno_data_sz, | ||||
| }; | }; | ||||
| static uint32_t hystart_lowcwnd = 16; | |||||
| static uint32_t hystart_minrtt_thresh = 4000; | |||||
| static uint32_t hystart_maxrtt_thresh = 16000; | |||||
| static uint32_t hystart_n_rttsamples = 8; | |||||
| static uint32_t hystart_css_growth_div = 4; | |||||
| static uint32_t hystart_css_rounds = 5; | |||||
| static uint32_t hystart_bblogs = 0; | |||||
| static void | static void | ||||
| newreno_log_hystart_event(struct cc_var *ccv, struct newreno *nreno, uint8_t mod, uint32_t flex1) | newreno_log_hystart_event(struct cc_var *ccv, struct newreno *nreno, uint8_t mod, uint32_t flex1) | ||||
| { | { | ||||
| /* | /* | ||||
| * Types of logs (mod value) | * Types of logs (mod value) | ||||
| * 1 - rtt_thresh in flex1, checking to see if RTT is to great. | * 1 - rtt_thresh in flex1, checking to see if RTT is to great. | ||||
| * 2 - rtt is too great, rtt_thresh in flex1. | * 2 - rtt is too great, rtt_thresh in flex1. | ||||
| * 3 - CSS is active incr in flex1 | * 3 - CSS is active incr in flex1 | ||||
| * 4 - A new round is beginning flex1 is round count | * 4 - A new round is beginning flex1 is round count | ||||
| * 5 - A new RTT measurement flex1 is the new measurement. | * 5 - A new RTT measurement flex1 is the new measurement. | ||||
| * 6 - We enter CA ssthresh is also in flex1. | * 6 - We enter CA ssthresh is also in flex1. | ||||
| * 7 - Socket option to change hystart executed opt.val in flex1. | * 7 - Socket option to change hystart executed opt.val in flex1. | ||||
| * 8 - Back out of CSS into SS, flex1 is the css_baseline_minrtt | * 8 - Back out of CSS into SS, flex1 is the css_baseline_minrtt | ||||
| * 9 - We enter CA, via an ECN mark. | |||||
| * 10 - We enter CA, via a loss. | |||||
| * 11 - We have slipped out of SS into CA via cwnd growth. | |||||
| * 12 - After idle has re-enabled hystart++ | |||||
| */ | */ | ||||
| struct tcpcb *tp; | struct tcpcb *tp; | ||||
| if (hystart_bblogs == 0) | if (hystart_bblogs == 0) | ||||
| return; | return; | ||||
| tp = ccv->ccvc.tcp; | tp = ccv->ccvc.tcp; | ||||
| if (tp->t_logstate != TCP_LOG_STATE_OFF) { | if (tp->t_logstate != TCP_LOG_STATE_OFF) { | ||||
| union tcp_log_stackspecific log; | union tcp_log_stackspecific log; | ||||
| Show All 9 Lines | if (tp->t_logstate != TCP_LOG_STATE_OFF) { | ||||
| /* We only need bottom 16 bits of flags */ | /* We only need bottom 16 bits of flags */ | ||||
| log.u_bbr.flex7 = nreno->newreno_flags & 0x0000ffff; | log.u_bbr.flex7 = nreno->newreno_flags & 0x0000ffff; | ||||
| log.u_bbr.flex8 = mod; | log.u_bbr.flex8 = mod; | ||||
| log.u_bbr.epoch = nreno->css_current_round; | log.u_bbr.epoch = nreno->css_current_round; | ||||
| log.u_bbr.timeStamp = tcp_get_usecs(&tv); | log.u_bbr.timeStamp = tcp_get_usecs(&tv); | ||||
| log.u_bbr.lt_epoch = nreno->css_fas_at_css_entry; | log.u_bbr.lt_epoch = nreno->css_fas_at_css_entry; | ||||
| log.u_bbr.pkts_out = nreno->css_last_fas; | log.u_bbr.pkts_out = nreno->css_last_fas; | ||||
| log.u_bbr.delivered = nreno->css_lowrtt_fas; | log.u_bbr.delivered = nreno->css_lowrtt_fas; | ||||
| log.u_bbr.pkt_epoch = ccv->flags; | |||||
| TCP_LOG_EVENTP(tp, NULL, | TCP_LOG_EVENTP(tp, NULL, | ||||
| &tp->t_inpcb->inp_socket->so_rcv, | &tp->t_inpcb->inp_socket->so_rcv, | ||||
| &tp->t_inpcb->inp_socket->so_snd, | &tp->t_inpcb->inp_socket->so_snd, | ||||
| TCP_HYSTART, 0, | TCP_HYSTART, 0, | ||||
| 0, &log, false, &tv); | 0, &log, false, &tv); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | if (cw > CCV(ccv, snd_ssthresh)) { | ||||
| /* | /* | ||||
| * We have slipped into CA with | * We have slipped into CA with | ||||
| * CSS active. Deactivate all. | * CSS active. Deactivate all. | ||||
| */ | */ | ||||
| /* Turn off the CSS flag */ | /* Turn off the CSS flag */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| /* Disable use of CSS in the future except long idle */ | /* Disable use of CSS in the future except long idle */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | ||||
| newreno_log_hystart_event(ccv, nreno, 11, CCV(ccv, snd_ssthresh)); | |||||
| } | } | ||||
| if (V_tcp_do_rfc3465) { | if (V_tcp_do_rfc3465) { | ||||
| if (ccv->flags & CCF_ABC_SENTAWND) | if (ccv->flags & CCF_ABC_SENTAWND) | ||||
| ccv->flags &= ~CCF_ABC_SENTAWND; | ccv->flags &= ~CCF_ABC_SENTAWND; | ||||
| else | else | ||||
| incr = 0; | incr = 0; | ||||
| } else | } else | ||||
| incr = max((incr * incr / cw), 1); | incr = max((incr * incr / cw), 1); | ||||
| Show All 9 Lines | if (cw > CCV(ccv, snd_ssthresh)) { | ||||
| * doesn't rely on tcpcb vars. | * doesn't rely on tcpcb vars. | ||||
| */ | */ | ||||
| uint16_t abc_val; | uint16_t abc_val; | ||||
| if (ccv->flags & CCF_USE_LOCAL_ABC) | if (ccv->flags & CCF_USE_LOCAL_ABC) | ||||
| abc_val = ccv->labc; | abc_val = ccv->labc; | ||||
| else | else | ||||
| abc_val = V_tcp_abc_l_var; | abc_val = V_tcp_abc_l_var; | ||||
| if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_ALLOWED) && | if ((ccv->flags & CCF_HYSTART_ALLOWED) && | ||||
| (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) && | (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) && | ||||
| ((nreno->newreno_flags & CC_NEWRENO_HYSTART_IN_CSS) == 0)) { | ((nreno->newreno_flags & CC_NEWRENO_HYSTART_IN_CSS) == 0)) { | ||||
| /* | /* | ||||
| * Hystart is allowed and still enabled and we are not yet | * Hystart is allowed and still enabled and we are not yet | ||||
| * in CSS. Lets check to see if we can make a decision on | * in CSS. Lets check to see if we can make a decision on | ||||
| * if we need to go into CSS. | * if we need to go into CSS. | ||||
| */ | */ | ||||
| if ((nreno->css_rttsample_count >= hystart_n_rttsamples) && | if ((nreno->css_rttsample_count >= hystart_n_rttsamples) && | ||||
| (CCV(ccv, snd_cwnd) > | (nreno->css_current_round_minrtt != 0xffffffff) && | ||||
| (hystart_lowcwnd * tcp_fixed_maxseg(ccv->ccvc.tcp)))) { | (nreno->css_lastround_minrtt != 0xffffffff)) { | ||||
| uint32_t rtt_thresh; | uint32_t rtt_thresh; | ||||
| /* Clamp (minrtt_thresh, lastround/8, maxrtt_thresh) */ | /* Clamp (minrtt_thresh, lastround/8, maxrtt_thresh) */ | ||||
| rtt_thresh = (nreno->css_lastround_minrtt >> 3); | rtt_thresh = (nreno->css_lastround_minrtt >> 3); | ||||
| if (rtt_thresh < hystart_minrtt_thresh) | if (rtt_thresh < hystart_minrtt_thresh) | ||||
| rtt_thresh = hystart_minrtt_thresh; | rtt_thresh = hystart_minrtt_thresh; | ||||
| if (rtt_thresh > hystart_maxrtt_thresh) | if (rtt_thresh > hystart_maxrtt_thresh) | ||||
| rtt_thresh = hystart_maxrtt_thresh; | rtt_thresh = hystart_maxrtt_thresh; | ||||
| newreno_log_hystart_event(ccv, nreno, 1, rtt_thresh); | newreno_log_hystart_event(ccv, nreno, 1, rtt_thresh); | ||||
| if (nreno->css_current_round_minrtt >= (nreno->css_lastround_minrtt + rtt_thresh)) { | if (nreno->css_current_round_minrtt >= (nreno->css_lastround_minrtt + rtt_thresh)) { | ||||
| /* Enter CSS */ | /* Enter CSS */ | ||||
| nreno->newreno_flags |= CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags |= CC_NEWRENO_HYSTART_IN_CSS; | ||||
| nreno->css_fas_at_css_entry = nreno->css_lowrtt_fas; | nreno->css_fas_at_css_entry = nreno->css_lowrtt_fas; | ||||
| /* | |||||
| * The draft (v4) calls for us to set baseline to css_current_round_min | |||||
| * but that can cause an oscillation. We probably shoudl be using | |||||
| * css_lastround_minrtt, but the authors insist that will cause | |||||
| * issues on exiting early. We will leave the draft version for now | |||||
| * but I suspect this is incorrect. | |||||
| */ | |||||
| nreno->css_baseline_minrtt = nreno->css_current_round_minrtt; | nreno->css_baseline_minrtt = nreno->css_current_round_minrtt; | ||||
| nreno->css_entered_at_round = nreno->css_current_round; | nreno->css_entered_at_round = nreno->css_current_round; | ||||
| newreno_log_hystart_event(ccv, nreno, 2, rtt_thresh); | newreno_log_hystart_event(ccv, nreno, 2, rtt_thresh); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (CCV(ccv, snd_nxt) == CCV(ccv, snd_max)) | if (CCV(ccv, snd_nxt) == CCV(ccv, snd_max)) | ||||
| incr = min(ccv->bytes_this_ack, | incr = min(ccv->bytes_this_ack, | ||||
| Show All 18 Lines | |||||
| static void | static void | ||||
| newreno_after_idle(struct cc_var *ccv) | newreno_after_idle(struct cc_var *ccv) | ||||
| { | { | ||||
| struct newreno *nreno; | struct newreno *nreno; | ||||
| nreno = ccv->cc_data; | nreno = ccv->cc_data; | ||||
| newreno_cc_after_idle(ccv); | newreno_cc_after_idle(ccv); | ||||
| if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) == 0) { | if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) == 0) { | ||||
| if (CCV(ccv, snd_cwnd) <= (hystart_lowcwnd * tcp_fixed_maxseg(ccv->ccvc.tcp))) { | |||||
| /* | /* | ||||
| * Re-enable hystart if our cwnd has fallen below | * Re-enable hystart if we have been idle. | ||||
| * the hystart lowcwnd point. | |||||
| */ | */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| nreno->newreno_flags |= CC_NEWRENO_HYSTART_ENABLED; | nreno->newreno_flags |= CC_NEWRENO_HYSTART_ENABLED; | ||||
| newreno_log_hystart_event(ccv, nreno, 12, CCV(ccv, snd_ssthresh)); | |||||
| } | } | ||||
| } | } | ||||
| } | |||||
| /* | /* | ||||
| * Perform any necessary tasks before we enter congestion recovery. | * Perform any necessary tasks before we enter congestion recovery. | ||||
| */ | */ | ||||
| static void | static void | ||||
| newreno_cong_signal(struct cc_var *ccv, uint32_t type) | newreno_cong_signal(struct cc_var *ccv, uint32_t type) | ||||
| { | { | ||||
| struct newreno *nreno; | struct newreno *nreno; | ||||
| Show All 26 Lines | cwin = max(((uint64_t)cwin * (uint64_t)factor) / (100ULL * (uint64_t)mss), | ||||
| 2) * mss; | 2) * mss; | ||||
| switch (type) { | switch (type) { | ||||
| case CC_NDUPACK: | case CC_NDUPACK: | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) { | if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) { | ||||
| /* Make sure the flags are all off we had a loss */ | /* Make sure the flags are all off we had a loss */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| newreno_log_hystart_event(ccv, nreno, 10, CCV(ccv, snd_ssthresh)); | |||||
| } | } | ||||
| if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { | if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { | ||||
| if (IN_CONGRECOVERY(CCV(ccv, t_flags) && | if (IN_CONGRECOVERY(CCV(ccv, t_flags) && | ||||
| V_cc_do_abe && V_cc_abe_frlossreduce)) { | V_cc_do_abe && V_cc_abe_frlossreduce)) { | ||||
| CCV(ccv, snd_ssthresh) = | CCV(ccv, snd_ssthresh) = | ||||
| ((uint64_t)CCV(ccv, snd_ssthresh) * | ((uint64_t)CCV(ccv, snd_ssthresh) * | ||||
| (uint64_t)beta) / (uint64_t)beta_ecn; | (uint64_t)beta) / (uint64_t)beta_ecn; | ||||
| } | } | ||||
| if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) | if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) | ||||
| CCV(ccv, snd_ssthresh) = cwin; | CCV(ccv, snd_ssthresh) = cwin; | ||||
| ENTER_RECOVERY(CCV(ccv, t_flags)); | ENTER_RECOVERY(CCV(ccv, t_flags)); | ||||
| } | } | ||||
| break; | break; | ||||
| case CC_ECN: | case CC_ECN: | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) { | if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) { | ||||
| /* Make sure the flags are all off we had a loss */ | /* Make sure the flags are all off we had a loss */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| newreno_log_hystart_event(ccv, nreno, 9, CCV(ccv, snd_ssthresh)); | |||||
| } | } | ||||
| if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { | ||||
| CCV(ccv, snd_ssthresh) = cwin; | CCV(ccv, snd_ssthresh) = cwin; | ||||
| CCV(ccv, snd_cwnd) = cwin; | CCV(ccv, snd_cwnd) = cwin; | ||||
| ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ENTER_CONGRECOVERY(CCV(ccv, t_flags)); | ||||
| } | } | ||||
| break; | break; | ||||
| case CC_RTO: | case CC_RTO: | ||||
| Show All 26 Lines | case CC_NEWRENO_BETA: | ||||
| nreno->beta = opt->val; | nreno->beta = opt->val; | ||||
| break; | break; | ||||
| case CC_NEWRENO_BETA_ECN: | case CC_NEWRENO_BETA_ECN: | ||||
| if ((!V_cc_do_abe) && ((nreno->newreno_flags & CC_NEWRENO_BETA_ECN) == 0)) | if ((!V_cc_do_abe) && ((nreno->newreno_flags & CC_NEWRENO_BETA_ECN) == 0)) | ||||
| return (EACCES); | return (EACCES); | ||||
| nreno->beta_ecn = opt->val; | nreno->beta_ecn = opt->val; | ||||
| nreno->newreno_flags |= CC_NEWRENO_BETA_ECN_ENABLED; | nreno->newreno_flags |= CC_NEWRENO_BETA_ECN_ENABLED; | ||||
| break; | break; | ||||
| case CC_NEWRENO_ENABLE_HYSTART: | |||||
| /* Allow hystart on this connection */ | |||||
| if (opt->val != 0) { | |||||
| nreno->newreno_flags |= CC_NEWRENO_HYSTART_ALLOWED; | |||||
| if (opt->val > 1) | |||||
| nreno->newreno_flags |= CC_NEWRENO_HYSTART_CAN_SH_CWND; | |||||
| if (opt->val > 2) | |||||
| nreno->newreno_flags |= CC_NEWRENO_HYSTART_CONS_SSTH; | |||||
| } else | |||||
| nreno->newreno_flags &= ~(CC_NEWRENO_HYSTART_ALLOWED|CC_NEWRENO_HYSTART_CAN_SH_CWND|CC_NEWRENO_HYSTART_CONS_SSTH); | |||||
| newreno_log_hystart_event(ccv, nreno, 7, opt->val); | |||||
| break; | |||||
| default: | default: | ||||
| return (ENOPROTOOPT); | return (ENOPROTOOPT); | ||||
| } | } | ||||
| break; | break; | ||||
| case SOPT_GET: | case SOPT_GET: | ||||
| switch (opt->name) { | switch (opt->name) { | ||||
| case CC_NEWRENO_BETA: | case CC_NEWRENO_BETA: | ||||
| opt->val = (nreno == NULL) ? | opt->val = (nreno == NULL) ? | ||||
| V_newreno_beta : nreno->beta; | V_newreno_beta : nreno->beta; | ||||
| break; | break; | ||||
| case CC_NEWRENO_BETA_ECN: | case CC_NEWRENO_BETA_ECN: | ||||
| opt->val = (nreno == NULL) ? | opt->val = (nreno == NULL) ? | ||||
| V_newreno_beta_ecn : nreno->beta_ecn; | V_newreno_beta_ecn : nreno->beta_ecn; | ||||
| break; | break; | ||||
| case CC_NEWRENO_ENABLE_HYSTART: | |||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ALLOWED) { | |||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_CONS_SSTH) | |||||
| opt->val = 3; | |||||
| else if (nreno->newreno_flags & CC_NEWRENO_HYSTART_CAN_SH_CWND) | |||||
| opt->val = 2; | |||||
| else | |||||
| opt->val = 1; | |||||
| } else | |||||
| opt->val = 0; | |||||
| break; | |||||
| default: | default: | ||||
| return (ENOPROTOOPT); | return (ENOPROTOOPT); | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| return (EINVAL); | return (EINVAL); | ||||
| } | } | ||||
| Show All 29 Lines | newreno_newround(struct cc_var *ccv, uint32_t round_cnt) | ||||
| /* We have entered a new round */ | /* We have entered a new round */ | ||||
| nreno->css_lastround_minrtt = nreno->css_current_round_minrtt; | nreno->css_lastround_minrtt = nreno->css_current_round_minrtt; | ||||
| nreno->css_current_round_minrtt = 0xffffffff; | nreno->css_current_round_minrtt = 0xffffffff; | ||||
| nreno->css_rttsample_count = 0; | nreno->css_rttsample_count = 0; | ||||
| nreno->css_current_round = round_cnt; | nreno->css_current_round = round_cnt; | ||||
| if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_IN_CSS) && | if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_IN_CSS) && | ||||
| ((round_cnt - nreno->css_entered_at_round) >= hystart_css_rounds)) { | ((round_cnt - nreno->css_entered_at_round) >= hystart_css_rounds)) { | ||||
| /* Enter CA */ | /* Enter CA */ | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_CAN_SH_CWND) { | if (ccv->flags & CCF_HYSTART_CAN_SH_CWND) { | ||||
| /* | /* | ||||
| * We engage more than snd_ssthresh, engage | * We engage more than snd_ssthresh, engage | ||||
| * the brakes!! Though we will stay in SS to | * the brakes!! Though we will stay in SS to | ||||
| * creep back up again, so lets leave CSS active | * creep back up again, so lets leave CSS active | ||||
| * and give us hystart_css_rounds more rounds. | * and give us hystart_css_rounds more rounds. | ||||
| */ | */ | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_CONS_SSTH) { | if (ccv->flags & CCF_HYSTART_CONS_SSTH) { | ||||
| CCV(ccv, snd_ssthresh) = ((nreno->css_lowrtt_fas + nreno->css_fas_at_css_entry) / 2); | CCV(ccv, snd_ssthresh) = ((nreno->css_lowrtt_fas + nreno->css_fas_at_css_entry) / 2); | ||||
| } else { | } else { | ||||
| CCV(ccv, snd_ssthresh) = nreno->css_lowrtt_fas; | CCV(ccv, snd_ssthresh) = nreno->css_lowrtt_fas; | ||||
| } | } | ||||
| CCV(ccv, snd_cwnd) = nreno->css_fas_at_css_entry; | CCV(ccv, snd_cwnd) = nreno->css_fas_at_css_entry; | ||||
| nreno->css_entered_at_round = round_cnt; | nreno->css_entered_at_round = round_cnt; | ||||
| } else { | } else { | ||||
| CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); | CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); | ||||
| /* Turn off the CSS flag */ | /* Turn off the CSS flag */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| /* Disable use of CSS in the future except long idle */ | /* Disable use of CSS in the future except long idle */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_ENABLED; | ||||
| } | } | ||||
| newreno_log_hystart_event(ccv, nreno, 6, CCV(ccv, snd_ssthresh)); | newreno_log_hystart_event(ccv, nreno, 6, CCV(ccv, snd_ssthresh)); | ||||
| } | } | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) | |||||
| newreno_log_hystart_event(ccv, nreno, 4, round_cnt); | newreno_log_hystart_event(ccv, nreno, 4, round_cnt); | ||||
| } | } | ||||
| static void | static void | ||||
| newreno_rttsample(struct cc_var *ccv, uint32_t usec_rtt, uint32_t rxtcnt, uint32_t fas) | newreno_rttsample(struct cc_var *ccv, uint32_t usec_rtt, uint32_t rxtcnt, uint32_t fas) | ||||
| { | { | ||||
| struct newreno *nreno; | struct newreno *nreno; | ||||
| nreno = (struct newreno *)ccv->cc_data; | nreno = (struct newreno *)ccv->cc_data; | ||||
| if (rxtcnt > 1) { | if (rxtcnt > 1) { | ||||
| /* | /* | ||||
| * Only look at RTT's that are non-ambiguous. | * Only look at RTT's that are non-ambiguous. | ||||
| */ | */ | ||||
| return; | return; | ||||
| } | } | ||||
| nreno->css_rttsample_count++; | nreno->css_rttsample_count++; | ||||
| nreno->css_last_fas = fas; | nreno->css_last_fas = fas; | ||||
| if (nreno->css_current_round_minrtt > usec_rtt) { | if (nreno->css_current_round_minrtt > usec_rtt) { | ||||
| nreno->css_current_round_minrtt = usec_rtt; | nreno->css_current_round_minrtt = usec_rtt; | ||||
| nreno->css_lowrtt_fas = nreno->css_last_fas; | nreno->css_lowrtt_fas = nreno->css_last_fas; | ||||
| } | } | ||||
| if ((nreno->newreno_flags & CC_NEWRENO_HYSTART_IN_CSS) && | if ((nreno->css_rttsample_count >= hystart_n_rttsamples) && | ||||
| (nreno->css_rttsample_count >= hystart_n_rttsamples) && | (nreno->css_current_round_minrtt != 0xffffffff) && | ||||
| (nreno->css_baseline_minrtt > nreno->css_current_round_minrtt)) { | (nreno->css_lastround_minrtt != 0xffffffff)) { | ||||
| /* | /* | ||||
| * We were in CSS and the RTT is now less, we | * We were in CSS and the RTT is now less, we | ||||
| * entered CSS erroneously. | * entered CSS erroneously. | ||||
| */ | */ | ||||
| nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | nreno->newreno_flags &= ~CC_NEWRENO_HYSTART_IN_CSS; | ||||
| newreno_log_hystart_event(ccv, nreno, 8, nreno->css_baseline_minrtt); | newreno_log_hystart_event(ccv, nreno, 8, nreno->css_baseline_minrtt); | ||||
| nreno->css_baseline_minrtt = 0xffffffff; | nreno->css_baseline_minrtt = 0xffffffff; | ||||
| } | } | ||||
| if (nreno->newreno_flags & CC_NEWRENO_HYSTART_ENABLED) | |||||
| newreno_log_hystart_event(ccv, nreno, 5, usec_rtt); | newreno_log_hystart_event(ccv, nreno, 5, usec_rtt); | ||||
| } | } | ||||
| SYSCTL_DECL(_net_inet_tcp_cc_newreno); | SYSCTL_DECL(_net_inet_tcp_cc_newreno); | ||||
| SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, newreno, | SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, newreno, | ||||
| CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, | ||||
| "New Reno related settings"); | "New Reno related settings"); | ||||
| SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta, | SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta, | ||||
| CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
| &VNET_NAME(newreno_beta), 3, &newreno_beta_handler, "IU", | &VNET_NAME(newreno_beta), 3, &newreno_beta_handler, "IU", | ||||
| "New Reno beta, specified as number between 1 and 100"); | "New Reno beta, specified as number between 1 and 100"); | ||||
| SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta_ecn, | SYSCTL_PROC(_net_inet_tcp_cc_newreno, OID_AUTO, beta_ecn, | ||||
| CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, | ||||
| &VNET_NAME(newreno_beta_ecn), 3, &newreno_beta_handler, "IU", | &VNET_NAME(newreno_beta_ecn), 3, &newreno_beta_handler, "IU", | ||||
| "New Reno beta ecn, specified as number between 1 and 100"); | "New Reno beta ecn, specified as number between 1 and 100"); | ||||
| SYSCTL_NODE(_net_inet_tcp_cc_newreno, OID_AUTO, hystartplusplus, | |||||
| CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, | |||||
| "New Reno related HyStart++ settings"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, lowcwnd, | |||||
| CTLFLAG_RW, | |||||
| &hystart_lowcwnd, 16, | |||||
| "The number of MSS in the CWND before HyStart++ is active"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, minrtt_thresh, | |||||
| CTLFLAG_RW, | |||||
| &hystart_minrtt_thresh, 4000, | |||||
| "HyStarts++ minimum RTT thresh used in clamp (in microseconds)"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, maxrtt_thresh, | |||||
| CTLFLAG_RW, | |||||
| &hystart_maxrtt_thresh, 16000, | |||||
| "HyStarts++ maximum RTT thresh used in clamp (in microseconds)"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, n_rttsamples, | |||||
| CTLFLAG_RW, | |||||
| &hystart_n_rttsamples, 8, | |||||
| "The number of RTT samples that must be seen to consider HyStart++"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, css_growth_div, | |||||
| CTLFLAG_RW, | |||||
| &hystart_css_growth_div, 4, | |||||
| "The divisor to the growth when in Hystart++ CSS"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, css_rounds, | |||||
| CTLFLAG_RW, | |||||
| &hystart_css_rounds, 5, | |||||
| "The number of rounds HyStart++ lasts in CSS before falling to CA"); | |||||
| SYSCTL_UINT(_net_inet_tcp_cc_newreno_hystartplusplus, OID_AUTO, bblogs, | |||||
| CTLFLAG_RW, | |||||
| &hystart_bblogs, 0, | |||||
| "Do we enable HyStart++ Black Box logs to be generated if BB logging is on"); | |||||
| DECLARE_CC_MODULE(newreno, &newreno_cc_algo); | DECLARE_CC_MODULE(newreno, &newreno_cc_algo); | ||||
| MODULE_VERSION(newreno, 2); | MODULE_VERSION(newreno, 2); | ||||