aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2014-09-02 21:22:36 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-03 23:56:32 -0400
commit940001762ac514810e305aab356983829e5fa82a (patch)
tree4f63ce59f54641741fb0c148db9c7e400e0c41a7 /lib
parent1f59533f9ca5634e7b8914252e48aee9d9cbe501 (diff)
lib/rhashtable: allow user to set the minimum shifts of shrinking
Although rhashtable library allows user to specify a quiet big size for user's created hash table, the table may be shrunk to a very small size - HASH_MIN_SIZE(4) after object is removed from the table at the first time. Subsequently, even if the total amount of objects saved in the table is quite lower than user's initial setting in a long time, the hash table size is still dynamically adjusted by rhashtable_shrink() or rhashtable_expand() each time object is inserted or removed from the table. However, as synchronize_rcu() has to be called when table is shrunk or expanded by the two functions, we should permit user to set the minimum table size through configuring the minimum number of shifts according to user specific requirement, avoiding these expensive actions of shrinking or expanding because of calling synchronize_rcu(). Signed-off-by: Ying Xue <ying.xue@windriver.com> Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/rhashtable.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index a2c78810ebc1..8dfec3f26d4c 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -298,7 +298,7 @@ int rhashtable_shrink(struct rhashtable *ht, gfp_t flags)
298 298
299 ASSERT_RHT_MUTEX(ht); 299 ASSERT_RHT_MUTEX(ht);
300 300
301 if (tbl->size <= HASH_MIN_SIZE) 301 if (ht->shift <= ht->p.min_shift)
302 return 0; 302 return 0;
303 303
304 ntbl = bucket_table_alloc(tbl->size / 2, flags); 304 ntbl = bucket_table_alloc(tbl->size / 2, flags);
@@ -506,9 +506,10 @@ void *rhashtable_lookup_compare(const struct rhashtable *ht, u32 hash,
506} 506}
507EXPORT_SYMBOL_GPL(rhashtable_lookup_compare); 507EXPORT_SYMBOL_GPL(rhashtable_lookup_compare);
508 508
509static size_t rounded_hashtable_size(unsigned int nelem) 509static size_t rounded_hashtable_size(struct rhashtable_params *params)
510{ 510{
511 return max(roundup_pow_of_two(nelem * 4 / 3), HASH_MIN_SIZE); 511 return max(roundup_pow_of_two(params->nelem_hint * 4 / 3),
512 1UL << params->min_shift);
512} 513}
513 514
514/** 515/**
@@ -566,8 +567,11 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
566 (!params->key_len && !params->obj_hashfn)) 567 (!params->key_len && !params->obj_hashfn))
567 return -EINVAL; 568 return -EINVAL;
568 569
570 params->min_shift = max_t(size_t, params->min_shift,
571 ilog2(HASH_MIN_SIZE));
572
569 if (params->nelem_hint) 573 if (params->nelem_hint)
570 size = rounded_hashtable_size(params->nelem_hint); 574 size = rounded_hashtable_size(params);
571 575
572 tbl = bucket_table_alloc(size, GFP_KERNEL); 576 tbl = bucket_table_alloc(size, GFP_KERNEL);
573 if (tbl == NULL) 577 if (tbl == NULL)