Adds ECN handling managed by ROCCET.
This commit is contained in:
31
tcp_roccet.c
31
tcp_roccet.c
@@ -130,6 +130,7 @@ static inline void roccettcp_reset(struct roccettcp *ca)
|
|||||||
ca->curr_min_rtt_timed.rtt = ~0U;
|
ca->curr_min_rtt_timed.rtt = ~0U;
|
||||||
ca->curr_min_rtt_timed.time = ~0U;
|
ca->curr_min_rtt_timed.time = ~0U;
|
||||||
ca->last_rtt = 0;
|
ca->last_rtt = 0;
|
||||||
|
ca->ece_received = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void update_min_rtt(struct sock *sk)
|
static inline void update_min_rtt(struct sock *sk)
|
||||||
@@ -431,12 +432,17 @@ __bpf_kfunc static void roccettcp_cong_avoid(struct sock *sk, u32 ack,
|
|||||||
if (now - ca->roccet_last_event_time_us <= 100 * USEC_PER_MSEC)
|
if (now - ca->roccet_last_event_time_us <= 100 * USEC_PER_MSEC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Lift off: Detect an exit point for tcp slow start
|
/* LAUNCH: Detect an exit point for tcp slow start
|
||||||
* in networks with large buffers of multiple BDP
|
* in networks with large buffers of multiple BDP
|
||||||
* Like in cellular networks (5G, ...).
|
* Like in cellular networks (5G, ...).
|
||||||
|
* Or exit LAUNCH if cwnd is too large for application layer
|
||||||
|
* data rate.
|
||||||
*/
|
*/
|
||||||
if (tcp_in_slow_start(tp) && ca->curr_srRTT > sr_rtt_upper_bound &&
|
|
||||||
get_ack_rate_diff(ca) >= ack_rate_diff_ss) {
|
if ((tcp_in_slow_start(tp) && ca->curr_srRTT > sr_rtt_upper_bound &&
|
||||||
|
get_ack_rate_diff(ca) >= ack_rate_diff_ss) ||
|
||||||
|
(!tcp_is_cwnd_limited(sk) && tcp_in_slow_start(tp))
|
||||||
|
) {
|
||||||
ca->epoch_start = 0;
|
ca->epoch_start = 0;
|
||||||
|
|
||||||
/* Handle inital slow start. Here we observe the most problems */
|
/* Handle inital slow start. Here we observe the most problems */
|
||||||
@@ -487,7 +493,9 @@ __bpf_kfunc static void roccettcp_cong_avoid(struct sock *sk, u32 ack,
|
|||||||
if (roccet_xj < sr_rtt_upper_bound)
|
if (roccet_xj < sr_rtt_upper_bound)
|
||||||
roccet_xj = sr_rtt_upper_bound;
|
roccet_xj = sr_rtt_upper_bound;
|
||||||
|
|
||||||
if (ca->curr_srRTT > roccet_xj && bw_limit_detect) {
|
if (ca->curr_srRTT > roccet_xj && (bw_limit_detect || ca->ece_received)) {
|
||||||
|
if(ca->ece_received)
|
||||||
|
ca->ece_received = 0;
|
||||||
ca->epoch_start = 0;
|
ca->epoch_start = 0;
|
||||||
ca->roccet_last_event_time_us = now;
|
ca->roccet_last_event_time_us = now;
|
||||||
ca->cnt = 100 * tcp_snd_cwnd(tp);
|
ca->cnt = 100 * tcp_snd_cwnd(tp);
|
||||||
@@ -527,7 +535,7 @@ __bpf_kfunc static u32 roccettcp_recalc_ssthresh(struct sock *sk)
|
|||||||
/* Don't exit slow start if loss occurs. */
|
/* Don't exit slow start if loss occurs. */
|
||||||
if (tcp_in_slow_start(tp))
|
if (tcp_in_slow_start(tp))
|
||||||
return tcp_snd_cwnd(tp);
|
return tcp_snd_cwnd(tp);
|
||||||
|
|
||||||
ca->epoch_start = 0; /* end of epoch */
|
ca->epoch_start = 0; /* end of epoch */
|
||||||
|
|
||||||
/* Wmax and fast convergence */
|
/* Wmax and fast convergence */
|
||||||
@@ -576,6 +584,18 @@ __bpf_kfunc static void roccettcp_acked(struct sock *sk,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__bpf_kfunc static void roccet_in_ack_event(struct sock *sk, u32 flags)
|
||||||
|
{
|
||||||
|
struct roccettcp *ca = inet_csk_ca(sk);
|
||||||
|
|
||||||
|
/* Handle ECE bit.
|
||||||
|
* Pocessing of ECE events is done in roccettcp_cong_avoid()
|
||||||
|
*/
|
||||||
|
if (flags & CA_ACK_ECE) {
|
||||||
|
ca->ece_received = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct tcp_congestion_ops roccet_tcp __read_mostly = {
|
static struct tcp_congestion_ops roccet_tcp __read_mostly = {
|
||||||
.init = roccettcp_init,
|
.init = roccettcp_init,
|
||||||
.ssthresh = roccettcp_recalc_ssthresh,
|
.ssthresh = roccettcp_recalc_ssthresh,
|
||||||
@@ -584,6 +604,7 @@ static struct tcp_congestion_ops roccet_tcp __read_mostly = {
|
|||||||
.undo_cwnd = tcp_reno_undo_cwnd,
|
.undo_cwnd = tcp_reno_undo_cwnd,
|
||||||
.cwnd_event = roccettcp_cwnd_event,
|
.cwnd_event = roccettcp_cwnd_event,
|
||||||
.pkts_acked = roccettcp_acked,
|
.pkts_acked = roccettcp_acked,
|
||||||
|
.in_ack_event = roccet_in_ack_event,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "roccet",
|
.name = "roccet",
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -39,7 +39,8 @@ struct roccettcp {
|
|||||||
u32 tcp_cwnd; /* estimated tcp cwnd */
|
u32 tcp_cwnd; /* estimated tcp cwnd */
|
||||||
u32 curr_rtt; /* the minimum rtt of current round */
|
u32 curr_rtt; /* the minimum rtt of current round */
|
||||||
|
|
||||||
u32 roccet_last_event_time_us; /* The last time ROCCETv2 was triggered */
|
u32 roccet_last_event_time_us; /* The last time ROCCET was triggered */
|
||||||
|
u32 ece_received; /* Set to true if an ECE bit was received */
|
||||||
u32 curr_min_rtt; /* The current observed minRTT */
|
u32 curr_min_rtt; /* The current observed minRTT */
|
||||||
struct TimedRTT curr_min_rtt_timed; /* The current observed minRTT with
|
struct TimedRTT curr_min_rtt_timed; /* The current observed minRTT with
|
||||||
the timestamp when it was observed */
|
the timestamp when it was observed */
|
||||||
|
|||||||
Reference in New Issue
Block a user