]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Improvements for the datagrams receipt
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 30 Jun 2022 09:28:56 +0000 (11:28 +0200)
committerFrédéric Lécaille <flecaille@haproxy.com>
Thu, 30 Jun 2022 12:34:27 +0000 (14:34 +0200)
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.

src/quic_sock.c
src/xprt_quic.c

index f8590f84626ec81079e126b2feb67b92e5a23390..51d887a2cc2adb33424c6a26476e4e66b525b63e 100644 (file)
@@ -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 <rxbuf> 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);
index 018975dd31e38076e027342271d1bf097feb87ba..ce4a2f9704e7451ff140fbf257ac3c42f5c8a80e 100644 (file)
@@ -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);