Print this page
3660 tcp_slow_start_* tunables should allow increasing the initial congestion window
Reviewed by: Dan McDonald <danmcd@nexenta.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Reviewed by: Brendan Gregg <brendan.gregg@joyent.com>

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2011, Joyent Inc. All rights reserved.
+ * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #ifndef _INET_TCP_IMPL_H
 #define _INET_TCP_IMPL_H
 

@@ -197,17 +198,44 @@
  * depending on the caller.  If the upper layer has not used the
  * TCP_INIT_CWND option to change the initial cwnd, tcp_init_cwnd
  * should be 0 and we use the formula in RFC 3390 to set tcp_cwnd.
  * If the upper layer has changed set the tcp_init_cwnd, just use
  * it to calculate the tcp_cwnd.
+ *
+ * "An Argument for Increasing TCP's Initial Congestion Window"
+ * ACM SIGCOMM Computer Communications Review, vol. 40 (2010), pp. 27-33
+ *  -- Nandita Dukkipati, Tiziana Refice, Yuchung Cheng,
+ *     Hsiao-keng Jerry Chu, Tom Herbert, Amit Agarwal,
+ *     Arvind Jain, Natalia Sutin
+ *
+ *   "Based on the results from our experiments, we believe the
+ *    initial congestion window should be at least ten segments
+ *    and the same be investigated for standardization by the IETF."
+ *
+ * As such, the def_max_init_cwnd argument with which this macro is
+ * invoked is either the tcps_slow_start_initial or
+ * tcps_slow_start_after_idle which both default to 0 and will respect
+ * RFC 3390 exactly.  If the tunables are explicitly set by the operator,
+ * then the initial congestion window should be set as the operator
+ * demands, within reason. We shall arbitrarily define reason as a
+ * maximum of 16 (same as used by the TCP_INIT_CWND setsockopt).
  */
+
+/* Maximum TCP initial cwin (start/restart). */
+#define TCP_MAX_INIT_CWND       16
+
 #define TCP_SET_INIT_CWND(tcp, mss, def_max_init_cwnd)                  \
 {                                                                       \
         if ((tcp)->tcp_init_cwnd == 0) {                                \
-                (tcp)->tcp_cwnd = MIN(def_max_init_cwnd * (mss),        \
-                    MIN(4 * (mss), MAX(2 * (mss), 4380 / (mss) * (mss)))); \
+                if (def_max_init_cwnd == 0) {                           \
+                        (tcp)->tcp_cwnd = MIN(4 * (mss),                \
+                            MAX(2 * (mss), 4380 / (mss) * (mss)));      \
         } else {                                                        \
+                        (tcp)->tcp_cwnd = MIN(TCP_MAX_INIT_CWND * (mss),\
+                            def_max_init_cwnd * (mss));                 \
+                }                                                       \
+        } else {                                                        \
                 (tcp)->tcp_cwnd = (tcp)->tcp_init_cwnd * (mss);         \
         }                                                               \
         tcp->tcp_cwnd_cnt = 0;                                          \
 }