]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: account for global congestion window
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 28 Apr 2025 06:52:43 +0000 (08:52 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 29 Apr 2025 13:19:32 +0000 (15:19 +0200)
Use the newly defined cshared type to account for the sum of congestion
window of every QUIC connection. This value is stored in global counter
quic_mem_global defined in proto_quic module.

include/haproxy/proto_quic.h
include/haproxy/quic_cc.h
src/proto_quic.c
src/quic_cc.c
src/quic_conn.c

index b6f473c6d20543d62741cdd78b305d3845d09fe4..1da8da8fe94caa5cfe6768ab5b7368d7e35db89c 100644 (file)
@@ -30,4 +30,6 @@ extern struct protocol proto_quic6;
 
 extern struct quic_dghdlr *quic_dghdlrs;
 
+extern THREAD_LOCAL struct cshared quic_mem_diff;
+
 #endif /* _HAPROXY_PROTO_QUIC_H  */
index 6569799ff640e4d8606c991384c4e6ee7c005f6c..4360a5af0038e0a2748f507aacb4a3f0422864b0 100644 (file)
 #include <haproxy/api.h>
 #include <haproxy/buf.h>
 #include <haproxy/chunk.h>
+#include <haproxy/proto_quic.h>
 #include <haproxy/quic_cc-t.h>
 #include <haproxy/quic_conn-t.h>
 #include <haproxy/quic_loss.h>
+#include <haproxy/thread.h>
 
 void quic_cc_init(struct quic_cc *cc, struct quic_cc_algo *algo, struct quic_conn *qc);
 void quic_cc_event(struct quic_cc *cc, struct quic_cc_event *ev);
@@ -91,6 +93,7 @@ static inline void quic_cc_path_init(struct quic_cc_path *path, int ipv4, unsign
        *(size_t *)&path->mtu = max_dgram_sz;
        path->initial_wnd = QUIC_MIN(10 * max_dgram_sz, QUIC_MAX(max_dgram_sz << 1, 14720U));
        path->cwnd = path->initial_wnd;
+       cshared_add(&quic_mem_diff, path->cwnd);
        path->cwnd_last_max = path->cwnd;
        path->limit_max = max_cwnd;
        path->limit_min = max_dgram_sz << 1;
index a0e9812c7584d19413ac9e9d69e5c3388a871a27..7dfe5fd327946d1da68c1b29832e9561c8bd8798 100644 (file)
 #include <haproxy/sock.h>
 #include <haproxy/sock_inet.h>
 #include <haproxy/task.h>
+#include <haproxy/thread.h>
 #include <haproxy/tools.h>
 
 /* per-thread quic datagram handlers */
 struct quic_dghdlr *quic_dghdlrs;
 
+static uint64_t quic_mem_global;
+THREAD_LOCAL struct cshared quic_mem_diff;
+
 /* Size of the internal buffer of QUIC RX buffer at the fd level */
 #define QUIC_RX_BUFSZ  (1UL << 18)
 
@@ -659,6 +663,14 @@ static void quic_bind_tid_reset(struct connection *conn)
        qc_bind_tid_reset(qc);
 }
 
+static int quic_init_mem(void)
+{
+       /* 1024 is enough to limit modification on global counter but keeping it precise enough even with a lot of threads */
+       cshared_init(&quic_mem_diff, &quic_mem_global, 1024);
+       return 1;
+}
+REGISTER_PER_THREAD_INIT(quic_init_mem);
+
 static int quic_alloc_dghdlrs(void)
 {
        int i;
index 0d9151ebb89efe80978988cb36c653dba32ce7fc..31bb6e7970ae631c81df964350248dfbcc64d4bb 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <haproxy/proto_quic.h>
 #include <haproxy/quic_cc.h>
 #include <haproxy/quic_pacing.h>
+#include <haproxy/thread.h>
 
 struct quic_cc_algo *default_quic_cc_algo = &quic_cc_algo_cubic;
 
@@ -79,14 +81,19 @@ static int quic_cwnd_may_increase(const struct quic_cc_path *path)
 /* Restore congestion window for <path> to its minimal value. */
 void quic_cc_path_reset(struct quic_cc_path *path)
 {
+       const uint64_t old = path->cwnd;
        path->cwnd = path->limit_min;
+       cshared_add(&quic_mem_diff, path->cwnd - old);
 }
 
 /* Set congestion window for <path> to <val>. Min and max limits are enforced. */
 void quic_cc_path_set(struct quic_cc_path *path, uint64_t val)
 {
+       const uint64_t old = path->cwnd;
+
        path->cwnd = QUIC_MIN(val, path->limit_max);
        path->cwnd = QUIC_MAX(path->cwnd, path->limit_min);
+       cshared_add(&quic_mem_diff, path->cwnd - old);
 
        path->cwnd_last_max = QUIC_MAX(path->cwnd, path->cwnd_last_max);
 }
@@ -97,9 +104,12 @@ void quic_cc_path_set(struct quic_cc_path *path, uint64_t val)
  */
 void quic_cc_path_inc(struct quic_cc_path *path, uint64_t val)
 {
+       const uint64_t old = path->cwnd;
+
        if (quic_cwnd_may_increase(path)) {
                path->cwnd = QUIC_MIN(path->cwnd + val, path->limit_max);
                path->cwnd = QUIC_MAX(path->cwnd, path->limit_min);
+               cshared_add(&quic_mem_diff, path->cwnd - old);
 
                path->cwnd_last_max = QUIC_MAX(path->cwnd, path->cwnd_last_max);
        }
index 547c8981745346c7e4ae993ae1a31e3e5d429505..51ace545f61be01ccc490279907e2dda3cde39e1 100644 (file)
@@ -1442,6 +1442,10 @@ void quic_conn_release(struct quic_conn *qc)
                HA_ATOMIC_DEC(&qc->li->rx.quic_curr_accept);
        }
 
+       /* Substract last congestion window from global memory counter. */
+       cshared_add(&quic_mem_diff, -qc->path->cwnd);
+       qc->path->cwnd = 0;
+
        /* free remaining stream descriptors */
        node = eb64_first(&qc->streams_by_id);
        while (node) {