Commit 34498825cb9062192b77fa02dae672a4fe6eec70

Authored by Patrick McHardy
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
... ... @@ -273,7 +273,7 @@
273 273 }
274 274  
275 275 /* node numbers are 1..n, not 0..n */
276   - return (hashval % config->num_total_nodes) + 1;
  276 + return (((u64)hashval * config->num_total_nodes) >> 32) + 1;
277 277 }
278 278  
279 279 static inline int
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 *