aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/inet6_hashtables.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda@ilport.com.ua>2006-04-10 01:48:59 -0400
committerDavid S. Miller <davem@davemloft.net>2006-04-10 01:48:59 -0400
commitb1a7ffcb7a047e99ab02424e651e0492f36095f7 (patch)
treece84ddd2087b512ae484d6c6d21f985ef2e32a09 /net/ipv6/inet6_hashtables.c
parent55c0022e53452360064ea264c41410c70565d9f8 (diff)
[IPV6]: Deinline few large functions in inet6 code
Deinline a few functions which produce 200+ bytes of code. Size Uses Wasted Name and definition ===== ==== ====== ================================================ 429 3 818 __inet6_lookup include/net/inet6_hashtables.h 404 2 384 __inet6_lookup_established include/net/inet6_hashtables.h 206 3 372 __inet6_hash include/net/inet6_hashtables.h Signed-off-by: Denis Vlasenko <vda@ilport.com.ua> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/inet6_hashtables.c')
-rw-r--r--net/ipv6/inet6_hashtables.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index bb8ffb8a14c5..2ae84c961678 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -23,6 +23,86 @@
23#include <net/inet6_hashtables.h> 23#include <net/inet6_hashtables.h>
24#include <net/ip.h> 24#include <net/ip.h>
25 25
26void __inet6_hash(struct inet_hashinfo *hashinfo,
27 struct sock *sk)
28{
29 struct hlist_head *list;
30 rwlock_t *lock;
31
32 BUG_TRAP(sk_unhashed(sk));
33
34 if (sk->sk_state == TCP_LISTEN) {
35 list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)];
36 lock = &hashinfo->lhash_lock;
37 inet_listen_wlock(hashinfo);
38 } else {
39 unsigned int hash;
40 sk->sk_hash = hash = inet6_sk_ehashfn(sk);
41 hash &= (hashinfo->ehash_size - 1);
42 list = &hashinfo->ehash[hash].chain;
43 lock = &hashinfo->ehash[hash].lock;
44 write_lock(lock);
45 }
46
47 __sk_add_node(sk, list);
48 sock_prot_inc_use(sk->sk_prot);
49 write_unlock(lock);
50}
51EXPORT_SYMBOL(__inet6_hash);
52
53/*
54 * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
55 * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
56 *
57 * The sockhash lock must be held as a reader here.
58 */
59struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
60 const struct in6_addr *saddr,
61 const u16 sport,
62 const struct in6_addr *daddr,
63 const u16 hnum,
64 const int dif)
65{
66 struct sock *sk;
67 const struct hlist_node *node;
68 const __u32 ports = INET_COMBINED_PORTS(sport, hnum);
69 /* Optimize here for direct hit, only listening connections can
70 * have wildcards anyways.
71 */
72 unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport);
73 struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash);
74
75 prefetch(head->chain.first);
76 read_lock(&head->lock);
77 sk_for_each(sk, node, &head->chain) {
78 /* For IPV6 do the cheaper port and family tests first. */
79 if (INET6_MATCH(sk, hash, saddr, daddr, ports, dif))
80 goto hit; /* You sunk my battleship! */
81 }
82 /* Must check for a TIME_WAIT'er before going to listener hash. */
83 sk_for_each(sk, node, &(head + hashinfo->ehash_size)->chain) {
84 const struct inet_timewait_sock *tw = inet_twsk(sk);
85
86 if(*((__u32 *)&(tw->tw_dport)) == ports &&
87 sk->sk_family == PF_INET6) {
88 const struct inet6_timewait_sock *tw6 = inet6_twsk(sk);
89
90 if (ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
91 ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
92 (!sk->sk_bound_dev_if || sk->sk_bound_dev_if == dif))
93 goto hit;
94 }
95 }
96 read_unlock(&head->lock);
97 return NULL;
98
99hit:
100 sock_hold(sk);
101 read_unlock(&head->lock);
102 return sk;
103}
104EXPORT_SYMBOL(__inet6_lookup_established);
105
26struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, 106struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
27 const struct in6_addr *daddr, 107 const struct in6_addr *daddr,
28 const unsigned short hnum, const int dif) 108 const unsigned short hnum, const int dif)