]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
net: Add rtnetlink init_rcvwnd to set the TCP initial receive window
authorlaurent chavey <chavey@google.com>
Tue, 15 Dec 2009 11:15:28 +0000 (11:15 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Dec 2009 22:13:30 +0000 (14:13 -0800)
Add rtnetlink init_rcvwnd to set the TCP initial receive window size
advertised by passive and active TCP connections.
The current Linux TCP implementation limits the advertised TCP initial
receive window to the one prescribed by slow start. For short lived
TCP connections used for transaction type of traffic (i.e. http
requests), bounding the advertised TCP initial receive window results
in increased latency to complete the transaction.
Support for setting initial congestion window is already supported
using rtnetlink init_cwnd, but the feature is useless without the
ability to set a larger TCP initial receive window.
The rtnetlink init_rcvwnd allows increasing the TCP initial receive
window, allowing TCP connection to advertise larger TCP receive window
than the ones bounded by slow start.

Signed-off-by: Laurent Chavey <chavey@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/rtnetlink.h
include/net/dst.h
include/net/tcp.h
net/ipv4/syncookies.c
net/ipv4/tcp_output.c
net/ipv6/syncookies.c

index 05330fc5b436034aa1b361934e2180bd96266938..9590364fe8b53fa4082834c47ff64b322194fa47 100644 (file)
@@ -362,6 +362,8 @@ enum {
 #define RTAX_FEATURES RTAX_FEATURES
        RTAX_RTO_MIN,
 #define RTAX_RTO_MIN RTAX_RTO_MIN
+       RTAX_INITRWND,
+#define RTAX_INITRWND RTAX_INITRWND
        __RTAX_MAX
 };
 
index 39c4a5963e12a8cece4cd7c4d2bd9a8ee192361d..ce078cda6b748a61eadfcf16315b84e8893aeded 100644 (file)
@@ -83,8 +83,6 @@ struct dst_entry {
         * (L1_CACHE_SIZE would be too much)
         */
 #ifdef CONFIG_64BIT
-       long                    __pad_to_align_refcnt[2];
-#else
        long                    __pad_to_align_refcnt[1];
 #endif
        /*
index 185e22baecb1deb39c92e8b32450517a6b762ab7..788c99f98597d6e59b900951b18e6089e2ba0a69 100644 (file)
@@ -965,7 +965,8 @@ static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
 /* Determine a window scaling and initial window to offer. */
 extern void tcp_select_initial_window(int __space, __u32 mss,
                                      __u32 *rcv_wnd, __u32 *window_clamp,
-                                     int wscale_ok, __u8 *rcv_wscale);
+                                     int wscale_ok, __u8 *rcv_wscale,
+                                     __u32 init_rcv_wnd);
 
 static inline int tcp_win_from_space(int space)
 {
index 66fd80ef247337d03f84fd264aab748f60346297..5c24db4a3c91a54d7d6b3b86e8d4d906999d7d76 100644 (file)
@@ -358,7 +358,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 
        tcp_select_initial_window(tcp_full_space(sk), req->mss,
                                  &req->rcv_wnd, &req->window_clamp,
-                                 ireq->wscale_ok, &rcv_wscale);
+                                 ireq->wscale_ok, &rcv_wscale,
+                                 dst_metric(&rt->u.dst, RTAX_INITRWND));
 
        ireq->rcv_wscale  = rcv_wscale;
 
index 12b2af36eab8fd4c652bcff19e3d535dfc54801c..4a1605d3f909666321b6b6c1684354bbc58a22f6 100644 (file)
@@ -183,7 +183,8 @@ static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
  */
 void tcp_select_initial_window(int __space, __u32 mss,
                               __u32 *rcv_wnd, __u32 *window_clamp,
-                              int wscale_ok, __u8 *rcv_wscale)
+                              int wscale_ok, __u8 *rcv_wscale,
+                              __u32 init_rcv_wnd)
 {
        unsigned int space = (__space < 0 ? 0 : __space);
 
@@ -232,7 +233,13 @@ void tcp_select_initial_window(int __space, __u32 mss,
                        init_cwnd = 2;
                else if (mss > 1460)
                        init_cwnd = 3;
-               if (*rcv_wnd > init_cwnd * mss)
+               /* when initializing use the value from init_rcv_wnd
+                * rather than the default from above
+                */
+               if (init_rcv_wnd &&
+                   (*rcv_wnd > init_rcv_wnd * mss))
+                       *rcv_wnd = init_rcv_wnd * mss;
+               else if (*rcv_wnd > init_cwnd * mss)
                        *rcv_wnd = init_cwnd * mss;
        }
 
@@ -2417,7 +2424,8 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
                        &req->rcv_wnd,
                        &req->window_clamp,
                        ireq->wscale_ok,
-                       &rcv_wscale);
+                       &rcv_wscale,
+                       dst_metric(dst, RTAX_INITRWND));
                ireq->rcv_wscale = rcv_wscale;
        }
 
@@ -2544,7 +2552,8 @@ static void tcp_connect_init(struct sock *sk)
                                  &tp->rcv_wnd,
                                  &tp->window_clamp,
                                  sysctl_tcp_window_scaling,
-                                 &rcv_wscale);
+                                 &rcv_wscale,
+                                 dst_metric(dst, RTAX_INITRWND));
 
        tp->rx_opt.rcv_wscale = rcv_wscale;
        tp->rcv_ssthresh = tp->rcv_wnd;
index 7208a06576c6843996a02796804d33e61a524ee8..34d1f0690d7e4f6031172fd4640da207b07c25b3 100644 (file)
@@ -269,7 +269,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
        tcp_select_initial_window(tcp_full_space(sk), req->mss,
                                  &req->rcv_wnd, &req->window_clamp,
-                                 ireq->wscale_ok, &rcv_wscale);
+                                 ireq->wscale_ok, &rcv_wscale,
+                                 dst_metric(dst, RTAX_INITRWND));
 
        ireq->rcv_wscale = rcv_wscale;