Page MenuHomeFreeBSD

D8253.diff
No OneTemporary

D8253.diff

Index: sys/netinet/cc/cc_cubic.h
===================================================================
--- sys/netinet/cc/cc_cubic.h
+++ sys/netinet/cc/cc_cubic.h
@@ -42,6 +42,8 @@
/* Number of bits of precision for fixed point math calcs. */
#define CUBIC_SHIFT 8
+#define CUBIC_SCALE (1 << CUBIC_SHIFT)
+
#define CUBIC_SHIFT_4 32
/* 0.5 << CUBIC_SHIFT. */
Index: sys/netinet/cc/cc_cubic.c
===================================================================
--- sys/netinet/cc/cc_cubic.c
+++ sys/netinet/cc/cc_cubic.c
@@ -96,11 +96,20 @@
int epoch_ack_count;
/* Time of last congestion event in ticks. */
int t_last_cong;
+ /* Time of last congestion event in ticks for previous event. */
+ int t_last_cong_prev;
};
static MALLOC_DEFINE(M_CUBIC, "cubic data",
"Per connection data required for the CUBIC congestion control algorithm");
+SYSCTL_NODE(_net_inet_tcp_cc, OID_AUTO, cubic, CTLFLAG_RW, NULL,
+ "cubic congestion control related settings");
+
+static int fast_convergence = 1;
+SYSCTL_INT(_net_inet_tcp_cc_cubic, OID_AUTO, fast_convergence, CTLFLAG_RWTUN,
+ &fast_convergence, 0, "Enable fast convergence");
+
struct cc_algo cubic_cc_algo = {
.name = "cubic",
.ack_received = cubic_ack_received,
@@ -247,7 +256,6 @@
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
- cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = win;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
}
@@ -259,9 +267,12 @@
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
- cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
cubic_data->max_cwnd = win;
cubic_data->t_last_cong = ticks;
+ /*
+ * cubic_ssthresh_update(ccv) sets ssthresh to cwnd
+ * scaled by beta so this assignment is equivalent
+ */
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
@@ -275,13 +286,19 @@
* chance the first one is a false alarm and may not indicate
* congestion.
*/
- if (CCV(ccv, t_rxtshift) >= 2) {
- cubic_data->num_cong_events++;
- cubic_data->t_last_cong = ticks;
- cubic_ssthresh_update(ccv);
- cubic_data->max_cwnd = win;
- CCV(ccv, snd_cwnd) = mss;
- }
+ if (CCV(ccv, t_rxtshift) == 1)
+ cubic_data->t_last_cong_prev = cubic_data->t_last_cong;
+ cubic_ssthresh_update(ccv);
+ cubic_data->num_cong_events++;
+ cubic_data->max_cwnd = win;
+ cubic_data->t_last_cong = ticks;
+ CCV(ccv, snd_cwnd) = mss;
+ break;
+ case CC_RTO_ERR:
+ cubic_data->num_cong_events--;
+ cubic_data->t_last_cong = cubic_data->t_last_cong_prev;
+ cubic_data->max_cwnd = max(cubic_data->max_cwnd,
+ cubic_data->prev_max_cwnd);
break;
}
}
@@ -411,18 +428,52 @@
cubic_ssthresh_update(struct cc_var *ccv)
{
struct cubic *cubic_data;
+ u_long snd_ssthresh, snd_cwnd;
cubic_data = ccv->cc_data;
/*
- * On the first congestion event, set ssthresh to cwnd * 0.5, on
- * subsequent congestion events, set it to cwnd * beta.
+ * 3.5. Multiplicative decrease
+ *
+ * When a packet loss occurs, CUBIC reduces its window size by a factor
+ * of beta. Parameter beta_cubic SHOULD be set to 0.7.
+ *
+ * W_max = cwnd; // save window size before reduction
+ * cwnd = cwnd * beta_cubic; // window reduction
*/
- if (cubic_data->num_cong_events == 0)
- CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd) >> 1;
+ snd_ssthresh = (CCV(ccv, snd_cwnd) * CUBIC_BETA) >> CUBIC_SHIFT;
+ CCV(ccv, snd_ssthresh) = max(snd_ssthresh, 2*CCV(ccv, t_maxseg));
+
+ /*
+ * 3.6. Fast convergence
+ *
+ * To improve the convergence speed of CUBIC, we add a heuristic in the
+ * protocol. When a new flow joins the network, existing flows in the
+ * network need to give up their bandwidth shares to allow the flow some
+ * room for growth if the existing flows have been using all the
+ * bandwidth of the network. To increase this release of bandwidth by
+ * existing flows, the following mechanism called fast convergence
+ * SHOULD be implemented.
+ *
+ * With fast convergence, when a loss event occurs, before a window
+ * reduction of congestion window, a flow remembers the last value of
+ * W_max before it updates W_max for the current loss event. Let us
+ * call the last value of W_max to be W_last_max.
+ *
+ * if (W_max < W_last_max){ // check downward trend
+ * W_last_max = W_max; // remember the last W_max
+ * W_max = W_max*(1+beta_cubic)/2; // further reduce W_max
+ * } else { // check upward trend
+ * W_last_max = W_max // remember the last W_max
+ * }
+ */
+ snd_cwnd = CCV(ccv, snd_cwnd);
+
+ if (snd_cwnd < cubic_data->prev_max_cwnd && fast_convergence)
+ cubic_data->prev_max_cwnd = (snd_cwnd *
+ (CUBIC_SCALE + CUBIC_BETA)) / (2 * CUBIC_SCALE);
else
- CCV(ccv, snd_ssthresh) = ((u_long)CCV(ccv, snd_cwnd) *
- CUBIC_BETA) >> CUBIC_SHIFT;
+ cubic_data->prev_max_cwnd = snd_cwnd;
}

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 19, 2:29 AM (11 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29889319
Default Alt Text
D8253.diff (4 KB)

Event Timeline