40 static inline void issue_retransmits(
struct connection *c,
43 static inline void dctcp_win_init(
struct connection *c);
44 static inline void dctcp_win_update(
struct connection *c,
47 static inline void dctcp_rate_init(
struct connection *c);
48 static inline void dctcp_rate_update(
struct connection *c,
51 static inline void timely_init(
struct connection *c);
52 static inline void timely_update(
struct connection *c,
55 static inline void const_rate_init(
struct connection *c);
56 static inline void const_rate_update(
struct connection *c,
59 static inline uint32_t window_to_rate(uint32_t window, uint32_t rtt);
61 static uint32_t last_ts = 0;
65 uint32_t cc_next_ts(uint32_t cur_ts)
68 assert(cur_ts >= last_ts);
71 for (c = cc_conns; c != NULL; c = c->
cc_next) {
77 ts = MIN(ts, next_ts);
94 diff_ts = cur_ts - last_ts;
98 c = c_first = (next_conn != NULL ? next_conn : cc_conns);
104 for (; n < 128 && (n == 0 || c != c_first);
105 c = (c->cc_next != NULL ? c->cc_next : cc_conns), n++)
114 fprintf(stderr,
"cc_poll: nicif_connection_stats failed unexpectedly\n");
119 last = c->cc_last_drops;
120 c->cc_last_drops = stats.
c_drops;
123 last = c->cc_last_acks;
124 c->cc_last_acks = stats.
c_acks;
127 last = c->cc_last_ackb;
128 c->cc_last_ackb = stats.
c_ackb;
131 last = c->cc_last_ecnb;
132 c->cc_last_ecnb = stats.
c_ecnb;
140 case CONFIG_CC_DCTCP_WIN:
141 dctcp_win_update(c, &stats, diff_ts, cur_ts);
144 case CONFIG_CC_DCTCP_RATE:
145 dctcp_rate_update(c, &stats, diff_ts, cur_ts);
148 case CONFIG_CC_TIMELY:
149 timely_update(c, &stats, diff_ts, cur_ts);
152 case CONFIG_CC_CONST_RATE:
153 const_rate_update(c, &stats, diff_ts, cur_ts);
157 fprintf(stderr,
"cc_poll: unknown CC algorithm (%u)\n",
163 issue_retransmits(c, &stats, cur_ts);
166 c->cc_last_ts = cur_ts;
185 case CONFIG_CC_DCTCP_WIN:
186 dctcp_win_init(conn);
189 case CONFIG_CC_DCTCP_RATE:
190 dctcp_rate_init(conn);
193 case CONFIG_CC_TIMELY:
197 case CONFIG_CC_CONST_RATE:
198 const_rate_init(conn);
202 fprintf(stderr,
"cc_conn_init: unknown CC algorithm (%u)\n",
213 if (next_conn == conn) {
217 if (cc_conns == conn) {
220 for (cp = cc_conns; cp != NULL && cp->
cc_next != conn;
223 fprintf(stderr,
"conn_unregister: connection not found\n");
231 static inline void issue_retransmits(
struct connection *c,
257 static inline void dctcp_win_init(
struct connection *c)
261 cc->
window = 2 * CONF_MSS;
267 static inline void dctcp_win_update(
struct connection *c,
272 uint32_t rtt = stats->
rtt, win = cc->
window;
274 assert(win >= CONF_MSS);
285 if (win + stats->
c_ackb > win)
303 ecn_rate = (((uint64_t) stats->
c_ecnb) * UINT32_MAX) / stats->
c_ackb;
309 ecn_rate /= UINT32_MAX;
315 win = (((uint64_t) win) * (UINT32_MAX - cc->
ecn_rate / 2)) / UINT32_MAX;
319 incr = ((uint64_t) stats->
c_ackb * CONF_MSS) / win;
320 if ((uint32_t) (win + incr) > win)
335 c->
cc_rate = window_to_rate(win, rtt);
336 assert(win >= CONF_MSS);
342 static inline uint32_t window_to_rate(uint32_t
window, uint32_t rtt)
350 if (time < rtt * 1000)
355 rate = ((uint64_t)
window * 8 * 1000000) / time;
356 if (rate > UINT32_MAX)
365 static inline void dctcp_rate_init(
struct connection *c)
380 static inline void dctcp_rate_update(
struct connection *c,
414 act_rate = c_ackb * 8 * 1000 / (cur_ts - c->
cc_last_ts);
422 if (rate > (uint64_t) act_rate * 12 / 10) {
423 rate = (uint64_t) act_rate * 12 / 10;
428 if (c_drops == 0 && c_ecnb == 0 && c->
cc_rexmits == 0) {
430 if (rate * 2 >= rate)
448 c_ecnb = (c_ecnb <= c_ackb ? c_ecnb : c_ackb);
449 ecn_rate = (((uint64_t) c_ecnb) * UINT32_MAX) / c_ackb;
455 ecn_rate /= UINT32_MAX;
461 rate = (((uint64_t) rate) * (UINT32_MAX - cc->
ecn_rate / 2)) /
468 rate += (((uint64_t) rate) * config.
cc_dctcp_mimd) / UINT32_MAX;
484 static inline void timely_init(
struct connection *c)
493 static inline void timely_update(
struct connection *c,
497 int32_t new_rtt_diff = 0;
498 uint32_t new_rtt, new_rate,
act_rate;
500 int64_t x, normalized_gradient = 0;
502 new_rtt = stats->
rtt;
506 act_rate = stats->
c_ackb * 8 * 1000 / (cur_ts - cc->
last_ts);
524 c->
cc_rate = (uint64_t) act_rate * 12 / 10;
529 new_rtt_diff = new_rtt - cc->
rtt_prev;
533 x = (INT32_MAX - factor) * cc->
rtt_diff + factor * new_rtt_diff;
537 normalized_gradient =
543 uint32_t orig_rate = c->
cc_rate;
556 uint32_t d = ((uint64_t) UINT32_MAX * config.
cc_timely_thigh) / new_rtt;
557 uint32_t b = UINT32_MAX - d;
558 uint32_t a = (((uint64_t) config.
cc_timely_beta) * b) / UINT32_MAX;
559 c->
cc_rate = (((uint64_t) c->
cc_rate) * (UINT32_MAX - a)) / UINT32_MAX;
561 }
else if (normalized_gradient <= 0) {
572 int64_t a = ((int64_t) (config.
cc_timely_beta / 2)) * normalized_gradient;
573 int64_t b = a / INT16_MAX;
574 int64_t d = (b <= INT32_MAX ? INT32_MAX - b : 0);
575 int64_t e = ((int64_t) (uint64_t) c->
cc_rate) * d;
576 int64_t f = e / INT32_MAX;
583 if (c->
cc_rate < orig_rate / 2) {
598 static inline void const_rate_init(
struct connection *c)
603 static inline void const_rate_update(
struct connection *c,
int nicif_connection_setrate(uint32_t f_id, uint32_t rate)
unsigned cc_poll(uint32_t cur_ts)
uint32_t cc_control_granularity
uint32_t cc_control_interval
enum connection_status status
uint32_t cc_timely_min_rate
uint32_t cc_dctcp_minpkts
struct connection_cc_dctcp_win dctcp_win
int nicif_connection_retransmit(uint32_t f_id, uint16_t core)
int nicif_connection_stats(uint32_t f_id, struct nicif_connection_stats *p_stats)
struct connection_cc_dctcp_rate dctcp_rate
struct connection_cc_timely timely
void cc_conn_init(struct connection *conn)
struct connection * cc_next
uint32_t cc_timely_min_rtt
void cc_conn_remove(struct connection *conn)
enum config_cc_algorithm cc_algorithm