BUG/MINOR: quic: Missing application limitations tracking for BBR

The ->app_limited member of the delivery rate struct (quic_cc_drs) aim is to
store the index of the last transmitted byte marked as application-limited
so that to track the application-limited phases. During these phases,
BBR must ignore delivery rate samples to properly estimate the delivery rate.

Without such a patch, the Startup phase could be exited very quickly with
a very low estimated bottleneck bandwidth. This had a very bad impact
on little objects with download times smaller than the expected Startup phase
duration. For such objects, with enough bandwith, BBR should stay in the Startup
state.

No need to be backported, as BBR is implemented in the current developement version.
This commit is contained in:
Frederic Lecaille 2024-11-21 15:39:04 +01:00
parent 95d3edd68f
commit 01fcbd6c08
3 changed files with 24 additions and 0 deletions

View File

@ -152,6 +152,7 @@ struct quic_cc_algo {
void (*on_pkt_lost)(struct quic_cc *cc,
struct quic_tx_packet *pkt, uint32_t lost_bytes);
void (*congestion_event)(struct quic_cc *cc, uint32_t ts);
void (*check_app_limited)(const struct quic_cc *cc, int sent);
};
#endif /* USE_QUIC */

View File

@ -1481,6 +1481,23 @@ uint bbr_pacing_burst(const struct quic_cc *cc)
return p->send_quantum / p->mtu;
}
/* Update the delivery rate sampling state about the application limitation. */
static void bbr_check_app_limited(const struct quic_cc *cc, int sent)
{
struct bbr *bbr = quic_cc_priv(cc);
struct quic_cc_drs *drs = &bbr->drs;
struct quic_cc_path *p = container_of(cc, struct quic_cc_path, cc);
if (p->in_flight >= p->cwnd) {
drs->is_cwnd_limited = 1;
}
else if (!sent) {
drs->app_limited = drs->delivered + p->in_flight;
if (!drs->app_limited)
drs->app_limited = p->mtu;
}
}
static inline const char *bbr_state_str(struct bbr *bbr)
{
switch (bbr->state) {
@ -1525,6 +1542,7 @@ struct quic_cc_algo quic_cc_algo_bbr = {
.on_ack_rcvd = bbr_update_on_ack,
.congestion_event = bbr_congestion_event,
.on_pkt_lost = bbr_update_on_loss,
.check_app_limited = bbr_check_app_limited,
.state_cli = bbr_state_cli,
};

View File

@ -18,6 +18,7 @@
#include <haproxy/pool.h>
#include <haproxy/trace.h>
#include <haproxy/quic_cc_drs.h>
#include <haproxy/quic_cid.h>
#include <haproxy/quic_conn.h>
#include <haproxy/quic_pacing.h>
@ -506,6 +507,10 @@ enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
qel_register_send(&send_list, qc->ael, frms);
sent = qc_send(qc, 0, &send_list, max_dgram);
if (pacer && qc->path->cc.algo->check_app_limited)
qc->path->cc.algo->check_app_limited(&qc->path->cc, sent);
if (sent <= 0) {
ret = QUIC_TX_ERR_FATAL;
}