]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: Missing application limitations tracking for BBR
authorFrederic Lecaille <flecaille@haproxy.com>
Thu, 21 Nov 2024 14:39:04 +0000 (15:39 +0100)
committerFrederic Lecaille <flecaille@haproxy.com>
Thu, 21 Nov 2024 18:23:53 +0000 (19:23 +0100)
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.

include/haproxy/quic_cc-t.h
src/quic_cc_bbr.c
src/quic_tx.c

index 40ff8890995f1b9cfad4ea701884ce4219e2ef12..c49707533cda2111bcca3bf8eb5990a179f21191 100644 (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 */
index cf95808993f106908216897fb0c85a467624f77b..675de2238fa46162fe4004428475592bb79cf201 100644 (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,
 };
 
index e9dcfd545ccf05c39c6d008cd1fa129fee1036f9..536350eec4fc85b6c3b55c012096f0a122b19415 100644 (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;
        }