Update the repository with the changes made since the last LKML review.
This commit is contained in:
+70
-33
@@ -88,10 +88,17 @@ static u32 beta_scale __read_mostly;
|
||||
static u64 cube_factor __read_mostly;
|
||||
|
||||
/* 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_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_PARM_DESC(initial_ssthresh, "initial value of slow start threshold");
|
||||
module_param(bic_scale, int, 0444);
|
||||
@@ -100,6 +107,26 @@ MODULE_PARM_DESC(bic_scale,
|
||||
module_param(tcp_friendliness, int, 0644);
|
||||
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
|
||||
* to avoid invalid scale-related calculations. This validates the specified
|
||||
* parameters or rejects them.
|
||||
@@ -170,6 +197,7 @@ static void roccet_reset(struct sock *sk, struct roccettcp *ca)
|
||||
ca->last_rtt = U32_MAX;
|
||||
|
||||
ca->roccet_last_event_time_us = 0;
|
||||
ca->last_event_time_set = false;
|
||||
ca->ack_rate_last_rate = 0;
|
||||
|
||||
/* 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->probe_min_rtt_until = 0;
|
||||
ca->refill_until = 0;
|
||||
ca->rtt_probe_timers_set = false;
|
||||
|
||||
ca->initial_limit_reached = 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->roccet_last_event_time_us = now;
|
||||
ca->last_event_time_set = true;
|
||||
|
||||
if (ca->state == RTT_PROBE) {
|
||||
/* 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.
|
||||
* Continue anyway so we can recover.
|
||||
*/
|
||||
if (ca->probe_min_rtt_until > 0)
|
||||
pr_warn_once("ROCCET: Probing time should not be set");
|
||||
if (ca->rtt_probe_timers_set)
|
||||
pr_warn_once("ROCCET: Probing time should not be set when entering RTT Probe");
|
||||
|
||||
/* Safeguard for an "infinite" probe. This should logically never
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
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->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.
|
||||
*/
|
||||
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
|
||||
* 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
|
||||
* if-conditions.
|
||||
*/
|
||||
|
||||
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
|
||||
* check.
|
||||
*/
|
||||
if (ca->probe_min_rtt_until == 0)
|
||||
if (!ca->rtt_probe_timers_set)
|
||||
pr_warn_once("ROCCET: Probing time should be set");
|
||||
else if (time_before32(now, ca->probe_min_rtt_until))
|
||||
/* No state change if we are in the probing interval. */
|
||||
return;
|
||||
|
||||
/* If the interval has passed we likely just entered the refill
|
||||
* interval, so go into RTT_PROBE_REFILL.
|
||||
* If we are not in the interval, something went wrong and we should
|
||||
* quickly exit the probing phase.
|
||||
else if (time_after32(now, ca->refill_until))
|
||||
/* If the probe_min_rtt_until interval has passed we likely
|
||||
* just entered the refill interval, so go into
|
||||
* RTT_PROBE_REFILL. If we are not in the refill_until
|
||||
* 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
|
||||
* check.
|
||||
*/
|
||||
if (time_after32(now, ca->refill_until))
|
||||
pr_warn_once("ROCCET: Skipped refill interval.");
|
||||
|
||||
/* Reset cwnd to refill the pipe and consequently clear the stored
|
||||
* 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)
|
||||
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 */
|
||||
/* calculate c * time^3 / rtt,
|
||||
* 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
|
||||
* start. Which is fine since the pipe is already full.
|
||||
*/
|
||||
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) / 2,
|
||||
TCP_INIT_CWND));
|
||||
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) / 2, 1));
|
||||
} else {
|
||||
tcp_snd_cwnd_set(tp, max(tcp_snd_cwnd(tp) -
|
||||
(tcp_snd_cwnd(tp) / 3),
|
||||
TCP_INIT_CWND));
|
||||
(tcp_snd_cwnd(tp) / 3), 1));
|
||||
}
|
||||
tp->snd_ssthresh = tcp_snd_cwnd(tp);
|
||||
ca->roccet_last_event_time_us = now;
|
||||
ca->last_event_time_set = true;
|
||||
ca->state = ORBITER;
|
||||
return;
|
||||
}
|
||||
@@ -763,7 +785,7 @@ static void roccet_orbiter_update(struct sock *sk, u32 acked)
|
||||
u32 roccet_xj, jitter, sent, received;
|
||||
|
||||
/* 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 +
|
||||
100 * USEC_PER_MSEC)) {
|
||||
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)
|
||||
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);
|
||||
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->probe_min_rtt_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) {
|
||||
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) {
|
||||
/* Handle CWR as ROCCET congestion event,
|
||||
* 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 roccettcp *ca = inet_csk_ca(sk);
|
||||
|
||||
if (ca->roccet_last_event_time_us &&
|
||||
time_after32(now, ca->roccet_last_event_time_us +
|
||||
100 * USEC_PER_MSEC)) {
|
||||
/* If we are in DRAIN, ca->roccet_last_event_time_us has to be set.
|
||||
* If more than 100 ms have passed after a roccet event, exit DRAIN.
|
||||
* 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))
|
||||
ca->state = LAUNCH;
|
||||
else
|
||||
|
||||
+10
-2
@@ -54,6 +54,10 @@ struct roccettcp {
|
||||
u32 interval_snd_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 */
|
||||
u16 ack_rate_last_rate; /* Last ACK-rate */
|
||||
u16 ack_rate_curr_rate; /* Current ACK-rate */
|
||||
@@ -69,8 +73,12 @@ struct roccettcp {
|
||||
bool is_in_initial_launch: 1; /* true if the connection is in
|
||||
* the initial launch phase.
|
||||
*/
|
||||
u32 ack_carry_over; /* Used to carry over leftover acks from
|
||||
* LAUNCH to ORBITER
|
||||
bool last_event_time_set: 1; /* true if the last event time
|
||||
* has been set/initialized.
|
||||
*/
|
||||
bool rtt_probe_timers_set: 1; /* true if refill_until and
|
||||
* probe_min_rtt_until are currently
|
||||
* set.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user