aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
authorTom Herbert <therbert@google.com>2013-01-22 04:50:39 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-23 13:44:01 -0500
commit5ba24953e9707387cce87b07f0d5fbdd03c5c11b (patch)
treec98e56f8a06f07ff585f85cbe6af8cd9c19f2ca6 /net/ipv6/tcp_ipv6.c
parentba418fa357a7b3c9d477f4706c6c7c96ddbd1360 (diff)
soreuseport: TCP/IPv6 implementation
Motivation for soreuseport would be something like a web server binding to port 80 running with multiple threads, where each thread might have it's own listener socket. This could be done as an alternative to other models: 1) have one listener thread which dispatches completed connections to workers. 2) accept on a single listener socket from multiple threads. In case #1 the listener thread can easily become the bottleneck with high connection turn-over rate. In case #2, the proportion of connections accepted per thread tends to be uneven under high connection load (assuming simple event loop: while (1) { accept(); process() }, wakeup does not promote fairness among the sockets. We have seen the disproportion to be as high as 3:1 ratio between thread accepting most connections and the one accepting the fewest. With so_reusport the distribution is uniform. Signed-off-by: Tom Herbert <therbert@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 3701c3c6e2eb..06087e58738a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -834,7 +834,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
834 * no RST generated if md5 hash doesn't match. 834 * no RST generated if md5 hash doesn't match.
835 */ 835 */
836 sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev), 836 sk1 = inet6_lookup_listener(dev_net(skb_dst(skb)->dev),
837 &tcp_hashinfo, &ipv6h->daddr, 837 &tcp_hashinfo, &ipv6h->saddr,
838 th->source, &ipv6h->daddr,
838 ntohs(th->source), inet6_iif(skb)); 839 ntohs(th->source), inet6_iif(skb));
839 if (!sk1) 840 if (!sk1)
840 return; 841 return;
@@ -1598,6 +1599,7 @@ do_time_wait:
1598 struct sock *sk2; 1599 struct sock *sk2;
1599 1600
1600 sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, 1601 sk2 = inet6_lookup_listener(dev_net(skb->dev), &tcp_hashinfo,
1602 &ipv6_hdr(skb)->saddr, th->source,
1601 &ipv6_hdr(skb)->daddr, 1603 &ipv6_hdr(skb)->daddr,
1602 ntohs(th->dest), inet6_iif(skb)); 1604 ntohs(th->dest), inet6_iif(skb));
1603 if (sk2 != NULL) { 1605 if (sk2 != NULL) {