From: Heinz Mauelshagen Instead of using a fixed prime for the region hash buckets, select one from a sequence of primes, each one roughly twice the last one and mid-way between each pair of powers of 2. [Hoping for some real-world evidence this improves performance - AGK] Signed-off-by: Heinz Mauelshagen Signed-off-by: agk@redhat.com --- drivers/md/dm-region-hash.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) Index: linux-2.6.30/drivers/md/dm-region-hash.c =================================================================== --- linux-2.6.30.orig/drivers/md/dm-region-hash.c +++ linux-2.6.30/drivers/md/dm-region-hash.c @@ -148,11 +148,16 @@ sector_t dm_rh_get_region_size(struct dm EXPORT_SYMBOL_GPL(dm_rh_get_region_size); /* + * Table of primes for rh_hash/table size optimization. + */ +static const unsigned dm_region_hash_primes[] = { + 3, 7, 13, 27, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593, +}; + +/* * FIXME: shall we pass in a structure instead of all these args to * dm_region_hash_create()???? - */ -#define RH_HASH_MULT 2654435387U -#define RH_HASH_SHIFT 12 +*/ #define MIN_REGIONS 64 struct dm_region_hash *dm_region_hash_create( @@ -196,8 +201,12 @@ struct dm_region_hash *dm_region_hash_cr rh->mask = nr_buckets - 1; rh->nr_buckets = nr_buckets; - rh->shift = RH_HASH_SHIFT; - rh->prime = RH_HASH_MULT; + rh->shift = ffs(nr_buckets); + if (rh->shift - 1 > ARRAY_SIZE(dm_region_hash_primes)) + i = ARRAY_SIZE(dm_region_hash_primes); + else + i = rh->shift - 1; + rh->prime = dm_region_hash_primes[i - 1]; rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets)); if (!rh->buckets) {