diff options
author | Eric Dumazet <edumazet@google.com> | 2012-08-03 17:06:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-04 04:27:57 -0400 |
commit | 40384999d142552b81aeb596c2ae663dd3ff60ce (patch) | |
tree | 9ddb875415646dfc0a4362849f3177d404966df3 /net/ipv4/devinet.c | |
parent | 47061bc440b90a16d856fb0dba1cffc36427efa4 (diff) |
ipv4: change inet_addr_hash()
Use net_hash_mix(net) instead of hash_ptr(net, 8), and use
hash_32() instead of using a serie of XOR
Define IN4_ADDR_HSIZE_SHIFT for clarity
__ip_dev_find() can perform the net_eq() call only if ifa_local
matches the key, to avoid unneeded dereferences.
remove inline attributes
# size net/ipv4/devinet.o.before net/ipv4/devinet.o
text data bss dec hex filename
17471 2545 2048 22064 5630 net/ipv4/devinet.o.before
17335 2545 2048 21928 55a8 net/ipv4/devinet.o
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r-- | net/ipv4/devinet.c | 39 |
1 files changed, 18 insertions, 21 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 44bf82e3aef7..adf273f8ad2e 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -94,25 +94,22 @@ static const struct nla_policy ifa_ipv4_policy[IFA_MAX+1] = { | |||
94 | [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, | 94 | [IFA_LABEL] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, |
95 | }; | 95 | }; |
96 | 96 | ||
97 | /* inet_addr_hash's shifting is dependent upon this IN4_ADDR_HSIZE | 97 | #define IN4_ADDR_HSIZE_SHIFT 8 |
98 | * value. So if you change this define, make appropriate changes to | 98 | #define IN4_ADDR_HSIZE (1U << IN4_ADDR_HSIZE_SHIFT) |
99 | * inet_addr_hash as well. | 99 | |
100 | */ | ||
101 | #define IN4_ADDR_HSIZE 256 | ||
102 | static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE]; | 100 | static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE]; |
103 | static DEFINE_SPINLOCK(inet_addr_hash_lock); | 101 | static DEFINE_SPINLOCK(inet_addr_hash_lock); |
104 | 102 | ||
105 | static inline unsigned int inet_addr_hash(struct net *net, __be32 addr) | 103 | static u32 inet_addr_hash(struct net *net, __be32 addr) |
106 | { | 104 | { |
107 | u32 val = (__force u32) addr ^ hash_ptr(net, 8); | 105 | u32 val = (__force u32) addr ^ net_hash_mix(net); |
108 | 106 | ||
109 | return ((val ^ (val >> 8) ^ (val >> 16) ^ (val >> 24)) & | 107 | return hash_32(val, IN4_ADDR_HSIZE_SHIFT); |
110 | (IN4_ADDR_HSIZE - 1)); | ||
111 | } | 108 | } |
112 | 109 | ||
113 | static void inet_hash_insert(struct net *net, struct in_ifaddr *ifa) | 110 | static void inet_hash_insert(struct net *net, struct in_ifaddr *ifa) |
114 | { | 111 | { |
115 | unsigned int hash = inet_addr_hash(net, ifa->ifa_local); | 112 | u32 hash = inet_addr_hash(net, ifa->ifa_local); |
116 | 113 | ||
117 | spin_lock(&inet_addr_hash_lock); | 114 | spin_lock(&inet_addr_hash_lock); |
118 | hlist_add_head_rcu(&ifa->hash, &inet_addr_lst[hash]); | 115 | hlist_add_head_rcu(&ifa->hash, &inet_addr_lst[hash]); |
@@ -136,18 +133,18 @@ static void inet_hash_remove(struct in_ifaddr *ifa) | |||
136 | */ | 133 | */ |
137 | struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) | 134 | struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) |
138 | { | 135 | { |
139 | unsigned int hash = inet_addr_hash(net, addr); | 136 | u32 hash = inet_addr_hash(net, addr); |
140 | struct net_device *result = NULL; | 137 | struct net_device *result = NULL; |
141 | struct in_ifaddr *ifa; | 138 | struct in_ifaddr *ifa; |
142 | struct hlist_node *node; | 139 | struct hlist_node *node; |
143 | 140 | ||
144 | rcu_read_lock(); | 141 | rcu_read_lock(); |
145 | hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) { | 142 | hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) { |
146 | struct net_device *dev = ifa->ifa_dev->dev; | ||
147 | |||
148 | if (!net_eq(dev_net(dev), net)) | ||
149 | continue; | ||
150 | if (ifa->ifa_local == addr) { | 143 | if (ifa->ifa_local == addr) { |
144 | struct net_device *dev = ifa->ifa_dev->dev; | ||
145 | |||
146 | if (!net_eq(dev_net(dev), net)) | ||
147 | continue; | ||
151 | result = dev; | 148 | result = dev; |
152 | break; | 149 | break; |
153 | } | 150 | } |
@@ -182,10 +179,10 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | |||
182 | static void devinet_sysctl_register(struct in_device *idev); | 179 | static void devinet_sysctl_register(struct in_device *idev); |
183 | static void devinet_sysctl_unregister(struct in_device *idev); | 180 | static void devinet_sysctl_unregister(struct in_device *idev); |
184 | #else | 181 | #else |
185 | static inline void devinet_sysctl_register(struct in_device *idev) | 182 | static void devinet_sysctl_register(struct in_device *idev) |
186 | { | 183 | { |
187 | } | 184 | } |
188 | static inline void devinet_sysctl_unregister(struct in_device *idev) | 185 | static void devinet_sysctl_unregister(struct in_device *idev) |
189 | { | 186 | { |
190 | } | 187 | } |
191 | #endif | 188 | #endif |
@@ -205,7 +202,7 @@ static void inet_rcu_free_ifa(struct rcu_head *head) | |||
205 | kfree(ifa); | 202 | kfree(ifa); |
206 | } | 203 | } |
207 | 204 | ||
208 | static inline void inet_free_ifa(struct in_ifaddr *ifa) | 205 | static void inet_free_ifa(struct in_ifaddr *ifa) |
209 | { | 206 | { |
210 | call_rcu(&ifa->rcu_head, inet_rcu_free_ifa); | 207 | call_rcu(&ifa->rcu_head, inet_rcu_free_ifa); |
211 | } | 208 | } |
@@ -659,7 +656,7 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg | |||
659 | * Determine a default network mask, based on the IP address. | 656 | * Determine a default network mask, based on the IP address. |
660 | */ | 657 | */ |
661 | 658 | ||
662 | static inline int inet_abc_len(__be32 addr) | 659 | static int inet_abc_len(__be32 addr) |
663 | { | 660 | { |
664 | int rc = -1; /* Something else, probably a multicast. */ | 661 | int rc = -1; /* Something else, probably a multicast. */ |
665 | 662 | ||
@@ -1124,7 +1121,7 @@ skip: | |||
1124 | } | 1121 | } |
1125 | } | 1122 | } |
1126 | 1123 | ||
1127 | static inline bool inetdev_valid_mtu(unsigned int mtu) | 1124 | static bool inetdev_valid_mtu(unsigned int mtu) |
1128 | { | 1125 | { |
1129 | return mtu >= 68; | 1126 | return mtu >= 68; |
1130 | } | 1127 | } |
@@ -1239,7 +1236,7 @@ static struct notifier_block ip_netdev_notifier = { | |||
1239 | .notifier_call = inetdev_event, | 1236 | .notifier_call = inetdev_event, |
1240 | }; | 1237 | }; |
1241 | 1238 | ||
1242 | static inline size_t inet_nlmsg_size(void) | 1239 | static size_t inet_nlmsg_size(void) |
1243 | { | 1240 | { |
1244 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) | 1241 | return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) |
1245 | + nla_total_size(4) /* IFA_ADDRESS */ | 1242 | + nla_total_size(4) /* IFA_ADDRESS */ |