Commit 34498825cb9062192b77fa02dae672a4fe6eec70
Committed by
David S. Miller
1 parent
7b21e09d1c
[NETFILTER]: non-power-of-two jhash optimizations
Apply Eric Dumazet's jhash optimizations where applicable. Quoting Eric: Thanks to jhash, hash value uses full 32 bits. Instead of returning hash % size (implying a divide) we return the high 32 bits of the (hash * size) that will give results between [0 and size-1] and same hash distribution. On most cpus, a multiply is less expensive than a divide, by an order of magnitude. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 4 changed files with 14 additions and 8 deletions Side-by-side Diff
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/nf_nat_core.c
... | ... | @@ -77,10 +77,13 @@ |
77 | 77 | static inline unsigned int |
78 | 78 | hash_by_src(const struct nf_conntrack_tuple *tuple) |
79 | 79 | { |
80 | + unsigned int hash; | |
81 | + | |
80 | 82 | /* Original src, to ensure we map it consistently if poss. */ |
81 | - return jhash_3words((__force u32)tuple->src.u3.ip, | |
83 | + hash = jhash_3words((__force u32)tuple->src.u3.ip, | |
82 | 84 | (__force u32)tuple->src.u.all, |
83 | - tuple->dst.protonum, 0) % nf_nat_htable_size; | |
85 | + tuple->dst.protonum, 0); | |
86 | + return ((u64)hash * nf_nat_htable_size) >> 32; | |
84 | 87 | } |
85 | 88 | |
86 | 89 | /* Is this tuple already taken? (not by us) */ |
... | ... | @@ -211,7 +214,8 @@ |
211 | 214 | maxip = ntohl(range->max_ip); |
212 | 215 | j = jhash_2words((__force u32)tuple->src.u3.ip, |
213 | 216 | (__force u32)tuple->dst.u3.ip, 0); |
214 | - *var_ipp = htonl(minip + j % (maxip - minip + 1)); | |
217 | + j = ((u64)j * (maxip - minip + 1)) >> 32; | |
218 | + *var_ipp = htonl(minip + j); | |
215 | 219 | } |
216 | 220 | |
217 | 221 | /* Manipulate the tuple into the range given. For NF_INET_POST_ROUTING, |
net/netfilter/nf_conntrack_core.c
... | ... | @@ -81,7 +81,7 @@ |
81 | 81 | ((__force __u16)tuple->src.u.all << 16) | |
82 | 82 | (__force __u16)tuple->dst.u.all); |
83 | 83 | |
84 | - return jhash_2words(a, b, rnd) % size; | |
84 | + return ((u64)jhash_2words(a, b, rnd) * size) >> 32; | |
85 | 85 | } |
86 | 86 | |
87 | 87 | static inline u_int32_t hash_conntrack(const struct nf_conntrack_tuple *tuple) |
net/netfilter/nf_conntrack_expect.c
... | ... | @@ -73,15 +73,17 @@ |
73 | 73 | |
74 | 74 | static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple) |
75 | 75 | { |
76 | + unsigned int hash; | |
77 | + | |
76 | 78 | if (unlikely(!nf_ct_expect_hash_rnd_initted)) { |
77 | 79 | get_random_bytes(&nf_ct_expect_hash_rnd, 4); |
78 | 80 | nf_ct_expect_hash_rnd_initted = 1; |
79 | 81 | } |
80 | 82 | |
81 | - return jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all), | |
83 | + hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all), | |
82 | 84 | (((tuple->dst.protonum ^ tuple->src.l3num) << 16) | |
83 | - (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd) % | |
84 | - nf_ct_expect_hsize; | |
85 | + (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd); | |
86 | + return ((u64)hash * nf_ct_expect_hsize) >> 32; | |
85 | 87 | } |
86 | 88 | |
87 | 89 | struct nf_conntrack_expect * |