MINOR: quic: RX part modifications to support BBR
qc_notify_cc_of_newly_acked_pkts() aim is to notify the congestion algorithm of all the packet acknowledgements. It must call quic_cc_drs_update_rate_sample() to update the delivery rate sampling information. It must also call quic_cc_drs_on_ack_recv() to update the state of the delivery rate sampling part used by BBR. Finally, ->on_ack_rcvd() is called with the total number of bytes delivered by the sender from the newly acknowledged packets with <bytes_delivered> as parameter to do so. <pkt_delivered> store the per-packet number of bytes delivered by the newly sent acknowledged packet (the packet with the highest packet number). <bytes_lost> is also used and has been set by qc_packet_loss_lookup() before calling qc_notify_cc_of_newly_acked_pkts().
This commit is contained in:
parent
d85eb127e9
commit
44af88d856
|
@ -19,6 +19,7 @@
|
||||||
#include <haproxy/ncbuf.h>
|
#include <haproxy/ncbuf.h>
|
||||||
#include <haproxy/proto_quic.h>
|
#include <haproxy/proto_quic.h>
|
||||||
#include <haproxy/quic_ack.h>
|
#include <haproxy/quic_ack.h>
|
||||||
|
#include <haproxy/quic_cc_drs.h>
|
||||||
#include <haproxy/quic_cid.h>
|
#include <haproxy/quic_cid.h>
|
||||||
#include <haproxy/quic_retransmit.h>
|
#include <haproxy/quic_retransmit.h>
|
||||||
#include <haproxy/quic_retry.h>
|
#include <haproxy/quic_retry.h>
|
||||||
|
@ -421,33 +422,52 @@ int qc_handle_frms_of_lost_pkt(struct quic_conn *qc,
|
||||||
* Always succeeds.
|
* Always succeeds.
|
||||||
*/
|
*/
|
||||||
static void qc_notify_cc_of_newly_acked_pkts(struct quic_conn *qc,
|
static void qc_notify_cc_of_newly_acked_pkts(struct quic_conn *qc,
|
||||||
struct list *newly_acked_pkts)
|
struct list *newly_acked_pkts,
|
||||||
|
unsigned int bytes_lost,
|
||||||
|
unsigned int rtt)
|
||||||
{
|
{
|
||||||
struct quic_tx_packet *pkt, *tmp;
|
struct quic_tx_packet *pkt, *tmp;
|
||||||
struct quic_cc_event ev = { .type = QUIC_CC_EVT_ACK, };
|
struct quic_cc_event ev = { .type = QUIC_CC_EVT_ACK, };
|
||||||
|
struct quic_cc_path *p = qc->path;
|
||||||
|
struct quic_cc_drs *drs =
|
||||||
|
p->cc.algo->get_drs ? p->cc.algo->get_drs(&p->cc) : NULL;
|
||||||
|
unsigned int bytes_delivered = 0, pkt_delivered = 0;
|
||||||
|
|
||||||
TRACE_ENTER(QUIC_EV_CONN_PRSAFRM, qc);
|
TRACE_ENTER(QUIC_EV_CONN_PRSAFRM, qc);
|
||||||
|
|
||||||
list_for_each_entry_safe(pkt, tmp, newly_acked_pkts, list) {
|
list_for_each_entry_safe(pkt, tmp, newly_acked_pkts, list) {
|
||||||
pkt->pktns->tx.in_flight -= pkt->in_flight_len;
|
pkt->pktns->tx.in_flight -= pkt->in_flight_len;
|
||||||
qc->path->prep_in_flight -= pkt->in_flight_len;
|
p->prep_in_flight -= pkt->in_flight_len;
|
||||||
qc->path->in_flight -= pkt->in_flight_len;
|
p->in_flight -= pkt->in_flight_len;
|
||||||
if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
|
if (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING)
|
||||||
qc->path->ifae_pkts--;
|
p->ifae_pkts--;
|
||||||
/* If this packet contained an ACK frame, proceed to the
|
/* If this packet contained an ACK frame, proceed to the
|
||||||
* acknowledging of range of acks from the largest acknowledged
|
* acknowledging of range of acks from the largest acknowledged
|
||||||
* packet number which was sent in an ACK frame by this packet.
|
* packet number which was sent in an ACK frame by this packet.
|
||||||
*/
|
*/
|
||||||
if (pkt->largest_acked_pn != -1)
|
if (pkt->largest_acked_pn != -1)
|
||||||
qc_treat_ack_of_ack(qc, &pkt->pktns->rx.arngs, pkt->largest_acked_pn);
|
qc_treat_ack_of_ack(qc, &pkt->pktns->rx.arngs, pkt->largest_acked_pn);
|
||||||
|
bytes_delivered += pkt->len;
|
||||||
|
pkt_delivered = pkt->rs.delivered;
|
||||||
ev.ack.acked = pkt->in_flight_len;
|
ev.ack.acked = pkt->in_flight_len;
|
||||||
ev.ack.time_sent = pkt->time_sent;
|
ev.ack.time_sent = pkt->time_sent;
|
||||||
ev.ack.pn = pkt->pn_node.key;
|
ev.ack.pn = pkt->pn_node.key;
|
||||||
quic_cc_event(&qc->path->cc, &ev);
|
/* Note that this event is not emitted for BBR. */
|
||||||
|
quic_cc_event(&p->cc, &ev);
|
||||||
|
if (drs && (pkt->flags & QUIC_FL_TX_PACKET_ACK_ELICITING))
|
||||||
|
quic_cc_drs_update_rate_sample(drs, pkt);
|
||||||
LIST_DEL_INIT(&pkt->list);
|
LIST_DEL_INIT(&pkt->list);
|
||||||
quic_tx_packet_refdec(pkt);
|
quic_tx_packet_refdec(pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drs) {
|
||||||
|
quic_cc_drs_on_ack_recv(drs, p, pkt_delivered);
|
||||||
|
drs->lost += bytes_lost;
|
||||||
|
}
|
||||||
|
if (p->cc.algo->on_ack_rcvd)
|
||||||
|
p->cc.algo->on_ack_rcvd(&p->cc, bytes_delivered, pkt_delivered,
|
||||||
|
rtt, bytes_lost, now_ms);
|
||||||
|
|
||||||
TRACE_LEAVE(QUIC_EV_CONN_PRSAFRM, qc);
|
TRACE_LEAVE(QUIC_EV_CONN_PRSAFRM, qc);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -551,6 +571,8 @@ static int qc_parse_ack_frm(struct quic_conn *qc,
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
if (!LIST_ISEMPTY(&newly_acked_pkts)) {
|
if (!LIST_ISEMPTY(&newly_acked_pkts)) {
|
||||||
|
unsigned int bytes_lost = 0;
|
||||||
|
|
||||||
if (!qc_handle_newly_acked_pkts(qc, &pkt_flags, &newly_acked_pkts))
|
if (!qc_handle_newly_acked_pkts(qc, &pkt_flags, &newly_acked_pkts))
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
@ -560,11 +582,13 @@ static int qc_parse_ack_frm(struct quic_conn *qc,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!eb_is_empty(&qel->pktns->tx.pkts)) {
|
if (!eb_is_empty(&qel->pktns->tx.pkts)) {
|
||||||
qc_packet_loss_lookup(qel->pktns, qc, &lost_pkts);
|
qc_packet_loss_lookup(qel->pktns, qc, &lost_pkts, &bytes_lost);
|
||||||
if (!qc_release_lost_pkts(qc, qel->pktns, &lost_pkts, now_ms))
|
if (!qc_release_lost_pkts(qc, qel->pktns, &lost_pkts, now_ms))
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
qc_notify_cc_of_newly_acked_pkts(qc, &newly_acked_pkts);
|
|
||||||
|
qc_notify_cc_of_newly_acked_pkts(qc, &newly_acked_pkts,
|
||||||
|
bytes_lost, *rtt_sample);
|
||||||
if (quic_peer_validated_addr(qc))
|
if (quic_peer_validated_addr(qc))
|
||||||
qc->path->loss.pto_count = 0;
|
qc->path->loss.pto_count = 0;
|
||||||
qc_set_timer(qc);
|
qc_set_timer(qc);
|
||||||
|
|
Loading…
Reference in New Issue