Compare commits

...

3 Commits

Author SHA1 Message Date
Lukas Prause
e5c3729522 Adds ECN handling managed by ROCCET. 2026-02-09 13:40:16 +01:00
Lukas Prause
5ebd5c0cb7 Adjusts the comment about the ROCCET paper. 2026-01-30 13:34:47 +01:00
Lukas Prause
a4cce7378f Update paper state in README.md 2026-01-29 11:35:20 +01:00
3 changed files with 35 additions and 14 deletions

View File

@@ -11,11 +11,10 @@ The congestion avoidance phase, called ORBITER, uses
CUBIC's window growth function and adds, based on RTT CUBIC's window growth function and adds, based on RTT
and ACK rate, congestion events. and ACK rate, congestion events.
NOTE: A paper for TCP ROCCET is currently under review. A peer-reviewed paper on TCP ROCCET will be presented at the WONS 2026 conference.
Paper draft: A draft of the paper is available here:
https://arxiv.org/abs/2510.25281 https://arxiv.org/abs/2510.25281
The oldest Linux kernel version we tested with ROCCET is 6.1.
## Setup ## Setup

View File

@@ -14,8 +14,9 @@
* CUBIC's window growth function and adds, based on RTT * CUBIC's window growth function and adds, based on RTT
* and ACK rate, congestion events. * and ACK rate, congestion events.
* *
* NOTE: A paper for TCP ROCCET is currently under review. * A peer-reviewed paper on TCP ROCCET will be presented at the WONS 2026 conference.
* A draft of this paper can be found here: * A draft of the paper is available here:
* https://arxiv.org/abs/2510.25281
* *
* *
* Further information about CUBIC: * Further information about CUBIC:
@@ -128,7 +129,7 @@ static inline void roccettcp_reset(struct roccettcp *ca)
ca->bw_limit.next_check = 0; ca->bw_limit.next_check = 0;
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->ece_received = 0;
} }
static inline void update_min_rtt(struct sock *sk) static inline void update_min_rtt(struct sock *sk)
@@ -430,12 +431,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 */
@@ -486,7 +492,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);
@@ -575,6 +583,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,
@@ -583,6 +603,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",
}; };

View File

@@ -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 */