53#define SHIFT_MPTCP_MULTI_N 40
54#define SHIFT_MPTCP_MULTI_Z 16
55#define SHIFT_MPTCP_MULTI 8
78 if (cwnd_in_mtu == 0) {
100 SDT_PROBE5(sctp, cwnd, net, init,
115 uint64_t t_ucwnd_sbw;
123 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
127 t_ucwnd_sbw += (uint64_t)net->
cwnd / (uint64_t)net->
lastsa;
130 if (t_ucwnd_sbw == 0) {
139 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
151 int old_cwnd = net->
cwnd;
159 (uint64_t)t_ssthresh);
178 (uint64_t)net->
cwnd) /
183 if ((net->
cwnd > t_cwnd / 2) &&
198 SDT_PROBE5(sctp, cwnd, net, fr,
200 old_cwnd, net->
cwnd);
247#define SCTP_INST_LOOSING 1
248#define SCTP_INST_NEUTRAL 2
249#define SCTP_INST_GAINING 3
253 uint64_t rtt_offset, uint64_t vtag,
uint8_t inst_ind)
255 uint64_t oth, probepoint;
257 probepoint = (((uint64_t)net->
cwnd) << 32);
264 probepoint |= ((5 << 16) | 1);
265 SDT_PROBE5(sctp, cwnd, net, rttvar,
286 SDT_PROBE5(sctp, cwnd, net, rttstep,
292 if (net->
cwnd > (4 * net->
mtu)) {
309 probepoint |= ((6 << 16) | 0);
310 SDT_PROBE5(sctp, cwnd, net, rttvar,
322 SDT_PROBE5(sctp, cwnd, net, rttstep,
353 SDT_PROBE5(sctp, cwnd, net, rttvar,
369 if (net->
cwnd > (4 * net->
mtu)) {
388 uint64_t vtag,
uint8_t inst_ind)
390 uint64_t oth, probepoint;
393 probepoint = (((uint64_t)net->
cwnd) << 32);
401 probepoint |= ((1 << 16) | 1);
402 SDT_PROBE5(sctp, cwnd, net, rttvar,
419 probepoint |= ((2 << 16) | 0);
420 SDT_PROBE5(sctp, cwnd, net, rttvar,
433 SDT_PROBE5(sctp, cwnd, net, rttstep,
456 probepoint |= ((3 << 16) | 0);
457 SDT_PROBE5(sctp, cwnd, net, rttvar,
469 SDT_PROBE5(sctp, cwnd, net, rttstep,
488 probepoint |= ((4 << 16) | 0);
489 SDT_PROBE5(sctp, cwnd, net, rttvar,
501 SDT_PROBE5(sctp, cwnd, net, rttstep,
530 uint64_t oth, probepoint;
538 probepoint = (((uint64_t)net->
cwnd) << 32);
539 SDT_PROBE5(sctp, cwnd, net, rttvar,
551 SDT_PROBE5(sctp, cwnd, net, rttstep,
573 uint64_t bw_offset, rtt_offset;
574 uint64_t probepoint, rtt, vtag;
575 uint64_t bytes_for_this_rtt, inst_bw;
576 uint64_t div, inst_off;
621 probepoint = (((uint64_t)net->
cwnd) << 32);
628 div = net->
rtt / 1000;
630 inst_bw = bytes_for_this_rtt / div;
631 inst_off = inst_bw >> bw_shift;
634 else if ((inst_bw + inst_off) < nbw)
638 probepoint |= ((0xb << 16) | inst_ind);
641 inst_bw = bytes_for_this_rtt / (uint64_t)(net->
rtt);
643 probepoint |= ((0xc << 16) | inst_ind);
647 inst_bw = bytes_for_this_rtt;
649 probepoint |= ((0xd << 16) | inst_ind);
651 SDT_PROBE5(sctp, cwnd, net, rttvar,
653 ((nbw << 32) | inst_bw),
667 if (nbw < net->cc_mod.rtcc.lbw - bw_offset) {
675 ret =
cc_bw_same(stcb, net, nbw, rtt_offset, vtag, inst_ind);
684 int accum_moved,
int reneged_all
SCTP_UNUSED,
int will_exit,
int use_rtcc)
689 uint64_t t_ucwnd_sbw;
690 uint64_t t_path_mptcp;
691 uint64_t mptcp_like_alpha;
699 mptcp_like_alpha = 1;
704 TAILQ_FOREACH(net, &stcb->
asoc.
nets, sctp_next) {
711 t_ucwnd_sbw += (uint64_t)net->
cwnd / (uint64_t)srtt;
713 (((uint64_t)net->
mtu) * (uint64_t)srtt);
715 ((uint64_t)net->
mtu * (uint64_t)(srtt * srtt));
716 if (tmp > max_path) {
721 if (t_path_mptcp > 0) {
722 mptcp_like_alpha = max_path / (t_path_mptcp * t_path_mptcp);
724 mptcp_like_alpha = 1;
727 if (t_ssthresh == 0) {
730 if (t_ucwnd_sbw == 0) {
736 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
737#ifdef JANA_CMT_FAST_RECOVERY
755#ifdef JANA_CMT_FAST_RECOVERY
800 uint64_t vtag, probepoint;
802 probepoint = (((uint64_t)net->
cwnd) << 32);
803 probepoint |= ((0xa << 16) | 0);
804 vtag = (net->
rtt << 32) |
808 SDT_PROBE5(sctp,
cwnd, net, rttvar,
834 old_cwnd = net->
cwnd;
840 (uint64_t)t_ssthresh);
843 (uint64_t)t_ssthresh);
862 (uint64_t)net->
cwnd) /
863 ((uint64_t)srtt * t_ucwnd_sbw));
866 (uint64_t)net->
cwnd) /
867 ((uint64_t)srtt * t_ucwnd_sbw));
890 if (incr > net->
mtu) {
907 SDT_PROBE5(sctp,
cwnd, net, ack,
911 old_cwnd, net->
cwnd);
928 old_cwnd = net->
cwnd;
933 (uint64_t)t_ssthresh);
948 (uint64_t)net->
cwnd /
957 incr = (
uint32_t)((mptcp_like_alpha *
958 (uint64_t)net->
cwnd) >>
960 if (incr > net->
mtu) {
970 SDT_PROBE5(sctp,
cwnd, net, ack,
974 old_cwnd, net->
cwnd);
1000 old_cwnd = net->
cwnd;
1002 SDT_PROBE5(sctp,
cwnd, net, ack,
1004 old_cwnd, net->
cwnd);
1006 (
void *)net, net->
cwnd);
1012 int old_cwnd = net->
cwnd;
1014 uint64_t t_ucwnd_sbw;
1025 TAILQ_FOREACH(lnet, &stcb->
asoc.
nets, sctp_next) {
1027 t_cwnd += lnet->
cwnd;
1031 t_ucwnd_sbw += (uint64_t)lnet->
cwnd / (uint64_t)srtt;
1034 if (t_ssthresh < 1) {
1037 if (t_ucwnd_sbw < 1) {
1042 (uint64_t)net->
mtu *
1044 (uint64_t)t_ssthresh);
1053 cc_delta = t_ucwnd_sbw * (uint64_t)srtt / 2;
1054 if (cc_delta < t_cwnd) {
1060 if ((net->
cwnd > t_cwnd / 2) &&
1072 SDT_PROBE5(sctp,
cwnd, net, to,
1076 old_cwnd, net->
cwnd);
1084 int in_window,
int num_pkt_lost,
int use_rtcc)
1086 int old_cwnd = net->
cwnd;
1090 if (in_window == 0) {
1113 net->
cwnd -= (net->
mtu * num_pkt_lost);
1120 if (in_window == 0) {
1132 SDT_PROBE5(sctp,
cwnd, net, ecn,
1136 old_cwnd, net->
cwnd);
1152 int old_cwnd = net->
cwnd;
1166 bw_avail = (
uint32_t)(((uint64_t)(*bottle_bw) * net->
rtt) / (uint64_t)1000000);
1167 if (bw_avail > *bottle_bw) {
1176 bw_avail = *bottle_bw;
1178 if (*on_queue > bw_avail) {
1183 int seg_inflight, seg_onqueue, my_portion;
1187 incr = *on_queue - bw_avail;
1197 seg_onqueue = *on_queue / net->
mtu;
1198 my_portion = (incr * seg_inflight) / seg_onqueue;
1210 if (diff_adj > my_portion)
1213 my_portion -= diff_adj;
1220 net->
cwnd -= my_portion;
1233 incr = (bw_avail - *on_queue) >> 2;
1240 if (net->
cwnd > bw_avail) {
1242 net->
cwnd = bw_avail;
1249 if (net->
cwnd - old_cwnd != 0) {
1251 SDT_PROBE5(sctp,
cwnd, net, pd,
1255 old_cwnd, net->
cwnd);
1267 int old_cwnd = net->
cwnd;
1274 SDT_PROBE5(sctp,
cwnd, net, bl,
1278 old_cwnd, net->
cwnd);
1288 int accum_moved,
int reneged_all,
int will_exit)
1296 int in_window,
int num_pkt_lost)
1309 int in_window,
int num_pkt_lost)
1327 struct timeval ltls;
1339 uint64_t vtag, probepoint;
1345 probepoint = (((uint64_t)net->
cwnd) << 32);
1347 probepoint |= ((8 << 16) | 0);
1348 SDT_PROBE5(sctp, cwnd, net, rttvar,
1372 if (cwnd_in_mtu == 0) {
1385 cwnd = (net->
mtu -
sizeof(
struct sctphdr)) * cwnd_in_mtu;
1387 if (net->
cwnd > cwnd) {
1402 uint64_t vtag, probepoint;
1406 probepoint = (((uint64_t)net->
cwnd) << 32);
1407 probepoint |= ((9 << 16) | 0);
1408 vtag = (net->
rtt << 32) |
1411 SDT_PROBE5(sctp, cwnd, net, rttvar,
1439 if (setorget == 1) {
1446 TAILQ_FOREACH(net, &stcb->
asoc.
nets, sctp_next) {
1454 TAILQ_FOREACH(net, &stcb->
asoc.
nets, sctp_next) {
1458 TAILQ_FOREACH(net, &stcb->
asoc.
nets, sctp_next) {
1467 net = TAILQ_FIRST(&stcb->
asoc.
nets);
1473 net = TAILQ_FIRST(&stcb->
asoc.
nets);
1479 net = TAILQ_FIRST(&stcb->
asoc.
nets);
1504 int accum_moved,
int reneged_all,
int will_exit)
1526#define SCTP_HS_TABLE_SIZE 73
1607 int cur_val, i, indx, incr;
1608 int old_cwnd = net->
cwnd;
1610 cur_val = net->
cwnd >> 10;
1640 int cur_val, i, indx;
1641 int old_cwnd = net->
cwnd;
1643 cur_val = net->
cwnd >> 10;
1658 cur_val = net->
cwnd >> 10;
1664 for (i = indx; i >= 1; i--) {
1688 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
1734 }
else if (net->
net_ack > 0) {
1747 int accum_moved,
int reneged_all
SCTP_UNUSED,
int will_exit)
1754 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
1755#ifdef JANA_CMT_FAST_RECOVERY
1773#ifdef JANA_CMT_FAST_RECOVERY
1853 return (seq3 - seq2 >= seq1 - seq2);
1957 if (!
between(5 * maxB, 4 * old_maxB, 6 * old_maxB)) {
1965 ca->
beta = (minRTT << 7) / maxRTT;
1985 factor = 1 + (10 * diff + ((diff / 2) * (diff / 2) / hz)) / hz;
1989 uint32_t scale = (hz << 3) / (10 * minRTT);
1991 scale = min(max(scale, 1U << 2), 10U << 3);
1993 factor = (factor << 3) / scale;
1998 ca->
alpha = 2 * factor * ((1 << 7) - ca->
beta);
2024 if (minRTT > 0 && maxRTT > minRTT)
2139 int accum_moved,
int reneged_all
SCTP_UNUSED,
int will_exit)
2146 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
2147#ifdef JANA_CMT_FAST_RECOVERY
2165#ifdef JANA_CMT_FAST_RECOVERY
2213 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
2225 int old_cwnd = net->
cwnd;
2267 }
else if (net->
net_ack > 0) {
2281 int old_cwnd = net->
cwnd;
2299 old_cwnd = net->
cwnd;
2302 if (in_window == 0) {
#define SCTP_CWND_MONITOR_ENABLE
#define SCTP_CC_OPT_USE_DCCC_ECN
#define SCTP_CC_OPT_STEADY_STEP
#define SCTP_CWND_LOGGING_ENABLE
#define SCTP_CC_OPT_RTCC_SETMODE
static void sctp_set_rtcc_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_cwnd_update_rtcc_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, int in_window, int num_pkt_lost)
static void sctp_cwnd_update_exit_pf_common(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_pktdrop_chunk *cp, uint32_t *bottle_bw, uint32_t *on_queue)
static int cc_bw_limit(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw)
static void sctp_enforce_cwnd_limit(struct sctp_association *assoc, struct sctp_nets *net)
static int cc_bw_same(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset, uint64_t vtag, uint8_t inst_ind)
#define SCTP_HS_TABLE_SIZE
static void sctp_cwnd_update_after_output(struct sctp_tcb *stcb, struct sctp_nets *net, int burst_limit)
static int between(uint32_t seq1, uint32_t seq2, uint32_t seq3)
static void sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, int in_window, int num_pkt_lost)
static void htcp_param_update(struct sctp_nets *net)
static void htcp_reset(struct htcp *ca)
static void sctp_htcp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_cwnd_update_after_ecn_echo_common(struct sctp_tcb *stcb, struct sctp_nets *net, int in_window, int num_pkt_lost, int use_rtcc)
static void sctp_cwnd_update_rtcc_after_sack(struct sctp_tcb *stcb, struct sctp_association *asoc, int accum_moved, int reneged_all, int will_exit)
static void sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb, struct sctp_association *asoc)
#define SCTP_INST_GAINING
#define SHIFT_MPTCP_MULTI_Z
static int use_rtt_scaling
static void sctp_cwnd_new_rtcc_transmission_begins(struct sctp_tcb *stcb, struct sctp_nets *net)
static int cc_bw_increase(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t vtag)
static void sctp_cwnd_update_after_sack(struct sctp_tcb *stcb, struct sctp_association *asoc, int accum_moved, int reneged_all, int will_exit)
static void htcp_beta_update(struct htcp *ca, uint32_t minRTT, uint32_t maxRTT)
static void sctp_cwnd_update_after_sack_common(struct sctp_tcb *stcb, struct sctp_association *asoc, int accum_moved, int reneged_all SCTP_UNUSED, int will_exit, int use_rtcc)
static uint32_t htcp_recalc_ssthresh(struct sctp_nets *net)
static uint32_t htcp_ccount(struct htcp *ca)
#define SHIFT_MPTCP_MULTI
#define SCTP_INST_NEUTRAL
static void sctp_cwnd_update_rtcc_packet_transmitted(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net)
static int sctp_cwnd_rtcc_socket_option(struct sctp_tcb *stcb, int setorget, struct sctp_cc_option *cc_opt)
static uint32_t htcp_cong_time(struct htcp *ca)
static void measure_rtt(struct sctp_nets *net)
static void sctp_rtt_rtcc_calculated(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net, struct timeval *now SCTP_UNUSED)
static void sctp_cwnd_update_rtcc_tsn_acknowledged(struct sctp_nets *net, struct sctp_tmit_chunk *tp1)
static void sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb, struct sctp_association *asoc)
static void sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb, struct sctp_association *asoc, int accum_moved, int reneged_all SCTP_UNUSED, int will_exit)
static void sctp_hs_cwnd_increase(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_cwnd_prepare_rtcc_net_for_sack(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net)
static int cc_bw_decrease(struct sctp_tcb *stcb, struct sctp_nets *net, uint64_t nbw, uint64_t rtt_offset, uint64_t vtag, uint8_t inst_ind)
static void sctp_htcp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, int in_window, int num_pkt_lost SCTP_UNUSED)
static void sctp_htcp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
#define SCTP_INST_LOOSING
static void htcp_alpha_update(struct htcp *ca)
static const struct sctp_hs_raise_drop sctp_cwnd_adjust[SCTP_HS_TABLE_SIZE]
static void sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb, struct sctp_association *asoc, int accum_moved, int reneged_all SCTP_UNUSED, int will_exit)
static void measure_achieved_throughput(struct sctp_nets *net)
#define SHIFT_MPTCP_MULTI_N
static int use_bandwidth_switch
static void htcp_init(struct sctp_nets *net)
static void sctp_cwnd_update_after_fr(struct sctp_tcb *stcb, struct sctp_association *asoc)
static void htcp_cong_avoid(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_hs_cwnd_decrease(struct sctp_tcb *stcb, struct sctp_nets *net)
#define SCTP_CWND_LOG_FROM_BRST
#define SCTP_CWND_LOG_NOADV_SS
#define SCTP_FROM_SCTP_CC_FUNCTIONS
#define SCTP_CWND_LOG_FROM_SACK
#define SCTP_CWND_LOG_NOADV_CA
#define SCTP_GETPTIME_TIMEVAL(x)
#define SCTP_CWND_LOG_NO_CUMACK
#define SCTP_TSN_GE(a, b)
#define SCTP_CWND_LOG_FROM_RTX
#define SCTP_CWND_INITIALIZATION
#define SCTP_CWND_LOG_FROM_FR
#define SCTP_CWND_LOG_FROM_SAT
#define SCTP_CWND_LOG_FROM_CA
#define SCTP_TIMER_TYPE_SEND
#define SCTP_DEBUG_INDATA1
#define SCTP_CWND_LOG_FROM_SS
#define SCTP_INITIAL_CWND
#define SCTPDBG(level, params...)
#define SCTP_BASE_SYSCTL(__m)
#define sctp_get_tick_count()
#define SCTP_STAT_INCR(_x)
void sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t from)
void sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
uint32_t sctp_msecs_to_ticks(uint32_t msecs)
uint8_t rtt_set_this_sack
uint64_t bw_bytes_at_last_rttc
struct sctpchunk_listhead send_queue
struct sctpnetlisthead nets
uint8_t fast_retran_loss_recovery
uint32_t fast_recovery_tsn
uint8_t seen_a_sack_this_pkt
void(* sctp_set_initial_cc_param)(struct sctp_tcb *stcb, struct sctp_nets *net)
struct sctp_assoc_value aid_value
uint8_t new_pseudo_cumack
uint32_t partial_bytes_acked
uint32_t fast_recovery_tsn
union sctp_nets::cc_control_data cc_mod
uint8_t fast_retran_loss_recovery
uint8_t will_exit_fast_recovery
struct sctp_association asoc
struct sctp_inpcb * sctp_ep
union sctp_tmit_chunk::@34 rec
struct sctp_data_chunkrec data
struct sctp_association * asoc