diff options
author | Tom Herbert <therbert@google.com> | 2013-01-22 04:50:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-23 13:44:01 -0500 |
commit | da5e36308d9f7151845018369148201a5d28b46d (patch) | |
tree | fff243a12ae5a1d16c2827b3ac41ac23ea2043c4 /include/net/inet_hashtables.h | |
parent | 055dc21a1d1d219608cd4baac7d0683fb2cbbe8a (diff) |
soreuseport: TCP/IPv4 implementation
Allow multiple listener sockets to bind to the same port.
Motivation for soresuseport 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 'include/net/inet_hashtables.h')
-rw-r--r-- | include/net/inet_hashtables.h | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 67a8fa098e3a..7b2ae9d37076 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -81,7 +81,9 @@ struct inet_bind_bucket { | |||
81 | struct net *ib_net; | 81 | struct net *ib_net; |
82 | #endif | 82 | #endif |
83 | unsigned short port; | 83 | unsigned short port; |
84 | signed short fastreuse; | 84 | signed char fastreuse; |
85 | signed char fastreuseport; | ||
86 | kuid_t fastuid; | ||
85 | int num_owners; | 87 | int num_owners; |
86 | struct hlist_node node; | 88 | struct hlist_node node; |
87 | struct hlist_head owners; | 89 | struct hlist_head owners; |
@@ -257,15 +259,19 @@ extern void inet_unhash(struct sock *sk); | |||
257 | 259 | ||
258 | extern struct sock *__inet_lookup_listener(struct net *net, | 260 | extern struct sock *__inet_lookup_listener(struct net *net, |
259 | struct inet_hashinfo *hashinfo, | 261 | struct inet_hashinfo *hashinfo, |
262 | const __be32 saddr, | ||
263 | const __be16 sport, | ||
260 | const __be32 daddr, | 264 | const __be32 daddr, |
261 | const unsigned short hnum, | 265 | const unsigned short hnum, |
262 | const int dif); | 266 | const int dif); |
263 | 267 | ||
264 | static inline struct sock *inet_lookup_listener(struct net *net, | 268 | static inline struct sock *inet_lookup_listener(struct net *net, |
265 | struct inet_hashinfo *hashinfo, | 269 | struct inet_hashinfo *hashinfo, |
270 | __be32 saddr, __be16 sport, | ||
266 | __be32 daddr, __be16 dport, int dif) | 271 | __be32 daddr, __be16 dport, int dif) |
267 | { | 272 | { |
268 | return __inet_lookup_listener(net, hashinfo, daddr, ntohs(dport), dif); | 273 | return __inet_lookup_listener(net, hashinfo, saddr, sport, |
274 | daddr, ntohs(dport), dif); | ||
269 | } | 275 | } |
270 | 276 | ||
271 | /* Socket demux engine toys. */ | 277 | /* Socket demux engine toys. */ |
@@ -358,7 +364,8 @@ static inline struct sock *__inet_lookup(struct net *net, | |||
358 | struct sock *sk = __inet_lookup_established(net, hashinfo, | 364 | struct sock *sk = __inet_lookup_established(net, hashinfo, |
359 | saddr, sport, daddr, hnum, dif); | 365 | saddr, sport, daddr, hnum, dif); |
360 | 366 | ||
361 | return sk ? : __inet_lookup_listener(net, hashinfo, daddr, hnum, dif); | 367 | return sk ? : __inet_lookup_listener(net, hashinfo, saddr, sport, |
368 | daddr, hnum, dif); | ||
362 | } | 369 | } |
363 | 370 | ||
364 | static inline struct sock *inet_lookup(struct net *net, | 371 | static inline struct sock *inet_lookup(struct net *net, |