MINOR: quic/pacing: add burst support

qc_send_mux() has been extended previously to support pacing emission.
This will ensure that no more than one datagram will be emitted during
each invokation. However, to achieve better performance, it may be
necessary to emit a batch of several datagrams one one turn.

A so-called burst value can be specified by the user in the
configuration. However, some congestion control algos may defined their
owned dynamic value. As such, a new CC callback pacing_burst is defined.

quic_cc_default_pacing_burst() can be used for algo without pacing
interaction, such as cubic. It will returns a static value based on user
selected configuration.
This commit is contained in:
Amaury Denoyelle 2024-11-18 15:31:12 +01:00
parent 8039fe43e6
commit 886a7c475c
6 changed files with 24 additions and 10 deletions

View File

@ -113,6 +113,8 @@ struct quic_cc_path {
uint64_t in_flight;
/* Number of in flight ack-eliciting packets. */
uint64_t ifae_pkts;
/* Burst size if pacing is used. Not used if congestion algo handle pacing itself. */
uint32_t pacing_burst;
};
struct quic_cc_algo {
@ -126,6 +128,7 @@ struct quic_cc_algo {
/* Defined only if pacing is used. */
uint (*pacing_rate)(const struct quic_cc *cc);
uint (*pacing_burst)(const struct quic_cc *cc);
};
#endif /* USE_QUIC */

View File

@ -39,6 +39,7 @@ void quic_cc_state_trace(struct buffer *buf, const struct quic_cc *cc);
/* Pacing callbacks */
uint quic_cc_default_pacing_rate(const struct quic_cc *cc);
uint quic_cc_default_pacing_burst(const struct quic_cc *cc);
static inline const char *quic_cc_state_str(enum quic_cc_algo_state_type state)
{

View File

@ -15,8 +15,7 @@ static inline void quic_pacing_init(struct quic_pacer *pacer,
int quic_pacing_expired(const struct quic_pacer *pacer);
void quic_pacing_sent_done(struct quic_pacer *pacer);
void quic_pacing_sent_done(struct quic_pacer *pacer, int sent);
enum quic_tx_err quic_pacing_send(struct quic_pacer *pacer, struct quic_conn *qc);

View File

@ -54,3 +54,12 @@ uint quic_cc_default_pacing_rate(const struct quic_cc *cc)
struct quic_cc_path *path = container_of(cc, struct quic_cc_path, cc);
return path->loss.srtt * 1000000 / (path->cwnd / path->mtu + 1);
}
/* Return the max number of datagrams which can be emitted in a burst with
* pacing. Must return a strictly positive value.
*/
uint quic_cc_default_pacing_burst(const struct quic_cc *cc)
{
struct quic_cc_path *path = container_of(cc, struct quic_cc_path, cc);
return path->pacing_burst;
}

View File

@ -8,8 +8,8 @@ int quic_pacing_expired(const struct quic_pacer *pacer)
return !pacer->next || pacer->next <= now_mono_time();
}
/* Notify <pacer> about an emission of one datagram. */
void quic_pacing_sent_done(struct quic_pacer *pacer)
/* Notify <pacer> about an emission of <sent> count of datagrams. */
void quic_pacing_sent_done(struct quic_pacer *pacer, int sent)
{
pacer->next = now_mono_time() + pacer->cc->algo->pacing_rate(pacer->cc);
pacer->next = now_mono_time() + pacer->cc->algo->pacing_rate(pacer->cc) * sent;
}

View File

@ -494,8 +494,10 @@ enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
qc_send(qc, 0, &send_list, 0);
}
if (pacer)
max_dgram = 1;
if (pacer) {
max_dgram = qc->path->cc.algo->pacing_burst(&qc->path->cc);
BUG_ON(max_dgram <= 0); /* pacer must specify a positive burst value. */
}
TRACE_STATE("preparing data (from MUX)", QUIC_EV_CONN_TXPKT, qc);
qel_register_send(&send_list, qc->ael, frms);
@ -504,10 +506,10 @@ enum quic_tx_err qc_send_mux(struct quic_conn *qc, struct list *frms,
ret = QUIC_TX_ERR_FATAL;
}
else if (pacer) {
BUG_ON(sent > 1); /* burst not yet supported for pacing */
if (!LIST_ISEMPTY(frms))
BUG_ON(sent > max_dgram); /* Must not exceed pacing limit. */
if (max_dgram == sent && !LIST_ISEMPTY(frms))
ret = QUIC_TX_ERR_PACING;
quic_pacing_sent_done(pacer);
quic_pacing_sent_done(pacer, sent);
}
TRACE_LEAVE(QUIC_EV_CONN_TXPKT, qc);