Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flags for testing BBR extensions #1749

Merged
merged 9 commits into from
Oct 7, 2024
28 changes: 23 additions & 5 deletions picoquic/bbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@
#include "cc_common.h"
#include "picoquic_utils.h"

#ifdef BBRExperiment
#define BBRExpGate(ctx, test, action) { if (ctx->exp_flags.test) action; }
#define BBRExpTest(ctx, test) ( (ctx)->exp_flags.test )
#else
#define BBRExpGate(ctx, test, action) {}
#define BBRExpTest(ctx, test) (1)
#endif

#define RTTJitterBuffer On
#define RTTJitterBufferStartup On
#define RTTJitterBufferProbe On
Expand Down Expand Up @@ -257,6 +265,10 @@ typedef struct st_picoquic_bbr_state_t {
/* Experimental extensions, may or maynot be a good idea. */
uint64_t wifi_shadow_rtt; /* Shadow RTT used for wifi connections. */
double quantum_ratio; /* allow application to use a different default than 0.1% of bandwidth (or 1ms of traffic) */
#ifdef BBRExperiment
/* Control flags for BBR improvements */
bbr_exp exp_flags;
#endif

} picoquic_bbr_state_t;

Expand Down Expand Up @@ -439,6 +451,11 @@ static void BBROnInit(picoquic_bbr_state_t* bbr_state, picoquic_path_t* path_x,
bbr_state->extra_acked_delivered = 0;
/* Support for the wifi_shadow_rtt hack */
bbr_state->wifi_shadow_rtt = path_x->cnx->quic->wifi_shadow_rtt;

#ifdef BBRExperiment
/* Support for BBR Experiment */
bbr_state->exp_flags = path_x->cnx->quic->bbr_exp_flags;
#endif
/* Support for experimenting with the send_quantum ratio */
bbr_state->quantum_ratio = path_x->cnx->quic->bbr_quantum_ratio;
if (bbr_state->quantum_ratio == 0) {
Expand Down Expand Up @@ -675,7 +692,7 @@ static void BBROnExitRecovery(picoquic_bbr_state_t* bbr_state, picoquic_path_t*
bbr_state->recovery_packet_number = UINT64_MAX;
bbr_state->packet_conservation = 0;

if (bbr_state->is_pto_recovery) {
if (bbr_state->is_pto_recovery && BBRExpTest(bbr_state, do_handle_suspension)) {
/* TODO:
* we should try to enter startup with a high enough BW. However,
* simple attempts to restore the BW parameters have proven ineffective.
Expand Down Expand Up @@ -1639,7 +1656,7 @@ static int BBRCheckTimeToProbeBW(picoquic_bbr_state_t* bbr_state, picoquic_path_
{
if (BBRHasElapsedInPhase(bbr_state, bbr_state->bw_probe_wait, current_time) ||
BBRIsRenoCoexistenceProbeTime(bbr_state, path_x) ||
BBRCheckAppLimitedEnded(bbr_state, rs)) {
(BBRExpTest(bbr_state, do_enter_probeBW_after_limited) && BBRCheckAppLimitedEnded(bbr_state, rs))) {
BBRStartProbeBW_REFILL(bbr_state, path_x);
return 1;
}
Expand All @@ -1654,7 +1671,7 @@ static void BBRStartProbeBW_DOWN(picoquic_bbr_state_t* bbr_state, picoquic_path_
bbr_state->cwnd_gain = BBRProbeBwDownCwndGain; /* maintain cwnd */
BBRResetCongestionSignals(bbr_state);
bbr_state->bw_probe_up_cnt = UINT32_MAX; /* not growing inflight_hi */
if (bbr_state->probe_probe_bw_quickly) {
if (bbr_state->probe_probe_bw_quickly && BBRExpTest(bbr_state, do_rapid_start)) {
BBRPickProbeWaitEarly(bbr_state);
}
else {
Expand Down Expand Up @@ -1762,7 +1779,7 @@ static void BBRUpdateProbeBWCyclePhase(picoquic_bbr_state_t* bbr_state, picoquic

case picoquic_bbr_alg_probe_bw_up:
if (BBRHasElapsedInPhase(bbr_state, bbr_state->min_rtt, current_time) &&
(bbr_state->nb_rtt_excess > 0 ||
((BBRExpTest(bbr_state, do_exit_probeBW_up_on_delay) && bbr_state->nb_rtt_excess > 0) ||
path_x->bytes_in_transit > BBRInflightWithBw(bbr_state, path_x, 1.25, bbr_state->max_bw))) {
BBRStartProbeBW_DOWN(bbr_state, path_x, current_time);
}
Expand Down Expand Up @@ -1902,7 +1919,7 @@ static void BBRCheckStartupDone(picoquic_bbr_state_t* bbr_state,
BBRCheckStartupFullBandwidth(bbr_state, rs);
BBRCheckStartupHighLoss(bbr_state, path_x, rs);
#ifdef RTTJitterBufferStartup
if (IsRTTTooHigh(bbr_state)) {
if (IsRTTTooHigh(bbr_state) && BBRExpTest(bbr_state, do_early_exit)) {
bbr_state->filled_pipe = 1;
}
#endif
Expand Down Expand Up @@ -2287,6 +2304,7 @@ static void picoquic_bbr_notify(
break;
case picoquic_congestion_notification_lost_feedback:
/* Feedback has been lost. It will be restored at the next notification. */
BBRExpGate(bbr_state, do_control_lost, break);
BBREnterLostFeedback(bbr_state, path_x);
break;
case picoquic_congestion_notification_rtt_measurement:
Expand Down
18 changes: 18 additions & 0 deletions picoquic/picoquic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,24 @@ void picoquic_set_default_wifi_shadow_rtt(picoquic_quic_t* quic, uint64_t wifi_s
*/
void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantum_ratio);

/* Temporary code, do define a set of BBR flags that
* turn on and off individual extensions. We want to use that
* to do "before/after" measurements.
*/
#define BBRExperiment on
#ifdef BBRExperiment
/* Control flags for BBR improvements */
typedef struct st_bbr_exp {
unsigned int do_early_exit : 1;
unsigned int do_rapid_start : 1;
unsigned int do_handle_suspension : 1;
unsigned int do_control_lost : 1;
unsigned int do_exit_probeBW_up_on_delay : 1;
unsigned int do_enter_probeBW_after_limited : 1;
} bbr_exp;

void picoquic_set_bbr_exp(picoquic_quic_t * quic, bbr_exp* exp);
#endif
/* The experimental API 'picoquic_set_priority_limit_for_bypass'
* instruct the stack to send the high priority streams or datagrams
* immediately, even if congestion control would normally prevent it.
Expand Down
5 changes: 5 additions & 0 deletions picoquic/picoquic_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,11 @@ typedef struct st_picoquic_quic_t {
struct st_picoquic_unified_logging_t* qlog_fns;
picoquic_performance_log_fn perflog_fn;
void* v_perflog_ctx;

#ifdef BBRExperiment
bbr_exp bbr_exp_flags;
#endif

} picoquic_quic_t;

picoquic_packet_context_enum picoquic_context_from_epoch(int epoch);
Expand Down
18 changes: 17 additions & 1 deletion picoquic/quicctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,17 @@ picoquic_quic_t* picoquic_create(uint32_t max_nb_connections,
}
}
}

#ifdef BBRExperiment
if (ret == 0) {
quic->bbr_exp_flags.do_early_exit = 1;
quic->bbr_exp_flags.do_rapid_start = 1;
quic->bbr_exp_flags.do_handle_suspension = 1;
quic->bbr_exp_flags.do_control_lost = 1;
quic->bbr_exp_flags.do_exit_probeBW_up_on_delay = 1;
quic->bbr_exp_flags.do_enter_probeBW_after_limited = 1;
}
#endif

if (ret != 0) {
picoquic_free(quic);
quic = NULL;
Expand Down Expand Up @@ -4878,6 +4888,12 @@ void picoquic_set_default_bbr_quantum_ratio(picoquic_quic_t* quic, double quantu
quic->bbr_quantum_ratio = quantum_ratio;
}

#ifdef BBRExperiment
void picoquic_set_bbr_exp(picoquic_quic_t* quic, bbr_exp* exp)
{
quic->bbr_exp_flags = *exp;
}
#endif
void picoquic_set_priority_limit_for_bypass(picoquic_cnx_t* cnx, uint8_t priority_limit)
{
cnx->priority_limit_for_bypass = priority_limit;
Expand Down
Loading