-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6577cc5
commit 51100c1
Showing
5 changed files
with
305 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* Rate sample. */ | ||
struct quic_rs { | ||
uint64_t delivered; | ||
uint64_t prior_delivered; | ||
uint32_t interval; | ||
uint32_t prior_time; | ||
uint32_t send_elapsed; | ||
uint32_t ack_elapsed; | ||
uint32_t is_app_limited; | ||
}; | ||
|
||
/* Delivery rate sampling. */ | ||
struct quic_drs { | ||
struct quic_rs rs; | ||
uint64_t delivered; | ||
uint64_t lost; | ||
int app_limited; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
#include <inttypes.h> | ||
|
||
#include <haproxy/quic_cc.h> | ||
#include <haproxy/ticks.h> | ||
#include <haproxy/window_filter.h> | ||
|
||
/* XXX TO BE REMOVED */ | ||
#define true 1 | ||
#define false 0 | ||
|
||
#define BBR_STARTUP_PACING_GAIN 277 /* percent: 4 * ln(2)=2.77 */ | ||
#define BBR_STARTUP_CWND_GAIN 200 /* percent */ | ||
|
||
/* BBRLossThresh (2%) */ | ||
#define BBR_LOSS_THRESH_MULT 2 | ||
#define BBR_LOSS_THRESH_DIVI 100 | ||
/* BBRBeta (0.7) */ | ||
#define BBR_BETA_MULT 7 | ||
#define BBR_BETA_DIVI 10 | ||
/* BBRHeadroom (0.15) */ | ||
#define BBR_HEADROOM_MULT 15 | ||
#define BBR_HEADROOM_DIVI 100 | ||
|
||
#define BBR_MAX_BW_FILTERLEN 2 | ||
#define BBR_EXTRA_ACKED_FILTERLEN 10 | ||
|
||
#define BBR_MIN_RTT_FILTERLEN 10000 /* ms */ | ||
#define BBR_PROBE_RTT_CWND_GAIN 50 /* 50% */ | ||
#define BBR_PROBE_RTT_DURATION 200 /* ms */ | ||
#define BBR_PROBE_RTT_INTERVAL 5000 /* ms */ | ||
|
||
/* 4.1.1: State Transition Diagram */ | ||
/* BBR state */ | ||
enum bbr_state { | ||
BBR_ST_STARTUP, | ||
BBR_ST_DRAIN, | ||
BBR_ST_PROBE_BW_DOWN, | ||
BBR_ST_PROBE_BW_CRUISE, | ||
BBR_ST_PROBE_BW_REFILL, | ||
BBR_ST_PROBE_BW_UP, | ||
BBR_ST_PROBE_RTT, | ||
}; | ||
|
||
struct bbr { | ||
/* 2.4 Output Control Parameters */ | ||
uint64_t pacing_rate; | ||
uint64_t send_quantum; | ||
/* 2.5 Pacing State and Parameters */ | ||
uint64_t pacing_gain; | ||
//uint32_t next_departure_time; /* XXX check this XXX */ | ||
/* 2.6. cwnd State and Parameters */ | ||
uint64_t cwnd_gain; | ||
/* 2.7 General Algorithm State */ | ||
enum bbr_state state; | ||
uint64_t round_count; | ||
int round_start; /* boolean */ | ||
uint64_t next_round_delivered; | ||
int idle_restart; /* boolean */ | ||
/* 2.9.1 Data Rate Network Path Model Parameters */ | ||
uint64_t max_bw; | ||
uint64_t bw_lo; | ||
uint64_t bw; | ||
uint64_t prior_cwnd; | ||
/* 2.9.2 Data Volume Network Path Model Parameters */ | ||
uint32_t min_rtt; | ||
uint64_t extra_acked; | ||
uint64_t offload_budget; | ||
uint64_t max_inflight; | ||
uint64_t inflight_hi; | ||
uint64_t inflight_lo; | ||
/* 2.10 State for Responding to Congestion */ | ||
uint64_t bw_latest; | ||
uint64_t loss_in_round; | ||
uint64_t inflight_latest; | ||
/* 2.11 Estimating BBR.max_bw */ | ||
struct window_filter max_bw_filter; | ||
uint64_t cycle_count; | ||
/* 2.12 Estimating BBR.extra_acked */ | ||
uint32_t extra_acked_interval_start; | ||
uint64_t extra_acked_delivered; | ||
struct window_filter extra_acked_filter; | ||
/* 2.13 Startup Parameters and State */ | ||
int full_bw_reached; /* boolean */ | ||
int full_bw_now; /* boolean */ | ||
uint64_t full_bw; | ||
int full_bw_count; | ||
/* 2.14 ProbeRTT and min_rtt Parameters and State */ | ||
/* 2.14.1 Parameters for Estimating BBR.min_rtt */ | ||
uint32_t min_rtt_stamp; | ||
/* 2.14.2 Parameters for Scheduling ProbeRTT */ | ||
uint32_t probe_rtt_min_delay; /* ms */ | ||
uint32_t probe_rtt_min_stamp; /* ms */ | ||
uint32_t probe_rtt_done_stamp; | ||
int probe_rtt_round_done; /* boolean */ | ||
int probe_rtt_expired; /* boolean */ | ||
}; | ||
|
||
static void bbr_reset_congestion_signals(struct bbr *bbr) | ||
{ | ||
bbr->loss_in_round = 0; | ||
bbr->bw_latest = 0; | ||
bbr->inflight_latest = 0; | ||
} | ||
|
||
static void bbr_reset_lower_bounds(struct bbr *bbr) | ||
{ | ||
bbr->bw_lo = UINT64_MAX; | ||
bbr->inflight_lo = UINT64_MAX; | ||
} | ||
|
||
static void bbr_init_round_counting(struct bbr *bbr) | ||
{ | ||
bbr->next_round_delivered = 0; | ||
bbr->round_start = false; | ||
bbr->round_count = 0; | ||
} | ||
|
||
static void bbr_reset_full_bw(struct bbr *bbr) | ||
{ | ||
bbr->full_bw = 0; | ||
bbr->full_bw_count = 0; | ||
bbr->full_bw_now = false; | ||
} | ||
|
||
static void bbr_init_pacing_rate(struct bbr *bbr) | ||
{ | ||
/* XXX Not clear at this time XXX */ | ||
} | ||
|
||
static void bbr_enter_startup(struct bbr *bbr) | ||
{ | ||
bbr->state = BBR_ST_STARTUP; | ||
bbr->pacing_gain = BBR_STARTUP_PACING_GAIN; | ||
bbr->cwnd_gain = BBR_STARTUP_CWND_GAIN; | ||
} | ||
|
||
static int quic_cc_bbr_init(struct quic_cc *cc) | ||
{ | ||
struct bbr *bbr = quic_cc_priv(cc); | ||
|
||
window_filter_init(&bbr->max_bw_filter, BBR_MAX_BW_FILTERLEN); | ||
window_filter_init(&bbr->extra_acked_filter, BBR_EXTRA_ACKED_FILTERLEN); | ||
/* InitWindowedMaxFilter() */ | ||
bbr->min_rtt = 1; /* ms */ /* XXX check this XXX */ | ||
bbr->min_rtt_stamp = now_ms; | ||
bbr->probe_rtt_done_stamp = TICK_ETERNITY; /* XXX check this XXX */ | ||
bbr->probe_rtt_round_done = false; | ||
bbr->prior_cwnd = 0; | ||
bbr->idle_restart = false; | ||
bbr->extra_acked_interval_start = now_ms; | ||
bbr->extra_acked_delivered = 0; | ||
bbr->full_bw_reached = false; | ||
|
||
bbr_reset_congestion_signals(bbr); | ||
bbr_reset_lower_bounds(bbr); | ||
bbr_init_round_counting(bbr); | ||
bbr_reset_full_bw(bbr); | ||
bbr_init_pacing_rate(bbr); | ||
bbr_enter_startup(bbr); | ||
|
||
/* Not in RFC */ | ||
bbr->send_quantum = 0; /* XXX check this */ | ||
bbr->max_bw = 0; | ||
bbr->bw = 0; | ||
bbr->extra_acked = 0; | ||
bbr->offload_budget = 0; | ||
bbr->max_inflight = 0; | ||
bbr->inflight_hi = UINT64_MAX; | ||
bbr->cycle_count = 0; | ||
bbr->probe_rtt_min_delay = TICK_ETERNITY; | ||
bbr->probe_rtt_min_stamp = now_ms; | ||
bbr->probe_rtt_expired = false; | ||
|
||
return 1; | ||
} | ||
|
||
static void bbr_handle_restart_from_idle(struct bbr *bbr) | ||
{ | ||
} | ||
|
||
static void bbr_on_transmit(struct bbr *bbr) | ||
{ | ||
bbr_handle_restart_from_idle(bbr); | ||
} | ||
|
||
static bbr_check_startup_high_loss() | ||
{ | ||
} | ||
|
||
static void bbr_check_startup_done(struct bbr *bbr) | ||
{ | ||
bbr_check_startup_high_loss(); | ||
if (bbr->state == BBR_ST_STARTUP and bbr->full_bw_reached) | ||
bbr_enter_drain(); | ||
} | ||
|
||
static void bbr_update_model_and_state() | ||
{ | ||
bbr_update_latest_delivery_signals(); | ||
bbr_update_congestion_signals(); | ||
bbr_update_ack_aggregation(); | ||
bbr_check_full_bw_reached(); | ||
bbr_check_startup_done(); | ||
bbr_check_drain_done(); | ||
bbr_update_probe_bw_cycle_phase(); | ||
bbr_update_min_rtt(); | ||
bbr_check_probe_rtt(); | ||
bbr_advance_latest_delivery_signals(); | ||
bbr_bound_bw_for_model(); | ||
} | ||
|
||
static void bbr_update_control_parameters() | ||
{ | ||
bbr_set_pacing_rate(); | ||
bbr_set_send_quantum(); | ||
bbr_set_cwnd(); | ||
} | ||
|
||
static void bbr_update_on_ack() | ||
{ | ||
bbr_update_model_and_state(); | ||
bbr_update_control_parameters(); | ||
} | ||
|
||
static void bbr_note_loss(struct bbr *bbr) | ||
{ | ||
if (!bbr->loss_in_round) /* first loss in this round trip? */ | ||
bbr->loss_round_delivered = C.delivered; | ||
bbr->loss_in_round = 1; | ||
} | ||
|
||
/* At what prefix of packet did losses exceed BBRLossThresh? */ | ||
static uint64_t bbr_inflight_hi_from_lost_packet(struct quic *rs, packet) | ||
{ | ||
size = packet.size; | ||
/* What was in flight before this packet? */ | ||
inflight_prev = rs->tx_in_flight - size; | ||
/* What was lost before this packet? */ | ||
lost_prev = rs->lost - size; | ||
lost_prefix = (BBR_LOSS_THRESH * inflight_prev - lost_prev) / | ||
(1 - BBR_LOSS_THRESH); | ||
/* At what inflight value did losses cross BBRLossThresh? */ | ||
inflight = inflight_prev + lost_prefix; | ||
|
||
return inflight; | ||
} | ||
|
||
static bbr_handle_lost_packet(packet) | ||
{ | ||
struct quic_rs *rs; | ||
|
||
bbr_note_loss(); | ||
if (!bbr->bw_probe_samples) | ||
return /* not a packet sent while probing bandwidth */ | ||
|
||
rs->tx_in_flight = packet.tx_in_flight; /* inflight at transmit */ | ||
rs->lost = C.lost - packet.lost; /* data lost since transmit */ | ||
rs->is_app_limited = packet.is_app_limited; | ||
if (is_flight_too_high(rs)) { | ||
rs->tx_in_flight = bbr_inflight_hi_from_lost_packet(rs, packet); | ||
bbr_handle_inflight_too_high(rs) | ||
} | ||
} | ||
|
||
static bbr_update_on_loss(packet) | ||
{ | ||
bbr_handle_lost_packet(packet); | ||
} | ||
|
||
struct quic_cc_algo quic_cc_algo_bbr = { | ||
.type = QUIC_CC_ALGO_TP_BBR, | ||
.init = quic_cc_bbr_init, | ||
}; | ||
|
||
void quic_cc_bbr_check(void) | ||
{ | ||
struct quic_cc *cc; | ||
BUG_ON_HOT(sizeof(struct bbr) > sizeof(cc->priv)); | ||
} | ||
|
||
INITCALL0(STG_REGISTER, quic_cc_bbr_check); |