summaryrefslogtreecommitdiffstats
path: root/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c')
-rw-r--r--src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c302
1 files changed, 136 insertions, 166 deletions
diff --git a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
index 2211a31..8b3845c 100644
--- a/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
+++ b/src/contrib/libngtcp2/ngtcp2/lib/ngtcp2_bbr.c
@@ -39,8 +39,9 @@
#define NGTCP2_BBR_EXTRA_ACKED_FILTERLEN 10
#define NGTCP2_BBR_STARTUP_PACING_GAIN_H 277
+#define NGTCP2_BBR_DRAIN_PACING_GAIN_H 35
-#define NGTCP2_BBR_STARTUP_CWND_GAIN_H 200
+#define NGTCP2_BBR_DEFAULT_CWND_GAIN_H 200
#define NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H 50
@@ -72,7 +73,7 @@ static void bbr_reset_lower_bounds(ngtcp2_cc_bbr *bbr);
static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr);
-static void bbr_init_full_pipe(ngtcp2_cc_bbr *bbr);
+static void bbr_reset_full_bw(ngtcp2_cc_bbr *bbr);
static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
@@ -84,8 +85,7 @@ static void bbr_set_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
static void bbr_enter_startup(ngtcp2_cc_bbr *bbr);
-static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr,
- const ngtcp2_cc_ack *ack);
+static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr);
static void bbr_update_on_ack(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
@@ -148,16 +148,17 @@ static void bbr_start_probe_bw_cruise(ngtcp2_cc_bbr *bbr);
static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr);
-static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts);
+static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat,
const ngtcp2_cc_ack *ack,
ngtcp2_tstamp ts);
-static int bbr_check_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts);
+static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
+ ngtcp2_tstamp ts);
+
+static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
static int bbr_has_elapsed_in_phase(ngtcp2_cc_bbr *bbr,
ngtcp2_duration interval, ngtcp2_tstamp ts);
@@ -175,9 +176,8 @@ static void bbr_probe_inflight_hi_upward(ngtcp2_cc_bbr *bbr,
static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
-static int bbr_check_time_to_probe_bw(ngtcp2_cc_bbr *bbr,
- ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts);
+static int bbr_is_time_to_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
+ ngtcp2_tstamp ts);
static void bbr_pick_probe_wait(ngtcp2_cc_bbr *bbr);
@@ -197,6 +197,8 @@ static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat,
const ngtcp2_rs *rs, ngtcp2_tstamp ts);
+static void bbr_note_loss(ngtcp2_cc_bbr *bbr);
+
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts);
@@ -227,15 +229,14 @@ static void bbr_handle_restart_from_idle(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat,
ngtcp2_tstamp ts);
-static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t bw,
- uint64_t gain_h);
+static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h);
static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat,
uint64_t inflight);
static uint64_t bbr_inflight(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- uint64_t bw, uint64_t gain_h);
+ uint64_t gain_h);
static void bbr_update_max_inflight(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat);
@@ -247,10 +248,6 @@ static uint64_t min_pipe_cwnd(size_t max_udp_payload_size);
static void bbr_advance_max_bw_filter(ngtcp2_cc_bbr *bbr);
-static void bbr_modulate_cwnd_for_recovery(ngtcp2_cc_bbr *bbr,
- ngtcp2_conn_stat *cstat,
- const ngtcp2_cc_ack *ack);
-
static void bbr_save_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
static void bbr_restore_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat);
@@ -272,7 +269,7 @@ static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
ngtcp2_tstamp sent_time);
static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts);
+ const ngtcp2_cc_ack *ack);
static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
ngtcp2_tstamp initial_ts) {
@@ -289,11 +286,12 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
bbr->idle_restart = 0;
bbr->extra_acked_interval_start = initial_ts;
bbr->extra_acked_delivered = 0;
+ bbr->full_bw_reached = 0;
bbr_reset_congestion_signals(bbr);
bbr_reset_lower_bounds(bbr);
bbr_init_round_counting(bbr);
- bbr_init_full_pipe(bbr);
+ bbr_reset_full_bw(bbr);
bbr_init_pacing_rate(bbr, cstat);
bbr_enter_startup(bbr);
@@ -326,23 +324,17 @@ static void bbr_on_init(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
bbr->bw_probe_up_acks = 0;
bbr->inflight_hi = UINT64_MAX;
- bbr->bw_hi = UINT64_MAX;
bbr->probe_rtt_expired = 0;
bbr->probe_rtt_min_delay = UINT64_MAX;
bbr->probe_rtt_min_stamp = initial_ts;
bbr->in_loss_recovery = 0;
- bbr->packet_conservation = 0;
+ bbr->round_count_at_recovery = UINT64_MAX;
bbr->max_inflight = 0;
bbr->congestion_recovery_start_ts = UINT64_MAX;
- bbr->congestion_recovery_next_round_delivered = 0;
-
- bbr->prior_inflight_lo = 0;
- bbr->prior_inflight_hi = 0;
- bbr->prior_bw_lo = 0;
}
static void bbr_reset_congestion_signals(ngtcp2_cc_bbr *bbr) {
@@ -362,48 +354,53 @@ static void bbr_init_round_counting(ngtcp2_cc_bbr *bbr) {
bbr->round_count = 0;
}
-static void bbr_init_full_pipe(ngtcp2_cc_bbr *bbr) {
- bbr->filled_pipe = 0;
+static void bbr_reset_full_bw(ngtcp2_cc_bbr *bbr) {
bbr->full_bw = 0;
bbr->full_bw_count = 0;
+ bbr->full_bw_now = 0;
}
-static void bbr_check_startup_full_bandwidth(ngtcp2_cc_bbr *bbr) {
- if (bbr->filled_pipe || !bbr->round_start || bbr->rst->rs.is_app_limited) {
+static void bbr_check_full_bw_reached(ngtcp2_cc_bbr *bbr,
+ ngtcp2_conn_stat *cstat) {
+ if (bbr->full_bw_now || bbr->rst->rs.is_app_limited) {
return;
}
- if (bbr->max_bw * 100 >= bbr->full_bw * 125) {
- bbr->full_bw = bbr->max_bw;
- bbr->full_bw_count = 0;
- }
+ if (cstat->delivery_rate_sec * 100 >= bbr->full_bw * 125) {
+ bbr_reset_full_bw(bbr);
+ bbr->full_bw = cstat->delivery_rate_sec;
- ++bbr->full_bw_count;
-
- if (bbr->full_bw_count >= 3) {
- bbr->filled_pipe = 1;
-
- ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
- "bbr filled pipe, full_bw=%" PRIu64, bbr->full_bw);
+ return;
}
-}
-static void bbr_check_startup_high_loss(ngtcp2_cc_bbr *bbr,
- const ngtcp2_cc_ack *ack) {
- if (bbr->filled_pipe || !bbr->round_start || bbr->rst->rs.is_app_limited) {
+ if (!bbr->round_start) {
return;
}
- if (bbr->loss_events_in_round <= 3) {
+ ++bbr->full_bw_count;
+
+ bbr->full_bw_now = bbr->full_bw_count >= 3;
+ if (!bbr->full_bw_now) {
return;
}
- /* loss_thresh = 2% */
- if (bbr->bytes_lost_in_round * 100 <= ack->prior_bytes_in_flight * 2) {
+ bbr->full_bw_reached = 1;
+
+ ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA,
+ "bbr reached full bandwidth, full_bw=%" PRIu64, bbr->full_bw);
+}
+
+static void bbr_check_startup_high_loss(ngtcp2_cc_bbr *bbr) {
+ if (bbr->full_bw_reached || bbr->loss_events_in_round <= 6 ||
+ (bbr->in_loss_recovery &&
+ bbr->round_count <= bbr->round_count_at_recovery) ||
+ !is_inflight_too_high(&bbr->rst->rs)) {
return;
}
- bbr->filled_pipe = 1;
+ bbr->full_bw_reached = 1;
+ bbr->inflight_hi = ngtcp2_max_uint64(bbr_bdp_multiple(bbr, bbr->cwnd_gain_h),
+ bbr->inflight_latest);
}
static void bbr_init_pacing_rate(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
@@ -423,7 +420,7 @@ static void bbr_set_pacing_rate_with_gain(ngtcp2_cc_bbr *bbr,
interval = NGTCP2_SECONDS * 100 * 100 / pacing_gain_h / bbr->bw /
(100 - NGTCP2_BBR_PACING_MARGIN_PERCENT);
- if (bbr->filled_pipe || interval < cstat->pacing_interval) {
+ if (bbr->full_bw_reached || interval < cstat->pacing_interval) {
cstat->pacing_interval = interval;
}
}
@@ -437,15 +434,13 @@ static void bbr_enter_startup(ngtcp2_cc_bbr *bbr) {
bbr->state = NGTCP2_BBR_STATE_STARTUP;
bbr->pacing_gain_h = NGTCP2_BBR_STARTUP_PACING_GAIN_H;
- bbr->cwnd_gain_h = NGTCP2_BBR_STARTUP_CWND_GAIN_H;
+ bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
}
-static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr,
- const ngtcp2_cc_ack *ack) {
- bbr_check_startup_full_bandwidth(bbr);
- bbr_check_startup_high_loss(bbr, ack);
+static void bbr_check_startup_done(ngtcp2_cc_bbr *bbr) {
+ bbr_check_startup_high_loss(bbr);
- if (bbr->state == NGTCP2_BBR_STATE_STARTUP && bbr->filled_pipe) {
+ if (bbr->state == NGTCP2_BBR_STATE_STARTUP && bbr->full_bw_reached) {
bbr_enter_drain(bbr);
}
}
@@ -468,7 +463,8 @@ static void bbr_update_model_and_state(ngtcp2_cc_bbr *bbr,
bbr_update_latest_delivery_signals(bbr, cstat);
bbr_update_congestion_signals(bbr, cstat, ack);
bbr_update_ack_aggregation(bbr, cstat, ack, ts);
- bbr_check_startup_done(bbr, ack);
+ bbr_check_full_bw_reached(bbr, cstat);
+ bbr_check_startup_done(bbr);
bbr_check_drain(bbr, cstat, ts);
bbr_update_probe_bw_cycle_phase(bbr, cstat, ack, ts);
bbr_update_min_rtt(bbr, ack, ts);
@@ -519,11 +515,6 @@ static void bbr_update_congestion_signals(ngtcp2_cc_bbr *bbr,
if (ack->bytes_lost) {
bbr->bytes_lost_in_round += ack->bytes_lost;
++bbr->loss_events_in_round;
-
- if (!bbr->loss_in_round) {
- bbr->loss_in_round = 1;
- bbr->loss_round_delivered = bbr->rst->delivered;
- }
}
if (!bbr->loss_round_start) {
@@ -568,7 +559,6 @@ static void bbr_loss_lower_bounds(ngtcp2_cc_bbr *bbr) {
static void bbr_bound_bw_for_model(ngtcp2_cc_bbr *bbr) {
bbr->bw = ngtcp2_min_uint64(bbr->max_bw, bbr->bw_lo);
- bbr->bw = ngtcp2_min_uint64(bbr->bw, bbr->bw_hi);
}
static void bbr_update_max_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
@@ -636,6 +626,12 @@ static void bbr_update_ack_aggregation(ngtcp2_cc_bbr *bbr,
extra = bbr->extra_acked_delivered - expected_delivered;
extra = ngtcp2_min_uint64(extra, cstat->cwnd);
+ if (bbr->full_bw_reached) {
+ bbr->extra_acked_filter.window_length = NGTCP2_BBR_EXTRA_ACKED_FILTERLEN;
+ } else {
+ bbr->extra_acked_filter.window_length = 1;
+ }
+
ngtcp2_window_filter_update(&bbr->extra_acked_filter, extra,
bbr->round_count);
@@ -646,14 +642,14 @@ static void bbr_enter_drain(ngtcp2_cc_bbr *bbr) {
ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr enter Drain");
bbr->state = NGTCP2_BBR_STATE_DRAIN;
- bbr->pacing_gain_h = 100 * 100 / NGTCP2_BBR_STARTUP_CWND_GAIN_H;
- bbr->cwnd_gain_h = NGTCP2_BBR_STARTUP_CWND_GAIN_H;
+ bbr->pacing_gain_h = NGTCP2_BBR_DRAIN_PACING_GAIN_H;
+ bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
}
static void bbr_check_drain(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
ngtcp2_tstamp ts) {
if (bbr->state == NGTCP2_BBR_STATE_DRAIN &&
- cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, bbr->bw, 100)) {
+ cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
bbr_enter_probe_bw(bbr, ts);
}
}
@@ -678,7 +674,7 @@ static void bbr_start_probe_bw_down(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
bbr->state = NGTCP2_BBR_STATE_PROBE_BW_DOWN;
bbr->pacing_gain_h = 90;
- bbr->cwnd_gain_h = 200;
+ bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
}
static void bbr_start_probe_bw_cruise(ngtcp2_cc_bbr *bbr) {
@@ -687,7 +683,7 @@ static void bbr_start_probe_bw_cruise(ngtcp2_cc_bbr *bbr) {
bbr->state = NGTCP2_BBR_STATE_PROBE_BW_CRUISE;
bbr->pacing_gain_h = 100;
- bbr->cwnd_gain_h = 200;
+ bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
}
static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr) {
@@ -704,18 +700,18 @@ static void bbr_start_probe_bw_refill(ngtcp2_cc_bbr *bbr) {
bbr->state = NGTCP2_BBR_STATE_PROBE_BW_REFILL;
bbr->pacing_gain_h = 100;
- bbr->cwnd_gain_h = 200;
+ bbr->cwnd_gain_h = NGTCP2_BBR_DEFAULT_CWND_GAIN_H;
}
-static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts) {
+static void bbr_start_probe_bw_up(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
ngtcp2_log_info(bbr->cc.log, NGTCP2_LOG_EVENT_CCA, "bbr start ProbeBW_UP");
bbr->ack_phase = NGTCP2_BBR_ACK_PHASE_ACKS_PROBE_STARTING;
bbr_start_round(bbr);
+ bbr_reset_full_bw(bbr);
- bbr->cycle_stamp = ts;
+ bbr->full_bw = cstat->delivery_rate_sec;
bbr->state = NGTCP2_BBR_STATE_PROBE_BW_UP;
bbr->pacing_gain_h = 125;
bbr->cwnd_gain_h = 225;
@@ -727,7 +723,7 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat,
const ngtcp2_cc_ack *ack,
ngtcp2_tstamp ts) {
- if (!bbr->filled_pipe) {
+ if (!bbr->full_bw_reached) {
return;
}
@@ -739,17 +735,17 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
switch (bbr->state) {
case NGTCP2_BBR_STATE_PROBE_BW_DOWN:
- if (bbr_check_time_to_probe_bw(bbr, cstat, ts)) {
+ if (bbr_is_time_to_probe_bw(bbr, cstat, ts)) {
return;
}
- if (bbr_check_time_to_cruise(bbr, cstat, ts)) {
+ if (bbr_is_time_to_cruise(bbr, cstat, ts)) {
bbr_start_probe_bw_cruise(bbr);
}
break;
case NGTCP2_BBR_STATE_PROBE_BW_CRUISE:
- if (bbr_check_time_to_probe_bw(bbr, cstat, ts)) {
+ if (bbr_is_time_to_probe_bw(bbr, cstat, ts)) {
return;
}
@@ -757,13 +753,12 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
case NGTCP2_BBR_STATE_PROBE_BW_REFILL:
if (bbr->round_start) {
bbr->bw_probe_samples = 1;
- bbr_start_probe_bw_up(bbr, cstat, ts);
+ bbr_start_probe_bw_up(bbr, cstat);
}
break;
case NGTCP2_BBR_STATE_PROBE_BW_UP:
- if (bbr_has_elapsed_in_phase(bbr, bbr->min_rtt, ts) &&
- cstat->bytes_in_flight > bbr_inflight(bbr, cstat, bbr->max_bw, 125)) {
+ if (bbr_is_time_to_go_down(bbr, cstat)) {
bbr_start_probe_bw_down(bbr, ts);
}
@@ -773,15 +768,26 @@ static void bbr_update_probe_bw_cycle_phase(ngtcp2_cc_bbr *bbr,
}
}
-static int bbr_check_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts) {
+static int bbr_is_time_to_cruise(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
+ ngtcp2_tstamp ts) {
(void)ts;
if (cstat->bytes_in_flight > bbr_inflight_with_headroom(bbr, cstat)) {
return 0;
}
- if (cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, bbr->max_bw, 100)) {
+ if (cstat->bytes_in_flight <= bbr_inflight(bbr, cstat, 100)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static int bbr_is_time_to_go_down(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
+ if (bbr->rst->is_cwnd_limited && cstat->cwnd >= bbr->inflight_hi) {
+ bbr_reset_full_bw(bbr);
+ bbr->full_bw = cstat->delivery_rate_sec;
+ } else if (bbr->full_bw_now) {
return 1;
}
@@ -861,8 +867,7 @@ static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
}
if (!bbr_check_inflight_too_high(bbr, cstat, ts)) {
- /* bbr->bw_hi never be updated */
- if (bbr->inflight_hi == UINT64_MAX /* || bbr->bw_hi == UINT64_MAX */) {
+ if (bbr->inflight_hi == UINT64_MAX) {
return;
}
@@ -870,19 +875,14 @@ static void bbr_adapt_upper_bounds(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
bbr->inflight_hi = bbr->rst->rs.tx_in_flight;
}
- if (cstat->delivery_rate_sec > bbr->bw_hi) {
- bbr->bw_hi = cstat->delivery_rate_sec;
- }
-
if (bbr->state == NGTCP2_BBR_STATE_PROBE_BW_UP) {
bbr_probe_inflight_hi_upward(bbr, cstat, ack);
}
}
}
-static int bbr_check_time_to_probe_bw(ngtcp2_cc_bbr *bbr,
- ngtcp2_conn_stat *cstat,
- ngtcp2_tstamp ts) {
+static int bbr_is_time_to_probe_bw(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
+ ngtcp2_tstamp ts) {
if (bbr_has_elapsed_in_phase(bbr, bbr->bw_probe_wait, ts) ||
bbr_is_reno_coexistence_probe_time(bbr, cstat)) {
bbr_start_probe_bw_refill(bbr);
@@ -916,7 +916,7 @@ static int bbr_is_reno_coexistence_probe_time(ngtcp2_cc_bbr *bbr,
static uint64_t bbr_target_inflight(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat) {
- uint64_t bdp = bbr_inflight(bbr, cstat, bbr->bw, 100);
+ uint64_t bdp = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h);
return ngtcp2_min_uint64(bdp, cstat->cwnd);
}
@@ -957,10 +957,21 @@ static void bbr_handle_inflight_too_high(ngtcp2_cc_bbr *bbr,
}
}
+static void bbr_note_loss(ngtcp2_cc_bbr *bbr) {
+ if (bbr->loss_in_round) {
+ return;
+ }
+
+ bbr->loss_in_round = 1;
+ bbr->loss_round_delivered = bbr->rst->delivered;
+}
+
static void bbr_handle_lost_packet(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
ngtcp2_rs rs = {0};
+ bbr_note_loss(bbr);
+
if (!bbr->bw_probe_samples) {
return;
}
@@ -1107,7 +1118,7 @@ static void bbr_mark_connection_app_limited(ngtcp2_cc_bbr *bbr,
static void bbr_exit_probe_rtt(ngtcp2_cc_bbr *bbr, ngtcp2_tstamp ts) {
bbr_reset_lower_bounds(bbr);
- if (bbr->filled_pipe) {
+ if (bbr->full_bw_reached) {
bbr_start_probe_bw_down(bbr, ts);
bbr_start_probe_bw_cruise(bbr);
} else {
@@ -1132,15 +1143,14 @@ static void bbr_handle_restart_from_idle(ngtcp2_cc_bbr *bbr,
}
}
-static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t bw,
- uint64_t gain_h) {
+static uint64_t bbr_bdp_multiple(ngtcp2_cc_bbr *bbr, uint64_t gain_h) {
uint64_t bdp;
if (bbr->min_rtt == UINT64_MAX) {
return bbr->initial_cwnd;
}
- bdp = bw * bbr->min_rtt / NGTCP2_SECONDS;
+ bdp = bbr->bw * bbr->min_rtt / NGTCP2_SECONDS;
return (uint64_t)(bdp * gain_h / 100);
}
@@ -1166,8 +1176,8 @@ static uint64_t bbr_quantization_budget(ngtcp2_cc_bbr *bbr,
}
static uint64_t bbr_inflight(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- uint64_t bw, uint64_t gain_h) {
- uint64_t inflight = bbr_bdp_multiple(bbr, bw, gain_h);
+ uint64_t gain_h) {
+ uint64_t inflight = bbr_bdp_multiple(bbr, gain_h);
return bbr_quantization_budget(bbr, cstat, inflight);
}
@@ -1179,8 +1189,7 @@ static void bbr_update_max_inflight(ngtcp2_cc_bbr *bbr,
/* Not documented */
/* bbr_update_aggregation_budget(bbr); */
- inflight =
- bbr_bdp_multiple(bbr, bbr->bw, bbr->cwnd_gain_h) + bbr->extra_acked;
+ inflight = bbr_bdp_multiple(bbr, bbr->cwnd_gain_h) + bbr->extra_acked;
bbr->max_inflight = bbr_quantization_budget(bbr, cstat, inflight);
}
@@ -1193,25 +1202,6 @@ static void bbr_advance_max_bw_filter(ngtcp2_cc_bbr *bbr) {
++bbr->cycle_count;
}
-static void bbr_modulate_cwnd_for_recovery(ngtcp2_cc_bbr *bbr,
- ngtcp2_conn_stat *cstat,
- const ngtcp2_cc_ack *ack) {
- if (ack->bytes_lost > 0) {
- if (cstat->cwnd > ack->bytes_lost) {
- cstat->cwnd -= ack->bytes_lost;
- cstat->cwnd =
- ngtcp2_max_uint64(cstat->cwnd, 2 * cstat->max_tx_udp_payload_size);
- } else {
- cstat->cwnd = 2 * cstat->max_tx_udp_payload_size;
- }
- }
-
- if (bbr->packet_conservation) {
- cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, cstat->bytes_in_flight +
- ack->bytes_delivered);
- }
-}
-
static void bbr_save_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
if (!bbr->in_loss_recovery && bbr->state != NGTCP2_BBR_STATE_PROBE_RTT) {
bbr->prior_cwnd = cstat->cwnd;
@@ -1228,7 +1218,7 @@ static void bbr_restore_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
static uint64_t bbr_probe_rtt_cwnd(ngtcp2_cc_bbr *bbr,
ngtcp2_conn_stat *cstat) {
uint64_t probe_rtt_cwnd =
- bbr_bdp_multiple(bbr, bbr->bw, NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H);
+ bbr_bdp_multiple(bbr, NGTCP2_BBR_PROBE_RTT_CWND_GAIN_H);
uint64_t mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
return ngtcp2_max_uint64(probe_rtt_cwnd, mpcwnd);
@@ -1250,21 +1240,18 @@ static void bbr_set_cwnd(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
uint64_t mpcwnd;
bbr_update_max_inflight(bbr, cstat);
- bbr_modulate_cwnd_for_recovery(bbr, cstat, ack);
-
- if (!bbr->packet_conservation) {
- if (bbr->filled_pipe) {
- cstat->cwnd += ack->bytes_delivered;
- cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, bbr->max_inflight);
- } else if (cstat->cwnd < bbr->max_inflight ||
- bbr->rst->delivered < bbr->initial_cwnd) {
- cstat->cwnd += ack->bytes_delivered;
- }
- mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
- cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, mpcwnd);
+ if (bbr->full_bw_reached) {
+ cstat->cwnd += ack->bytes_delivered;
+ cstat->cwnd = ngtcp2_min_uint64(cstat->cwnd, bbr->max_inflight);
+ } else if (cstat->cwnd < bbr->max_inflight ||
+ bbr->rst->delivered < bbr->initial_cwnd) {
+ cstat->cwnd += ack->bytes_delivered;
}
+ mpcwnd = min_pipe_cwnd(cstat->max_tx_udp_payload_size);
+ cstat->cwnd = ngtcp2_max_uint64(cstat->cwnd, mpcwnd);
+
bbr_bound_cwnd_for_probe_rtt(bbr, cstat);
bbr_bound_cwnd_for_model(bbr, cstat);
}
@@ -1289,23 +1276,16 @@ static void bbr_bound_cwnd_for_model(ngtcp2_cc_bbr *bbr,
}
static void bbr_set_send_quantum(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat) {
- size_t floor, send_quantum;
+ size_t send_quantum = 64 * 1024;
(void)bbr;
- if (cstat->pacing_interval > (NGTCP2_SECONDS * 8 * 10 / 12) >> 20) {
- floor = cstat->max_tx_udp_payload_size;
- } else {
- floor = 2 * cstat->max_tx_udp_payload_size;
- }
-
if (cstat->pacing_interval) {
- send_quantum = (size_t)(NGTCP2_MILLISECONDS / cstat->pacing_interval);
- send_quantum = ngtcp2_min_size(send_quantum, 64 * 1024);
- } else {
- send_quantum = 64 * 1024;
+ send_quantum = ngtcp2_min_size(
+ send_quantum, (size_t)(NGTCP2_MILLISECONDS / cstat->pacing_interval));
}
- cstat->send_quantum = ngtcp2_max_size(send_quantum, floor);
+ cstat->send_quantum =
+ ngtcp2_max_size(send_quantum, 2 * cstat->max_tx_udp_payload_size);
}
static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
@@ -1315,16 +1295,12 @@ static int in_congestion_recovery(const ngtcp2_conn_stat *cstat,
}
static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
- const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
+ const ngtcp2_cc_ack *ack) {
if (bbr->in_loss_recovery) {
- if (ts - cstat->congestion_recovery_start_ts >= cstat->smoothed_rtt) {
- bbr->packet_conservation = 0;
- }
-
if (ack->largest_pkt_sent_ts != UINT64_MAX &&
!in_congestion_recovery(cstat, ack->largest_pkt_sent_ts)) {
bbr->in_loss_recovery = 0;
- bbr->packet_conservation = 0;
+ bbr->round_count_at_recovery = UINT64_MAX;
bbr_restore_cwnd(bbr, cstat);
}
@@ -1333,6 +1309,8 @@ static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
if (bbr->congestion_recovery_start_ts != UINT64_MAX) {
bbr->in_loss_recovery = 1;
+ bbr->round_count_at_recovery =
+ bbr->round_start ? bbr->round_count : bbr->round_count + 1;
bbr_save_cwnd(bbr, cstat);
cstat->cwnd =
cstat->bytes_in_flight +
@@ -1340,11 +1318,6 @@ static void bbr_handle_recovery(ngtcp2_cc_bbr *bbr, ngtcp2_conn_stat *cstat,
cstat->congestion_recovery_start_ts = bbr->congestion_recovery_start_ts;
bbr->congestion_recovery_start_ts = UINT64_MAX;
- bbr->packet_conservation = 1;
- bbr->congestion_recovery_next_round_delivered = bbr->rst->delivered;
- bbr->prior_inflight_hi = bbr->inflight_hi;
- bbr->prior_inflight_lo = bbr->inflight_lo;
- bbr->prior_bw_lo = bbr->bw_lo;
}
}
@@ -1352,6 +1325,10 @@ static void bbr_cc_on_pkt_lost(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_pkt *pkt, ngtcp2_tstamp ts) {
ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
+ if (bbr->state == NGTCP2_BBR_STATE_STARTUP) {
+ return;
+ }
+
bbr_update_on_loss(bbr, cstat, pkt, ts);
}
@@ -1379,15 +1356,8 @@ static void bbr_cc_on_spurious_congestion(ngtcp2_cc *cc,
if (bbr->in_loss_recovery) {
bbr->in_loss_recovery = 0;
- bbr->packet_conservation = 0;
+ bbr->round_count_at_recovery = UINT64_MAX;
bbr_restore_cwnd(bbr, cstat);
- bbr->full_bw_count = 0;
- bbr->loss_in_round = 0;
- bbr->inflight_lo =
- ngtcp2_max_uint64(bbr->inflight_lo, bbr->prior_inflight_lo);
- bbr->inflight_hi =
- ngtcp2_max_uint64(bbr->inflight_hi, bbr->prior_inflight_hi);
- bbr->bw_lo = ngtcp2_max_uint64(bbr->bw_lo, bbr->prior_bw_lo);
}
}
@@ -1400,7 +1370,7 @@ static void bbr_cc_on_persistent_congestion(ngtcp2_cc *cc,
cstat->congestion_recovery_start_ts = UINT64_MAX;
bbr->congestion_recovery_start_ts = UINT64_MAX;
bbr->in_loss_recovery = 0;
- bbr->packet_conservation = 0;
+ bbr->round_count_at_recovery = UINT64_MAX;
bbr_save_cwnd(bbr, cstat);
cstat->cwnd = cstat->bytes_in_flight + cstat->max_tx_udp_payload_size;
@@ -1412,7 +1382,7 @@ static void bbr_cc_on_ack_recv(ngtcp2_cc *cc, ngtcp2_conn_stat *cstat,
const ngtcp2_cc_ack *ack, ngtcp2_tstamp ts) {
ngtcp2_cc_bbr *bbr = ngtcp2_struct_of(cc, ngtcp2_cc_bbr, cc);
- bbr_handle_recovery(bbr, cstat, ack, ts);
+ bbr_handle_recovery(bbr, cstat, ack);
bbr_update_on_ack(bbr, cstat, ack, ts);
}