tcp: inherit listener congestion control for passive cnx
authorEric Dumazet <eric.dumazet@gmail.com>
Wed, 30 Nov 2011 01:02:41 +0000 (01:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 30 Nov 2011 21:55:26 +0000 (16:55 -0500)
Rick Jones reported that TCP_CONGESTION sockopt performed on a listener
was ignored for its children sockets : right after accept() the
congestion control for new socket is the system default one.

This seems an oversight of the initial design (quoted from Stephen)

Based on prior investigation and patch from Rick.

Reported-by: Rick Jones <rick.jones2@hp.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Stephen Hemminger <shemminger@vyatta.com>
CC: Yuchung Cheng <ycheng@google.com>
Tested-by: Rick Jones <rick.jones2@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/ip-sysctl.txt
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c

index b8867061fce4019b88e55b5fad5496044f0d682d..cb2b1c6a2ce1d22eac1f4610d2bfdca70fe721c7 100644 (file)
@@ -175,6 +175,9 @@ tcp_congestion_control - STRING
        connections. The algorithm "reno" is always available, but
        additional choices may be available based on kernel configuration.
        Default is set as part of kernel configuration.
+       For passive connections, the listener congestion control choice
+       is inherited.
+       [see setsockopt(listenfd, SOL_TCP, TCP_CONGESTION, "name" ...) ]
 
 tcp_cookie_size - INTEGER
        Default size of TCP Cookie Transactions (TCPCT) option, that may be
index a9db4b1a22156dc944addbf661187b2e71070875..c4b8b09db9f5b7a6711246f5859a64b09f851907 100644 (file)
@@ -1511,6 +1511,7 @@ exit:
        return NULL;
 put_and_exit:
        tcp_clear_xmit_timers(newsk);
+       tcp_cleanup_congestion_control(newsk);
        bh_unlock_sock(newsk);
        sock_put(newsk);
        goto exit;
index 945efffdd929b81b1cf4943bee865eecf1c25978..9dc146e5ed65073da204f9b1ff82dbf6cb786da7 100644 (file)
@@ -495,7 +495,9 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
                newtp->frto_counter = 0;
                newtp->frto_highmark = 0;
 
-               newicsk->icsk_ca_ops = &tcp_init_congestion_ops;
+               if (newicsk->icsk_ca_ops != &tcp_init_congestion_ops &&
+                   !try_module_get(newicsk->icsk_ca_ops->owner))
+                       newicsk->icsk_ca_ops = &tcp_init_congestion_ops;
 
                tcp_set_ca_state(newsk, TCP_CA_Open);
                tcp_init_xmit_timers(newsk);