From: Frédéric Lécaille Date: Tue, 6 Jul 2021 13:39:26 +0000 (+0200) Subject: MINOR: proto_quic: Allocate TX ring buffers for listeners X-Git-Tag: v2.5-dev8~107 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48f8e1925b7e30c1a0b04c37f94108af766b461c;p=thirdparty%2Fhaproxy.git MINOR: proto_quic: Allocate TX ring buffers for listeners 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. --- diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 91408d7469..d8f2422d93 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -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 */ diff --git a/src/proto_quic.c b/src/proto_quic.c index 2b6bb6a6a4..1e2ca5786b 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include 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 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 if the message is at most bytes long * (including '\0'). Note that may be NULL if 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: