From: Frédéric Lécaille Date: Thu, 30 Jun 2022 09:28:56 +0000 (+0200) Subject: MINOR: quic: Improvements for the datagrams receipt X-Git-Tag: v2.7-dev2~168 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1b0707f3e7ee496e4398f87e8607909a7edcafbf;p=thirdparty%2Fhaproxy.git MINOR: quic: Improvements for the datagrams receipt First we add a loop around recfrom() into the most low level I/O handler quic_sock_fd_iocb() to collect as most as possible datagrams before during its tasklet wakeup with a limit: we recvfrom() at most "maxpollevents" datagrams. Furthermore we add a local task list into the datagram handler quic_lstnr_dghdlr() which is passed to the first datagrams parser qc_lstnr_pkt_rcv(). This latter parser only identifies the connection associated to the datagrams then wakeup the highest level packet parser I/O handlers (quic_conn.*io_cb()) after it is done, thanks to the call to tasklet_wakeup_after() which replaces from now on the call to tasklet_wakeup(). This should reduce drastically the latency and the chances to fulfil the RX buffers at the QUIC connections level as reported in GH #1737 by Tritan. These modifications depend on this commit: "MINOR: task: Add tasklet_wakeup_after()" Must be backported to 2.6 with the previous commit. --- diff --git a/src/quic_sock.c b/src/quic_sock.c index f8590f8462..51d887a2cc 100644 --- a/src/quic_sock.c +++ b/src/quic_sock.c @@ -275,6 +275,7 @@ void quic_sock_fd_iocb(int fd) socklen_t saddrlen; struct quic_dgram *new_dgram; unsigned char *dgram_buf; + int max_dgrams; BUG_ON(!l); @@ -291,6 +292,8 @@ void quic_sock_fd_iocb(int fd) buf = &rxbuf->buf; + max_dgrams = global.tune.maxpollevents; + start: /* Try to reuse an existing dgram. Note that there is alway at * least one datagram to pick, except the first time we enter * this function for this buffer. @@ -352,6 +355,8 @@ void quic_sock_fd_iocb(int fd) b_del(buf, ret); } new_dgram = NULL; + if (--max_dgrams > 0) + goto start; out: pool_free(pool_head_quic_dgram, new_dgram); MT_LIST_APPEND(&l->rx.rxbuf_list, &rxbuf->mt_list); diff --git a/src/xprt_quic.c b/src/xprt_quic.c index 018975dd31..ce4a2f9704 100644 --- a/src/xprt_quic.c +++ b/src/xprt_quic.c @@ -5236,7 +5236,7 @@ static inline int quic_padding_check(const unsigned char *buf, */ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end, struct quic_rx_packet *pkt, int first_pkt, - struct quic_dgram *dgram) + struct quic_dgram *dgram, struct list **tasklist_head) { unsigned char *beg, *payload; struct quic_conn *qc, *qc_to_purge = NULL; @@ -5610,7 +5610,7 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end, */ conn_ctx = qc->xprt_ctx; if (conn_ctx) - tasklet_wakeup(conn_ctx->wait_event.tasklet); + *tasklist_head = tasklet_wakeup_after(*tasklist_head, conn_ctx->wait_event.tasklet); drop_no_conn: if (drop_no_conn) @@ -6489,6 +6489,7 @@ struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state) struct quic_dghdlr *dghdlr = ctx; struct quic_dgram *dgram; int first_pkt = 1; + struct list *tasklist_head = NULL; while ((dgram = MT_LIST_POP(&dghdlr->dgrams, typeof(dgram), mt_list))) { pos = dgram->buf; @@ -6503,7 +6504,7 @@ struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state) LIST_INIT(&pkt->qc_rx_pkt_list); pkt->time_received = now_ms; quic_rx_packet_refinc(pkt); - qc_lstnr_pkt_rcv(pos, end, pkt, first_pkt, dgram); + qc_lstnr_pkt_rcv(pos, end, pkt, first_pkt, dgram, &tasklist_head); first_pkt = 0; pos += pkt->len; quic_rx_packet_refdec(pkt);