diff options
Diffstat (limited to 'lib/rhashtable.c')
| -rw-r--r-- | lib/rhashtable.c | 27 | 
1 files changed, 19 insertions, 8 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 9427b5766134..e5c8586cf717 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -774,7 +774,7 @@ int rhashtable_walk_start_check(struct rhashtable_iter *iter)  				skip++;  				if (list == iter->list) {  					iter->p = p; -					skip = skip; +					iter->skip = skip;  					goto found;  				}  			} @@ -964,8 +964,16 @@ EXPORT_SYMBOL_GPL(rhashtable_walk_stop);  static size_t rounded_hashtable_size(const struct rhashtable_params *params)  { -	return max(roundup_pow_of_two(params->nelem_hint * 4 / 3), -		   (unsigned long)params->min_size); +	size_t retsize; + +	if (params->nelem_hint) +		retsize = max(roundup_pow_of_two(params->nelem_hint * 4 / 3), +			      (unsigned long)params->min_size); +	else +		retsize = max(HASH_DEFAULT_SIZE, +			      (unsigned long)params->min_size); + +	return retsize;  }  static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) @@ -1022,8 +1030,6 @@ int rhashtable_init(struct rhashtable *ht,  	struct bucket_table *tbl;  	size_t size; -	size = HASH_DEFAULT_SIZE; -  	if ((!params->key_len && !params->obj_hashfn) ||  	    (params->obj_hashfn && !params->obj_cmpfn))  		return -EINVAL; @@ -1050,8 +1056,7 @@ int rhashtable_init(struct rhashtable *ht,  	ht->p.min_size = max_t(u16, ht->p.min_size, HASH_MIN_SIZE); -	if (params->nelem_hint) -		size = rounded_hashtable_size(&ht->p); +	size = rounded_hashtable_size(&ht->p);  	if (params->locks_mul)  		ht->p.locks_mul = roundup_pow_of_two(params->locks_mul); @@ -1143,13 +1148,14 @@ void rhashtable_free_and_destroy(struct rhashtable *ht,  				 void (*free_fn)(void *ptr, void *arg),  				 void *arg)  { -	struct bucket_table *tbl; +	struct bucket_table *tbl, *next_tbl;  	unsigned int i;  	cancel_work_sync(&ht->run_work);  	mutex_lock(&ht->mutex);  	tbl = rht_dereference(ht->tbl, ht); +restart:  	if (free_fn) {  		for (i = 0; i < tbl->size; i++) {  			struct rhash_head *pos, *next; @@ -1166,7 +1172,12 @@ void rhashtable_free_and_destroy(struct rhashtable *ht,  		}  	} +	next_tbl = rht_dereference(tbl->future_tbl, ht);  	bucket_table_free(tbl); +	if (next_tbl) { +		tbl = next_tbl; +		goto restart; +	}  	mutex_unlock(&ht->mutex);  }  EXPORT_SYMBOL_GPL(rhashtable_free_and_destroy);  | 
