]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: Stop stressing the acknowledgments process (RX ACK frames)
authorFrédéric Lécaille <flecaille@haproxy.com>
Wed, 15 Mar 2023 16:21:13 +0000 (17:21 +0100)
committerFrédéric Lécaille <flecaille@haproxy.com>
Mon, 20 Mar 2023 16:47:12 +0000 (17:47 +0100)
The ACK frame range of packets were handled from the largest to the smallest
packet number, leading to big number of ebtree insertions when the packet are
handled in the inverse way they are sent. This was detected a long time ago
but left in the code to stress our implementation. It is time to be more
efficient and process the packet so that to avoid useless ebtree insertions.

Modify qc_ackrng_pkts() responsible of handling the acknowledged packets from an
ACK frame range of acknowledged packets.

Must be backported to 2.7.

src/quic_conn.c

index 5fa2ce942db85f2259f8582ed217fce20a8c6acc..f8c7816ec8fb5725c568949473a6de3895b60b5f 100644 (file)
@@ -1809,23 +1809,29 @@ static inline void qc_treat_acked_tx_frm(struct quic_conn *qc,
 
 /* Remove <largest> down to <smallest> node entries from <pkts> tree of TX packet,
  * deallocating them, and their TX frames.
- * Returns the last node reached to be used for the next range.
  * May be NULL if <largest> node could not be found.
  */
-static inline struct eb64_node *qc_ackrng_pkts(struct quic_conn *qc,
-                                               struct eb_root *pkts,
-                                               unsigned int *pkt_flags,
-                                               struct list *newly_acked_pkts,
-                                               struct eb64_node *largest_node,
-                                               uint64_t largest, uint64_t smallest)
+static inline void qc_ackrng_pkts(struct quic_conn *qc,
+                                  struct eb_root *pkts,
+                                  unsigned int *pkt_flags,
+                                  struct list *newly_acked_pkts,
+                                  struct eb64_node *largest_node,
+                                  uint64_t largest, uint64_t smallest)
 {
        struct eb64_node *node;
        struct quic_tx_packet *pkt;
 
        TRACE_ENTER(QUIC_EV_CONN_PRSAFRM, qc);
 
-       node = largest_node ? largest_node : eb64_lookup_le(pkts, largest);
-       while (node && node->key >= smallest) {
+       node = eb64_lookup_ge(pkts, smallest);
+       if (!node)
+               goto leave;
+
+       largest_node = largest_node ? largest_node : eb64_lookup_le(pkts, largest);
+       if (!largest_node)
+               goto leave;
+
+       while (node && node->key <= largest_node->key) {
                struct quic_frame *frm, *frmbak;
 
                pkt = eb64_entry(node, struct quic_tx_packet, pn_node);
@@ -1838,12 +1844,12 @@ static inline struct eb64_node *qc_ackrng_pkts(struct quic_conn *qc,
                 * detach the previous one and the next one from <pkt>.
                 */
                quic_tx_packet_dgram_detach(pkt);
-               node = eb64_prev(node);
+               node = eb64_next(node);
                eb64_delete(&pkt->pn_node);
        }
 
+ leave:
        TRACE_LEAVE(QUIC_EV_CONN_PRSAFRM, qc);
-       return node;
 }
 
 /* Remove all frames from <pkt_frm_list> and reinsert them in the same order