[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>
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index aec157d..e53ae1e 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -77,10 +77,13 @@
static inline unsigned int
hash_by_src(const struct nf_conntrack_tuple *tuple)
{
+ unsigned int hash;
+
/* Original src, to ensure we map it consistently if poss. */
- return jhash_3words((__force u32)tuple->src.u3.ip,
+ hash = jhash_3words((__force u32)tuple->src.u3.ip,
(__force u32)tuple->src.u.all,
- tuple->dst.protonum, 0) % nf_nat_htable_size;
+ tuple->dst.protonum, 0);
+ return ((u64)hash * nf_nat_htable_size) >> 32;
}
/* Is this tuple already taken? (not by us) */
@@ -211,7 +214,8 @@
maxip = ntohl(range->max_ip);
j = jhash_2words((__force u32)tuple->src.u3.ip,
(__force u32)tuple->dst.u3.ip, 0);
- *var_ipp = htonl(minip + j % (maxip - minip + 1));
+ j = ((u64)j * (maxip - minip + 1)) >> 32;
+ *var_ipp = htonl(minip + j);
}
/* Manipulate the tuple into the range given. For NF_INET_POST_ROUTING,