Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Eric Dumazet and committed by
David S. Miller
40384999 47061bc4

+18 -21
+18 -21
net/ipv4/devinet.c
··· 94 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 98 - * value. So if you change this define, make appropriate changes to 99 - * inet_addr_hash as well. 100 - */ 101 - #define IN4_ADDR_HSIZE 256 97 + #define IN4_ADDR_HSIZE_SHIFT 8 98 + #define IN4_ADDR_HSIZE (1U << IN4_ADDR_HSIZE_SHIFT) 99 + 102 100 static struct hlist_head inet_addr_lst[IN4_ADDR_HSIZE]; 103 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)) & 110 - (IN4_ADDR_HSIZE - 1)); 107 + return hash_32(val, IN4_ADDR_HSIZE_SHIFT); 111 108 } 112 109 113 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 114 spin_lock(&inet_addr_hash_lock); 118 115 hlist_add_head_rcu(&ifa->hash, &inet_addr_lst[hash]); ··· 133 136 */ 134 137 struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) 135 138 { 136 - unsigned int hash = inet_addr_hash(net, addr); 139 + u32 hash = inet_addr_hash(net, addr); 137 140 struct net_device *result = NULL; 138 141 struct in_ifaddr *ifa; 139 142 struct hlist_node *node; 140 143 141 144 rcu_read_lock(); 142 145 hlist_for_each_entry_rcu(ifa, node, &inet_addr_lst[hash], hash) { 143 - struct net_device *dev = ifa->ifa_dev->dev; 144 - 145 - if (!net_eq(dev_net(dev), net)) 146 - continue; 147 146 if (ifa->ifa_local == addr) { 147 + struct net_device *dev = ifa->ifa_dev->dev; 148 + 149 + if (!net_eq(dev_net(dev), net)) 150 + continue; 148 151 result = dev; 149 152 break; 150 153 } ··· 179 182 static void devinet_sysctl_register(struct in_device *idev); 180 183 static void devinet_sysctl_unregister(struct in_device *idev); 181 184 #else 182 - static inline void devinet_sysctl_register(struct in_device *idev) 185 + static void devinet_sysctl_register(struct in_device *idev) 183 186 { 184 187 } 185 - static inline void devinet_sysctl_unregister(struct in_device *idev) 188 + static void devinet_sysctl_unregister(struct in_device *idev) 186 189 { 187 190 } 188 191 #endif ··· 202 205 kfree(ifa); 203 206 } 204 207 205 - static inline void inet_free_ifa(struct in_ifaddr *ifa) 208 + static void inet_free_ifa(struct in_ifaddr *ifa) 206 209 { 207 210 call_rcu(&ifa->rcu_head, inet_rcu_free_ifa); 208 211 } ··· 656 659 * Determine a default network mask, based on the IP address. 657 660 */ 658 661 659 - static inline int inet_abc_len(__be32 addr) 662 + static int inet_abc_len(__be32 addr) 660 663 { 661 664 int rc = -1; /* Something else, probably a multicast. */ 662 665 ··· 1121 1124 } 1122 1125 } 1123 1126 1124 - static inline bool inetdev_valid_mtu(unsigned int mtu) 1127 + static bool inetdev_valid_mtu(unsigned int mtu) 1125 1128 { 1126 1129 return mtu >= 68; 1127 1130 } ··· 1236 1239 .notifier_call = inetdev_event, 1237 1240 }; 1238 1241 1239 - static inline size_t inet_nlmsg_size(void) 1242 + static size_t inet_nlmsg_size(void) 1240 1243 { 1241 1244 return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) 1242 1245 + nla_total_size(4) /* IFA_ADDRESS */