]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proto_quic: Allocate TX ring buffers for listeners
authorFrédéric Lécaille <flecaille@haproxy.com>
Tue, 6 Jul 2021 13:39:26 +0000 (15:39 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Sep 2021 13:27:25 +0000 (15:27 +0200)
We allocate an array of QUIC ring buffer, one by thread, and arranges them in a
MT_LIST. Everything is allocated or nothing: we do not want to usse an incomplete
array of ring buffers to ensure that each thread may safely acquire one of these
buffers.

include/haproxy/receiver-t.h
src/proto_quic.c

index 91408d7469ccfd4c5925a56dca56c432d379e8cf..d8f2422d938e8f91114524a2fb4db3fa4cf881fe 100644 (file)
@@ -66,6 +66,8 @@ struct receiver {
        struct eb_root odcids;           /* QUIC original destination connection IDs. */
        struct eb_root cids;             /* QUIC connection IDs. */
        __decl_thread(HA_RWLOCK_T cids_lock); /* RW lock for connection IDs tree accesses */
+       struct qring *qrings;            /* Array of rings (one by thread) */
+       struct mt_list tx_qrings;        /* The same as ->qrings but arranged in a list */
 #endif
        /* warning: this struct is huge, keep it at the bottom */
        struct sockaddr_storage addr;    /* the address the socket is bound to */
index 2b6bb6a6a434be1011d469c823c92c86dbeabc42..1e2ca5786bbe794db3dc47b0c28fe3a6f37640e8 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <haproxy/api.h>
 #include <haproxy/arg.h>
+#include <haproxy/cbuf.h>
 #include <haproxy/connection.h>
 #include <haproxy/errors.h>
 #include <haproxy/fd.h>
@@ -44,6 +45,7 @@
 #include <haproxy/quic_sock.h>
 #include <haproxy/sock_inet.h>
 #include <haproxy/tools.h>
+#include <haproxy/xprt_quic-t.h>
 
 
 static void quic_add_listener(struct protocol *proto, struct listener *listener);
@@ -521,6 +523,38 @@ static void quic_add_listener(struct protocol *proto, struct listener *listener)
        default_add_listener(proto, listener);
 }
 
+/* Allocate the TX ring buffers for <l> listener.
+ * Return 1 if succeeded, 0 if not.
+ */
+static int quic_alloc_rings_listener(struct listener *l)
+{
+       struct qring *qr;
+       int i;
+
+       l->rx.qrings = calloc(global.nbthread, sizeof *l->rx.qrings);
+       if (!l->rx.qrings)
+               return 0;
+
+       MT_LIST_INIT(&l->rx.tx_qrings);
+       for (i = 0; i < global.nbthread; i++) {
+               struct qring *qr = &l->rx.qrings[i];
+
+               qr->cbuf = cbuf_new();
+               if (!qr->cbuf)
+                       goto err;
+
+               MT_LIST_APPEND(&l->rx.tx_qrings, &qr->mt_list);
+       }
+
+       return 1;
+
+ err:
+       while ((qr = MT_LIST_POP(&l->rx.tx_qrings, typeof(qr), mt_list)))
+               cbuf_free(qr->cbuf);
+       free(l->rx.qrings);
+       return 0;
+}
+
 /* This function tries to bind a QUIC4/6 listener. It may return a warning or
  * an error message in <errmsg> if the message is at most <errlen> bytes long
  * (including '\0'). Note that <errmsg> may be NULL if <errlen> is also zero.
@@ -551,6 +585,12 @@ static int quic_bind_listener(struct listener *listener, char *errmsg, int errle
                goto udp_return;
        }
 
+       if (!quic_alloc_rings_listener(listener)) {
+               msg = "could not initialize tx rings";
+               err |= ERR_WARN;
+               goto udp_return;
+       }
+
        listener_set_state(listener, LI_LISTEN);
 
  udp_return: