|
@@ -56,6 +56,7 @@ struct dctcp {
|
|
|
u32 next_seq;
|
|
|
u32 ce_state;
|
|
|
u32 delayed_ack_reserved;
|
|
|
+ u32 loss_cwnd;
|
|
|
};
|
|
|
|
|
|
static unsigned int dctcp_shift_g __read_mostly = 4; /* g = 1/2^4 */
|
|
@@ -96,6 +97,7 @@ static void dctcp_init(struct sock *sk)
|
|
|
ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA);
|
|
|
|
|
|
ca->delayed_ack_reserved = 0;
|
|
|
+ ca->loss_cwnd = 0;
|
|
|
ca->ce_state = 0;
|
|
|
|
|
|
dctcp_reset(tp, ca);
|
|
@@ -111,9 +113,10 @@ static void dctcp_init(struct sock *sk)
|
|
|
|
|
|
static u32 dctcp_ssthresh(struct sock *sk)
|
|
|
{
|
|
|
- const struct dctcp *ca = inet_csk_ca(sk);
|
|
|
+ struct dctcp *ca = inet_csk_ca(sk);
|
|
|
struct tcp_sock *tp = tcp_sk(sk);
|
|
|
|
|
|
+ ca->loss_cwnd = tp->snd_cwnd;
|
|
|
return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->dctcp_alpha) >> 11U), 2U);
|
|
|
}
|
|
|
|
|
@@ -308,12 +311,20 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static u32 dctcp_cwnd_undo(struct sock *sk)
|
|
|
+{
|
|
|
+ const struct dctcp *ca = inet_csk_ca(sk);
|
|
|
+
|
|
|
+ return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
|
|
|
+}
|
|
|
+
|
|
|
static struct tcp_congestion_ops dctcp __read_mostly = {
|
|
|
.init = dctcp_init,
|
|
|
.in_ack_event = dctcp_update_alpha,
|
|
|
.cwnd_event = dctcp_cwnd_event,
|
|
|
.ssthresh = dctcp_ssthresh,
|
|
|
.cong_avoid = tcp_reno_cong_avoid,
|
|
|
+ .undo_cwnd = dctcp_cwnd_undo,
|
|
|
.set_state = dctcp_state,
|
|
|
.get_info = dctcp_get_info,
|
|
|
.flags = TCP_CONG_NEEDS_ECN,
|