aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-11-09 00:26:33 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-10 23:54:38 -0500
commit30fff9231fad757c061285e347b33c5149c2c2e4 (patch)
tree79d07aba4b8de4367090442292e412d1ccf961ef /net/ipv6
parent0ab365f463b9c5c8b76476a1808dfde1c38f6f19 (diff)
udp: bind() optimisation
UDP bind() can be O(N^2) in some pathological cases. Thanks to secondary hash tables, we can make it O(N) Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/udp.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 2915e1dad726..f4c85b200051 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -100,12 +100,14 @@ static unsigned int udp6_portaddr_hash(struct net *net,
100 100
101int udp_v6_get_port(struct sock *sk, unsigned short snum) 101int udp_v6_get_port(struct sock *sk, unsigned short snum)
102{ 102{
103 unsigned int hash2_nulladdr =
104 udp6_portaddr_hash(sock_net(sk), &in6addr_any, snum);
105 unsigned int hash2_partial =
106 udp6_portaddr_hash(sock_net(sk), &inet6_sk(sk)->rcv_saddr, 0);
107
103 /* precompute partial secondary hash */ 108 /* precompute partial secondary hash */
104 udp_sk(sk)->udp_portaddr_hash = 109 udp_sk(sk)->udp_portaddr_hash = hash2_partial;
105 udp6_portaddr_hash(sock_net(sk), 110 return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal, hash2_nulladdr);
106 &inet6_sk(sk)->rcv_saddr,
107 0);
108 return udp_lib_get_port(sk, snum, ipv6_rcv_saddr_equal);
109} 111}
110 112
111static inline int compute_score(struct sock *sk, struct net *net, 113static inline int compute_score(struct sock *sk, struct net *net,
@@ -181,8 +183,6 @@ static inline int compute_score2(struct sock *sk, struct net *net,
181 return score; 183 return score;
182} 184}
183 185
184#define udp_portaddr_for_each_entry_rcu(__sk, node, list) \
185 hlist_nulls_for_each_entry_rcu(__sk, node, list, __sk_common.skc_portaddr_node)
186 186
187/* called with read_rcu_lock() */ 187/* called with read_rcu_lock() */
188static struct sock *udp6_lib_lookup2(struct net *net, 188static struct sock *udp6_lib_lookup2(struct net *net,