aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-08-03 17:06:50 -0400
committerDavid S. Miller <davem@davemloft.net>2012-08-04 04:27:57 -0400
commit40384999d142552b81aeb596c2ae663dd3ff60ce (patch)
tree9ddb875415646dfc0a4362849f3177d404966df3 /net/ipv4/devinet.c
parent47061bc440b90a16d856fb0dba1cffc36427efa4 (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.c39
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
102static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE]; 100static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE];
103static DEFINE_SPINLOCK(inet_addr_hash_lock); 101static DEFINE_SPINLOCK(inet_addr_hash_lock);
104 102
105static inline unsigned int inet_addr_hash(struct net *net, __be32 addr) 103static 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
113static void inet_hash_insert(struct net *net, struct in_ifaddr *ifa) 110static 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 */
137struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) 134struct 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,
182static void devinet_sysctl_register(struct in_device *idev); 179static void devinet_sysctl_register(struct in_device *idev);
183static void devinet_sysctl_unregister(struct in_device *idev); 180static void devinet_sysctl_unregister(struct in_device *idev);
184#else 181#else
185static inline void devinet_sysctl_register(struct in_device *idev) 182static void devinet_sysctl_register(struct in_device *idev)
186{ 183{
187} 184}
188static inline void devinet_sysctl_unregister(struct in_device *idev) 185static 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
208static inline void inet_free_ifa(struct in_ifaddr *ifa) 205static 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
662static inline int inet_abc_len(__be32 addr) 659static 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
1127static inline bool inetdev_valid_mtu(unsigned int mtu) 1124static 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
1242static inline size_t inet_nlmsg_size(void) 1239static 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 */