mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-20 04:30:46 +00:00
BUG/MINOR: quic: Wrong use of now_ms timestamps (cubic algo)
As now_ms may wrap, one must use the ticks API to protect the cubic congestion control algorithm implementation from side effects due to this. Furthermore to make the cubic congestion control algorithm more readable and easy to maintain, adding a new state ("in recovery period" QUIC_CC_ST_RP new enum) helps in reaching this goal. Implement quic_cc_cubic_rp_cb() which is the callback for this new state. Must be backported to 2.7 and 2.6.
This commit is contained in:
parent
6549f53fb6
commit
d7243318c4
@ -44,6 +44,8 @@ enum quic_cc_algo_state_type {
|
||||
QUIC_CC_ST_SS,
|
||||
/* Congestion avoidance. */
|
||||
QUIC_CC_ST_CA,
|
||||
/* Recovery period. */
|
||||
QUIC_CC_ST_RP,
|
||||
};
|
||||
|
||||
enum quic_cc_event_type {
|
||||
|
@ -43,6 +43,8 @@ static inline const char *quic_cc_state_str(enum quic_cc_algo_state_type state)
|
||||
return "ss";
|
||||
case QUIC_CC_ST_CA:
|
||||
return "ca";
|
||||
case QUIC_CC_ST_RP:
|
||||
return "rp";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
@ -189,6 +189,7 @@ static void quic_enter_recovery(struct quic_cc *cc)
|
||||
}
|
||||
path->cwnd = (CUBIC_BETA * path->cwnd) >> CUBIC_BETA_SCALE_SHIFT;
|
||||
c->ssthresh = QUIC_MAX(path->cwnd, path->min_cwnd);
|
||||
cc->algo->state = QUIC_CC_ST_RP;
|
||||
}
|
||||
|
||||
/* Congestion slow-start callback. */
|
||||
@ -200,10 +201,6 @@ static void quic_cc_cubic_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc, ev);
|
||||
switch (ev->type) {
|
||||
case QUIC_CC_EVT_ACK:
|
||||
/* Do not increase the congestion window in recovery period. */
|
||||
if (ev->ack.time_sent <= c->recovery_start_time)
|
||||
goto out;
|
||||
|
||||
path->cwnd += ev->ack.acked;
|
||||
/* Exit to congestion avoidance if slow start threshold is reached. */
|
||||
if (path->cwnd >= c->ssthresh)
|
||||
@ -211,10 +208,6 @@ static void quic_cc_cubic_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
break;
|
||||
|
||||
case QUIC_CC_EVT_LOSS:
|
||||
/* Do not decrease the congestion window when already in recovery period. */
|
||||
if (ev->loss.time_sent <= c->recovery_start_time)
|
||||
goto out;
|
||||
|
||||
quic_enter_recovery(cc);
|
||||
/* Exit to congestion avoidance. */
|
||||
cc->algo->state = QUIC_CC_ST_CA;
|
||||
@ -232,22 +225,12 @@ static void quic_cc_cubic_ss_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
/* Congestion avoidance callback. */
|
||||
static void quic_cc_cubic_ca_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
{
|
||||
struct cubic *c = quic_cc_priv(cc);
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc, ev);
|
||||
switch (ev->type) {
|
||||
case QUIC_CC_EVT_ACK:
|
||||
/* Do not increase the congestion window when already in recovery period. */
|
||||
if (ev->ack.time_sent <= c->recovery_start_time)
|
||||
goto out;
|
||||
|
||||
quic_cubic_update(cc, ev->ack.acked);
|
||||
break;
|
||||
case QUIC_CC_EVT_LOSS:
|
||||
/* Do not decrease the congestion window when already in recovery period. */
|
||||
if (ev->loss.time_sent <= c->recovery_start_time)
|
||||
goto out;
|
||||
|
||||
quic_enter_recovery(cc);
|
||||
break;
|
||||
case QUIC_CC_EVT_ECN_CE:
|
||||
@ -259,10 +242,43 @@ static void quic_cc_cubic_ca_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc, NULL, cc);
|
||||
}
|
||||
|
||||
/* Recovery period callback */
|
||||
static void quic_cc_cubic_rp_cb(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
{
|
||||
struct cubic *c = quic_cc_priv(cc);
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_CC, cc->qc, ev);
|
||||
|
||||
BUG_ON(!tick_isset(c->recovery_start_time));
|
||||
|
||||
switch (ev->type) {
|
||||
case QUIC_CC_EVT_ACK:
|
||||
/* RFC 9022 7.3.2. Recovery
|
||||
* A recovery period ends and the sender enters congestion avoidance when a
|
||||
* packet sent during the recovery period is acknowledged.
|
||||
*/
|
||||
if (tick_is_le(ev->ack.time_sent, c->recovery_start_time))
|
||||
goto leave;
|
||||
|
||||
cc->algo->state = QUIC_CC_ST_CA;
|
||||
c->recovery_start_time = TICK_ETERNITY;
|
||||
break;
|
||||
case QUIC_CC_EVT_LOSS:
|
||||
break;
|
||||
case QUIC_CC_EVT_ECN_CE:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
|
||||
leave:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CC, cc->qc, NULL, cc);
|
||||
}
|
||||
|
||||
static void (*quic_cc_cubic_state_cbs[])(struct quic_cc *cc,
|
||||
struct quic_cc_event *ev) = {
|
||||
[QUIC_CC_ST_SS] = quic_cc_cubic_ss_cb,
|
||||
[QUIC_CC_ST_CA] = quic_cc_cubic_ca_cb,
|
||||
[QUIC_CC_ST_RP] = quic_cc_cubic_rp_cb,
|
||||
};
|
||||
|
||||
static void quic_cc_cubic_event(struct quic_cc *cc, struct quic_cc_event *ev)
|
||||
|
Loading…
Reference in New Issue
Block a user