Update the repository with the changes made since the last LKML review.
This commit is contained in:
+72
-35
@@ -88,10 +88,17 @@ static u32 beta_scale __read_mostly;
|
|||||||
static u64 cube_factor __read_mostly;
|
static u64 cube_factor __read_mostly;
|
||||||
|
|
||||||
/* Note parameters that are used for precomputing scale factors are read-only */
|
/* Note parameters that are used for precomputing scale factors are read-only */
|
||||||
|
|
||||||
|
static int beta_param_set(const char *val, const struct kernel_param *kp);
|
||||||
|
static const struct kernel_param_ops beta_param_ops = {
|
||||||
|
.set = beta_param_set,
|
||||||
|
.get = param_get_int,
|
||||||
|
};
|
||||||
|
module_param_cb(beta, &beta_param_ops, &beta, 0644);
|
||||||
|
MODULE_PARM_DESC(beta, "beta for multiplicative increase");
|
||||||
|
|
||||||
module_param(fast_convergence, int, 0644);
|
module_param(fast_convergence, int, 0644);
|
||||||
MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
|
MODULE_PARM_DESC(fast_convergence, "turn on/off fast convergence");
|
||||||
module_param(beta, int, 0644);
|
|
||||||
MODULE_PARM_DESC(beta, "beta for multiplicative increase");
|
|
||||||
module_param(initial_ssthresh, int, 0644);
|
module_param(initial_ssthresh, int, 0644);
|
||||||
MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
|
MODULE_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
|
||||||
module_param(bic_scale, int, 0444);
|
module_param(bic_scale, int, 0444);
|
||||||
@@ -100,6 +107,26 @@ MODULE_PARM_DESC(bic_scale,
|
|||||||
module_param(tcp_friendliness, int, 0644);
|
module_param(tcp_friendliness, int, 0644);
|
||||||
MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
|
MODULE_PARM_DESC(tcp_friendliness, "turn on/off tcp friendliness");
|
||||||
|
|
||||||
|
/* Check & set the new beta parameter candidate value.
|
||||||
|
*/
|
||||||
|
static int beta_param_set(const char *val, const struct kernel_param *kp)
|
||||||
|
{
|
||||||
|
int beta_candidate;
|
||||||
|
int ret = kstrtoint(val, 10, &beta_candidate);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (beta_candidate <= 0 || beta_candidate >= BICTCP_BETA_SCALE) {
|
||||||
|
pr_err_once("TCP ROCCET: beta must be between 0 and %d\n",
|
||||||
|
BICTCP_BETA_SCALE);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return param_set_int(val, kp);
|
||||||
|
}
|
||||||
|
|
||||||
/* Used to check certain roccet parameters used in `param_precompute` in order
|
/* Used to check certain roccet parameters used in `param_precompute` in order
|
||||||
* to avoid invalid scale-related calculations. This validates the specified
|
* to avoid invalid scale-related calculations. This validates the specified
|
||||||
* parameters or rejects them.
|
* parameters or rejects them.
|
||||||
@@ -170,6 +197,7 @@ static void roccet_reset(struct sock *sk, struct roccettcp *ca)
|
|||||||
ca->last_rtt = U32_MAX;
|
ca->last_rtt = U32_MAX;
|
||||||
|
|
||||||
ca->roccet_last_event_time_us = 0;
|
ca->roccet_last_event_time_us = 0;
|
||||||
|
ca->last_event_time_set = false;
|
||||||
ca->ack_rate_last_rate = 0;
|
ca->ack_rate_last_rate = 0;
|
||||||
|
|
||||||
/* Initialize to current time to avoid an
|
/* Initialize to current time to avoid an
|
||||||
@@ -186,6 +214,7 @@ static void roccet_reset(struct sock *sk, struct roccettcp *ca)
|
|||||||
ca->state = LAUNCH;
|
ca->state = LAUNCH;
|
||||||
ca->probe_min_rtt_until = 0;
|
ca->probe_min_rtt_until = 0;
|
||||||
ca->refill_until = 0;
|
ca->refill_until = 0;
|
||||||
|
ca->rtt_probe_timers_set = false;
|
||||||
|
|
||||||
ca->initial_limit_reached = false;
|
ca->initial_limit_reached = false;
|
||||||
ca->is_in_initial_launch = false;
|
ca->is_in_initial_launch = false;
|
||||||
@@ -357,6 +386,7 @@ static void roccet_congestion_event(struct sock *sk, u32 now)
|
|||||||
|
|
||||||
ca->epoch_start = 0;
|
ca->epoch_start = 0;
|
||||||
ca->roccet_last_event_time_us = now;
|
ca->roccet_last_event_time_us = now;
|
||||||
|
ca->last_event_time_set = true;
|
||||||
|
|
||||||
if (ca->state == RTT_PROBE) {
|
if (ca->state == RTT_PROBE) {
|
||||||
/* In case we are in RTT_PROBE, continue with this state, as
|
/* In case we are in RTT_PROBE, continue with this state, as
|
||||||
@@ -402,8 +432,8 @@ static void roccet_enter_min_rtt_probe(struct sock *sk, u32 now)
|
|||||||
/* If probing is already set, there was a mix up.
|
/* If probing is already set, there was a mix up.
|
||||||
* Continue anyway so we can recover.
|
* Continue anyway so we can recover.
|
||||||
*/
|
*/
|
||||||
if (ca->probe_min_rtt_until > 0)
|
if (ca->rtt_probe_timers_set)
|
||||||
pr_warn_once("ROCCET: Probing time should not be set");
|
pr_warn_once("ROCCET: Probing time should not be set when entering RTT Probe");
|
||||||
|
|
||||||
/* Safeguard for an "infinite" probe. This should logically never
|
/* Safeguard for an "infinite" probe. This should logically never
|
||||||
* happen but still safeguard it.
|
* happen but still safeguard it.
|
||||||
@@ -427,9 +457,9 @@ static void roccet_enter_min_rtt_probe(struct sock *sk, u32 now)
|
|||||||
* we set the cwnd to its previous value after probing.
|
* we set the cwnd to its previous value after probing.
|
||||||
*/
|
*/
|
||||||
if (!tcp_is_cwnd_limited(sk))
|
if (!tcp_is_cwnd_limited(sk))
|
||||||
probe_cwnd = max(tcp_snd_cwnd(tp) / 3, TCP_INIT_CWND);
|
probe_cwnd = max(tcp_snd_cwnd(tp) / 3, 1);
|
||||||
else
|
else
|
||||||
probe_cwnd = max(tcp_snd_cwnd(tp) / 2, TCP_INIT_CWND);
|
probe_cwnd = max(tcp_snd_cwnd(tp) / 2, 1);
|
||||||
|
|
||||||
ca->probe_min_rtt_until = now + interval;
|
ca->probe_min_rtt_until = now + interval;
|
||||||
ca->cwnd_before_min_rtt_probe = tcp_snd_cwnd(tp);
|
ca->cwnd_before_min_rtt_probe = tcp_snd_cwnd(tp);
|
||||||
@@ -446,6 +476,7 @@ static void roccet_enter_min_rtt_probe(struct sock *sk, u32 now)
|
|||||||
* For this we use the previous cwnd for another probing interval.
|
* For this we use the previous cwnd for another probing interval.
|
||||||
*/
|
*/
|
||||||
ca->refill_until = ca->probe_min_rtt_until + interval;
|
ca->refill_until = ca->probe_min_rtt_until + interval;
|
||||||
|
ca->rtt_probe_timers_set = true; /* Now both timers are set. */
|
||||||
|
|
||||||
/* Now we know that ca->probe_min_rtt_until < ca->refill_until
|
/* Now we know that ca->probe_min_rtt_until < ca->refill_until
|
||||||
* and we advance to the next state of the probing phase.
|
* and we advance to the next state of the probing phase.
|
||||||
@@ -453,7 +484,6 @@ static void roccet_enter_min_rtt_probe(struct sock *sk, u32 now)
|
|||||||
* Wrap-arounds of these values are handled by the relevant
|
* Wrap-arounds of these values are handled by the relevant
|
||||||
* if-conditions.
|
* if-conditions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ca->state = RTT_PROBE;
|
ca->state = RTT_PROBE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,25 +500,26 @@ static void roccet_min_rtt_probe(struct sock *sk, u32 now)
|
|||||||
* probe_min_rtt_until wrap-arounds are handled by the time_before32
|
* probe_min_rtt_until wrap-arounds are handled by the time_before32
|
||||||
* check.
|
* check.
|
||||||
*/
|
*/
|
||||||
if (ca->probe_min_rtt_until == 0)
|
if (!ca->rtt_probe_timers_set)
|
||||||
pr_warn_once("ROCCET: Probing time should be set");
|
pr_warn_once("ROCCET: Probing time should be set");
|
||||||
else if (time_before32(now, ca->probe_min_rtt_until))
|
else if (time_before32(now, ca->probe_min_rtt_until))
|
||||||
/* No state change if we are in the probing interval. */
|
/* No state change if we are in the probing interval. */
|
||||||
return;
|
return;
|
||||||
|
else if (time_after32(now, ca->refill_until))
|
||||||
/* If the interval has passed we likely just entered the refill
|
/* If the probe_min_rtt_until interval has passed we likely
|
||||||
* interval, so go into RTT_PROBE_REFILL.
|
* just entered the refill interval, so go into
|
||||||
* If we are not in the interval, something went wrong and we should
|
* RTT_PROBE_REFILL. If we are not in the refill_until
|
||||||
* quickly exit the probing phase.
|
* interval, something went wrong and we should quickly exit
|
||||||
*
|
* the probing phase.
|
||||||
* Wraps-arounds of refill_until are caught by the time_after32 check.
|
*
|
||||||
*/
|
* Wraps-arounds of refill_until are caught by the time_after32
|
||||||
if (time_after32(now, ca->refill_until))
|
* check.
|
||||||
|
*/
|
||||||
pr_warn_once("ROCCET: Skipped refill interval.");
|
pr_warn_once("ROCCET: Skipped refill interval.");
|
||||||
|
|
||||||
/* Reset cwnd to refill the pipe and consequently clear the stored
|
/* Reset cwnd to refill the pipe and consequently clear the stored
|
||||||
* window.
|
* window.
|
||||||
* Also perform sanity check. THis should never happen.
|
* Also perform sanity check. This should never happen.
|
||||||
*/
|
*/
|
||||||
if (ca->cwnd_before_min_rtt_probe == 0)
|
if (ca->cwnd_before_min_rtt_probe == 0)
|
||||||
pr_warn_once("ROCCET: cwnd_before_min_rtt_probe is 0 during RTT_PROBE.");
|
pr_warn_once("ROCCET: cwnd_before_min_rtt_probe is 0 during RTT_PROBE.");
|
||||||
@@ -618,14 +649,6 @@ static void bictcp_update(struct roccettcp *ca, u32 cwnd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In case there are any ACKs left over from LAUNCH,
|
|
||||||
* apply them after the new epoch-reset
|
|
||||||
*/
|
|
||||||
if (ca->ack_carry_over) {
|
|
||||||
ca->ack_cnt += ca->ack_carry_over;
|
|
||||||
ca->ack_carry_over = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* cubic function - calc */
|
/* cubic function - calc */
|
||||||
/* calculate c * time^3 / rtt,
|
/* calculate c * time^3 / rtt,
|
||||||
* while considering overflow in calculation of time^3
|
* while considering overflow in calculation of time^3
|
||||||
@@ -722,15 +745,14 @@ static void roccet_launch_update(struct sock *sk, u32 acked)
|
|||||||
/* Halving the cwnd will undo the previous step of slow
|
/* Halving the cwnd will undo the previous step of slow
|
||||||
* start. Which is fine since the pipe is already full.
|
* start. Which is fine since the pipe is already full.
|
||||||
*/
|
*/
|
||||||
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) / 2,
|
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) / 2, 1));
|
||||||
TCP_INIT_CWND));
|
|
||||||
} else {
|
} else {
|
||||||
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) -
|
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) -
|
||||||
(tcp_snd_cwnd(tp) / 3),
|
(tcp_snd_cwnd(tp) / 3), 1));
|
||||||
TCP_INIT_CWND));
|
|
||||||
}
|
}
|
||||||
tp->snd_ssthresh = tcp_snd_cwnd(tp);
|
tp->snd_ssthresh = tcp_snd_cwnd(tp);
|
||||||
ca->roccet_last_event_time_us = now;
|
ca->roccet_last_event_time_us = now;
|
||||||
|
ca->last_event_time_set = true;
|
||||||
ca->state = ORBITER;
|
ca->state = ORBITER;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -763,7 +785,7 @@ static void roccet_orbiter_update(struct sock *sk, u32 acked)
|
|||||||
u32 roccet_xj, jitter, sent, received;
|
u32 roccet_xj, jitter, sent, received;
|
||||||
|
|
||||||
/* Enter DRAIN when roccet was recently triggered */
|
/* Enter DRAIN when roccet was recently triggered */
|
||||||
if (ca->roccet_last_event_time_us &&
|
if (ca->last_event_time_set &&
|
||||||
time_before32(now, ca->roccet_last_event_time_us +
|
time_before32(now, ca->roccet_last_event_time_us +
|
||||||
100 * USEC_PER_MSEC)) {
|
100 * USEC_PER_MSEC)) {
|
||||||
ca->state = DRAIN;
|
ca->state = DRAIN;
|
||||||
@@ -850,6 +872,14 @@ static void roccet_orbiter_update(struct sock *sk, u32 acked)
|
|||||||
if (!tcp_is_cwnd_limited(sk) || sent_more_than_acked)
|
if (!tcp_is_cwnd_limited(sk) || sent_more_than_acked)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* In case there are any ACKs left over from LAUNCH,
|
||||||
|
* apply them now.
|
||||||
|
*/
|
||||||
|
if (ca->ack_carry_over) {
|
||||||
|
acked += ca->ack_carry_over;
|
||||||
|
ca->ack_carry_over = 0;
|
||||||
|
}
|
||||||
|
|
||||||
bictcp_update(ca, tcp_snd_cwnd(tp), acked);
|
bictcp_update(ca, tcp_snd_cwnd(tp), acked);
|
||||||
tcp_cong_avoid_ai(tp, max(1, ca->cnt), acked);
|
tcp_cong_avoid_ai(tp, max(1, ca->cnt), acked);
|
||||||
}
|
}
|
||||||
@@ -952,6 +982,7 @@ static void roccet_handle_state_transitions(struct roccettcp *ca,
|
|||||||
(ca->state != RTT_PROBE && ca->state != RTT_PROBE_REFILL)) {
|
(ca->state != RTT_PROBE && ca->state != RTT_PROBE_REFILL)) {
|
||||||
ca->probe_min_rtt_until = 0;
|
ca->probe_min_rtt_until = 0;
|
||||||
ca->refill_until = 0;
|
ca->refill_until = 0;
|
||||||
|
ca->rtt_probe_timers_set = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,7 +998,7 @@ static void roccet_state(struct sock *sk, u8 new_state)
|
|||||||
|
|
||||||
if (new_state == TCP_CA_Loss) {
|
if (new_state == TCP_CA_Loss) {
|
||||||
roccet_reset(sk, ca);
|
roccet_reset(sk, ca);
|
||||||
tcp_snd_cwnd_set(tp, TCP_INIT_CWND);
|
tcp_snd_cwnd_set(tp, 1);
|
||||||
} else if (new_state == TCP_CA_CWR) {
|
} else if (new_state == TCP_CA_CWR) {
|
||||||
/* Handle CWR as ROCCET congestion event,
|
/* Handle CWR as ROCCET congestion event,
|
||||||
* however afterwards always set Wmax to the current cwnd.
|
* however afterwards always set Wmax to the current cwnd.
|
||||||
@@ -1064,9 +1095,15 @@ static void roccet_drain_update(struct sock *sk, u32 now)
|
|||||||
struct tcp_sock *tp = tcp_sk(sk);
|
struct tcp_sock *tp = tcp_sk(sk);
|
||||||
struct roccettcp *ca = inet_csk_ca(sk);
|
struct roccettcp *ca = inet_csk_ca(sk);
|
||||||
|
|
||||||
if (ca->roccet_last_event_time_us &&
|
/* If we are in DRAIN, ca->roccet_last_event_time_us has to be set.
|
||||||
time_after32(now, ca->roccet_last_event_time_us +
|
* If more than 100 ms have passed after a roccet event, exit DRAIN.
|
||||||
100 * USEC_PER_MSEC)) {
|
* The between check is here to handle idle-times and timer-wraps.
|
||||||
|
* It is ok if we "accidentally" exit DRAIN in such an occasion.
|
||||||
|
*/
|
||||||
|
if (!time_between32(now, ca->roccet_last_event_time_us
|
||||||
|
- 100 * USEC_PER_MSEC,
|
||||||
|
ca->roccet_last_event_time_us
|
||||||
|
+ 100 * USEC_PER_MSEC)) {
|
||||||
if (tcp_in_slow_start(tp))
|
if (tcp_in_slow_start(tp))
|
||||||
ca->state = LAUNCH;
|
ca->state = LAUNCH;
|
||||||
else
|
else
|
||||||
|
|||||||
+11
-3
@@ -54,6 +54,10 @@ struct roccettcp {
|
|||||||
u32 interval_snd_seq_start;
|
u32 interval_snd_seq_start;
|
||||||
u32 interval_una_seq_start;
|
u32 interval_una_seq_start;
|
||||||
|
|
||||||
|
u32 ack_carry_over; /* Used to carry over leftover acks from
|
||||||
|
* LAUNCH to ORBITER
|
||||||
|
*/
|
||||||
|
|
||||||
u32 ack_rate_last_rate_time; /* Timestamp of the last ACK-rate */
|
u32 ack_rate_last_rate_time; /* Timestamp of the last ACK-rate */
|
||||||
u16 ack_rate_last_rate; /* Last ACK-rate */
|
u16 ack_rate_last_rate; /* Last ACK-rate */
|
||||||
u16 ack_rate_curr_rate; /* Current ACK-rate */
|
u16 ack_rate_curr_rate; /* Current ACK-rate */
|
||||||
@@ -69,9 +73,13 @@ struct roccettcp {
|
|||||||
bool is_in_initial_launch: 1; /* true if the connection is in
|
bool is_in_initial_launch: 1; /* true if the connection is in
|
||||||
* the initial launch phase.
|
* the initial launch phase.
|
||||||
*/
|
*/
|
||||||
u32 ack_carry_over; /* Used to carry over leftover acks from
|
bool last_event_time_set: 1; /* true if the last event time
|
||||||
* LAUNCH to ORBITER
|
* has been set/initialized.
|
||||||
*/
|
*/
|
||||||
|
bool rtt_probe_timers_set: 1; /* true if refill_until and
|
||||||
|
* probe_min_rtt_until are currently
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __TCP_ROCCET_H */
|
#endif /* __TCP_ROCCET_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user