aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rhashtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rhashtable.c')
-rw-r--r--lib/rhashtable.c506
1 files changed, 174 insertions, 332 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index ba15dceee27f..b1c19c5fb326 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -66,9 +66,9 @@ static u32 rht_bucket_index(const struct bucket_table *tbl, u32 hash)
66 return hash & (tbl->size - 1); 66 return hash & (tbl->size - 1);
67} 67}
68 68
69static u32 obj_raw_hashfn(struct rhashtable *ht, const void *ptr) 69static u32 obj_raw_hashfn(struct rhashtable *ht,
70 const struct bucket_table *tbl, const void *ptr)
70{ 71{
71 struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
72 u32 hash; 72 u32 hash;
73 73
74 if (unlikely(!ht->p.key_len)) 74 if (unlikely(!ht->p.key_len))
@@ -80,10 +80,9 @@ static u32 obj_raw_hashfn(struct rhashtable *ht, const void *ptr)
80 return hash >> HASH_RESERVED_SPACE; 80 return hash >> HASH_RESERVED_SPACE;
81} 81}
82 82
83static u32 key_hashfn(struct rhashtable *ht, const void *key, u32 len) 83static u32 key_hashfn(struct rhashtable *ht, const struct bucket_table *tbl,
84 const void *key, u32 len)
84{ 85{
85 struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
86
87 return ht->p.hashfn(key, len, tbl->hash_rnd) >> HASH_RESERVED_SPACE; 86 return ht->p.hashfn(key, len, tbl->hash_rnd) >> HASH_RESERVED_SPACE;
88} 87}
89 88
@@ -91,60 +90,11 @@ static u32 head_hashfn(struct rhashtable *ht,
91 const struct bucket_table *tbl, 90 const struct bucket_table *tbl,
92 const struct rhash_head *he) 91 const struct rhash_head *he)
93{ 92{
94 return rht_bucket_index(tbl, obj_raw_hashfn(ht, rht_obj(ht, he))); 93 return rht_bucket_index(tbl, obj_raw_hashfn(ht, tbl, rht_obj(ht, he)));
95} 94}
96 95
97#ifdef CONFIG_PROVE_LOCKING 96#ifdef CONFIG_PROVE_LOCKING
98static void debug_dump_buckets(struct rhashtable *ht,
99 const struct bucket_table *tbl)
100{
101 struct rhash_head *he;
102 unsigned int i, hash;
103
104 for (i = 0; i < tbl->size; i++) {
105 pr_warn(" [Bucket %d] ", i);
106 rht_for_each_rcu(he, tbl, i) {
107 hash = head_hashfn(ht, tbl, he);
108 pr_cont("[hash = %#x, lock = %p] ",
109 hash, bucket_lock(tbl, hash));
110 }
111 pr_cont("\n");
112 }
113
114}
115
116static void debug_dump_table(struct rhashtable *ht,
117 const struct bucket_table *tbl,
118 unsigned int hash)
119{
120 struct bucket_table *old_tbl, *future_tbl;
121
122 pr_emerg("BUG: lock for hash %#x in table %p not held\n",
123 hash, tbl);
124
125 rcu_read_lock();
126 future_tbl = rht_dereference_rcu(ht->future_tbl, ht);
127 old_tbl = rht_dereference_rcu(ht->tbl, ht);
128 if (future_tbl != old_tbl) {
129 pr_warn("Future table %p (size: %zd)\n",
130 future_tbl, future_tbl->size);
131 debug_dump_buckets(ht, future_tbl);
132 }
133
134 pr_warn("Table %p (size: %zd)\n", old_tbl, old_tbl->size);
135 debug_dump_buckets(ht, old_tbl);
136
137 rcu_read_unlock();
138}
139
140#define ASSERT_RHT_MUTEX(HT) BUG_ON(!lockdep_rht_mutex_is_held(HT)) 97#define ASSERT_RHT_MUTEX(HT) BUG_ON(!lockdep_rht_mutex_is_held(HT))
141#define ASSERT_BUCKET_LOCK(HT, TBL, HASH) \
142 do { \
143 if (unlikely(!lockdep_rht_bucket_is_held(TBL, HASH))) { \
144 debug_dump_table(HT, TBL, HASH); \
145 BUG(); \
146 } \
147 } while (0)
148 98
149int lockdep_rht_mutex_is_held(struct rhashtable *ht) 99int lockdep_rht_mutex_is_held(struct rhashtable *ht)
150{ 100{
@@ -161,22 +111,9 @@ int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash)
161EXPORT_SYMBOL_GPL(lockdep_rht_bucket_is_held); 111EXPORT_SYMBOL_GPL(lockdep_rht_bucket_is_held);
162#else 112#else
163#define ASSERT_RHT_MUTEX(HT) 113#define ASSERT_RHT_MUTEX(HT)
164#define ASSERT_BUCKET_LOCK(HT, TBL, HASH)
165#endif 114#endif
166 115
167 116
168static struct rhash_head __rcu **bucket_tail(struct bucket_table *tbl, u32 n)
169{
170 struct rhash_head __rcu **pprev;
171
172 for (pprev = &tbl->buckets[n];
173 !rht_is_a_nulls(rht_dereference_bucket(*pprev, tbl, n));
174 pprev = &rht_dereference_bucket(*pprev, tbl, n)->next)
175 ;
176
177 return pprev;
178}
179
180static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl) 117static int alloc_bucket_locks(struct rhashtable *ht, struct bucket_table *tbl)
181{ 118{
182 unsigned int i, size; 119 unsigned int i, size;
@@ -270,101 +207,99 @@ static bool rht_shrink_below_30(const struct rhashtable *ht, size_t new_size)
270 (atomic_read(&ht->shift) > ht->p.min_shift); 207 (atomic_read(&ht->shift) > ht->p.min_shift);
271} 208}
272 209
273static void lock_buckets(struct bucket_table *new_tbl, 210static int rhashtable_rehash_one(struct rhashtable *ht, unsigned old_hash)
274 struct bucket_table *old_tbl, unsigned int hash)
275 __acquires(old_bucket_lock)
276{ 211{
277 spin_lock_bh(bucket_lock(old_tbl, hash)); 212 struct bucket_table *new_tbl = rht_dereference(ht->future_tbl, ht);
278 if (new_tbl != old_tbl) 213 struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
279 spin_lock_bh_nested(bucket_lock(new_tbl, hash), 214 struct rhash_head __rcu **pprev = &old_tbl->buckets[old_hash];
280 RHT_LOCK_NESTED); 215 int err = -ENOENT;
281} 216 struct rhash_head *head, *next, *entry;
217 spinlock_t *new_bucket_lock;
218 unsigned new_hash;
282 219
283static void unlock_buckets(struct bucket_table *new_tbl, 220 rht_for_each(entry, old_tbl, old_hash) {
284 struct bucket_table *old_tbl, unsigned int hash) 221 err = 0;
285 __releases(old_bucket_lock) 222 next = rht_dereference_bucket(entry->next, old_tbl, old_hash);
286{
287 if (new_tbl != old_tbl)
288 spin_unlock_bh(bucket_lock(new_tbl, hash));
289 spin_unlock_bh(bucket_lock(old_tbl, hash));
290}
291 223
292/** 224 if (rht_is_a_nulls(next))
293 * Unlink entries on bucket which hash to different bucket. 225 break;
294 *
295 * Returns true if no more work needs to be performed on the bucket.
296 */
297static bool hashtable_chain_unzip(struct rhashtable *ht,
298 const struct bucket_table *new_tbl,
299 struct bucket_table *old_tbl,
300 size_t old_hash)
301{
302 struct rhash_head *he, *p, *next;
303 unsigned int new_hash, new_hash2;
304 226
305 ASSERT_BUCKET_LOCK(ht, old_tbl, old_hash); 227 pprev = &entry->next;
228 }
306 229
307 /* Old bucket empty, no work needed. */ 230 if (err)
308 p = rht_dereference_bucket(old_tbl->buckets[old_hash], old_tbl, 231 goto out;
309 old_hash);
310 if (rht_is_a_nulls(p))
311 return false;
312 232
313 new_hash = head_hashfn(ht, new_tbl, p); 233 new_hash = head_hashfn(ht, new_tbl, entry);
314 ASSERT_BUCKET_LOCK(ht, new_tbl, new_hash);
315 234
316 /* Advance the old bucket pointer one or more times until it 235 new_bucket_lock = bucket_lock(new_tbl, new_hash);
317 * reaches a node that doesn't hash to the same bucket as the
318 * previous node p. Call the previous node p;
319 */
320 rht_for_each_continue(he, p->next, old_tbl, old_hash) {
321 new_hash2 = head_hashfn(ht, new_tbl, he);
322 ASSERT_BUCKET_LOCK(ht, new_tbl, new_hash2);
323 236
324 if (new_hash != new_hash2) 237 spin_lock(new_bucket_lock);
325 break; 238 head = rht_dereference_bucket(new_tbl->buckets[new_hash],
326 p = he; 239 new_tbl, new_hash);
327 }
328 rcu_assign_pointer(old_tbl->buckets[old_hash], p->next);
329 240
330 /* Find the subsequent node which does hash to the same 241 if (rht_is_a_nulls(head))
331 * bucket as node P, or NULL if no such node exists. 242 INIT_RHT_NULLS_HEAD(entry->next, ht, new_hash);
332 */ 243 else
333 INIT_RHT_NULLS_HEAD(next, ht, old_hash); 244 RCU_INIT_POINTER(entry->next, head);
334 if (!rht_is_a_nulls(he)) {
335 rht_for_each_continue(he, he->next, old_tbl, old_hash) {
336 if (head_hashfn(ht, new_tbl, he) == new_hash) {
337 next = he;
338 break;
339 }
340 }
341 }
342 245
343 /* Set p's next pointer to that subsequent node pointer, 246 rcu_assign_pointer(new_tbl->buckets[new_hash], entry);
344 * bypassing the nodes which do not hash to p's bucket 247 spin_unlock(new_bucket_lock);
345 */
346 rcu_assign_pointer(p->next, next);
347 248
348 p = rht_dereference_bucket(old_tbl->buckets[old_hash], old_tbl, 249 rcu_assign_pointer(*pprev, next);
349 old_hash);
350 250
351 return !rht_is_a_nulls(p); 251out:
252 return err;
352} 253}
353 254
354static void link_old_to_new(struct rhashtable *ht, struct bucket_table *new_tbl, 255static void rhashtable_rehash_chain(struct rhashtable *ht, unsigned old_hash)
355 unsigned int new_hash, struct rhash_head *entry)
356{ 256{
357 ASSERT_BUCKET_LOCK(ht, new_tbl, new_hash); 257 struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
258 spinlock_t *old_bucket_lock;
259
260 old_bucket_lock = bucket_lock(old_tbl, old_hash);
358 261
359 rcu_assign_pointer(*bucket_tail(new_tbl, new_hash), entry); 262 spin_lock_bh(old_bucket_lock);
263 while (!rhashtable_rehash_one(ht, old_hash))
264 ;
265 spin_unlock_bh(old_bucket_lock);
266}
267
268static void rhashtable_rehash(struct rhashtable *ht,
269 struct bucket_table *new_tbl)
270{
271 struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
272 unsigned old_hash;
273
274 get_random_bytes(&new_tbl->hash_rnd, sizeof(new_tbl->hash_rnd));
275
276 /* Make insertions go into the new, empty table right away. Deletions
277 * and lookups will be attempted in both tables until we synchronize.
278 * The synchronize_rcu() guarantees for the new table to be picked up
279 * so no new additions go into the old table while we relink.
280 */
281 rcu_assign_pointer(ht->future_tbl, new_tbl);
282
283 for (old_hash = 0; old_hash < old_tbl->size; old_hash++)
284 rhashtable_rehash_chain(ht, old_hash);
285
286 /* Publish the new table pointer. */
287 rcu_assign_pointer(ht->tbl, new_tbl);
288
289 /* Wait for readers. All new readers will see the new
290 * table, and thus no references to the old table will
291 * remain.
292 */
293 synchronize_rcu();
294
295 bucket_table_free(old_tbl);
360} 296}
361 297
362/** 298/**
363 * rhashtable_expand - Expand hash table while allowing concurrent lookups 299 * rhashtable_expand - Expand hash table while allowing concurrent lookups
364 * @ht: the hash table to expand 300 * @ht: the hash table to expand
365 * 301 *
366 * A secondary bucket array is allocated and the hash entries are migrated 302 * A secondary bucket array is allocated and the hash entries are migrated.
367 * while keeping them on both lists until the end of the RCU grace period.
368 * 303 *
369 * This function may only be called in a context where it is safe to call 304 * This function may only be called in a context where it is safe to call
370 * synchronize_rcu(), e.g. not within a rcu_read_lock() section. 305 * synchronize_rcu(), e.g. not within a rcu_read_lock() section.
@@ -378,9 +313,6 @@ static void link_old_to_new(struct rhashtable *ht, struct bucket_table *new_tbl,
378int rhashtable_expand(struct rhashtable *ht) 313int rhashtable_expand(struct rhashtable *ht)
379{ 314{
380 struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht); 315 struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht);
381 struct rhash_head *he;
382 unsigned int new_hash, old_hash;
383 bool complete = false;
384 316
385 ASSERT_RHT_MUTEX(ht); 317 ASSERT_RHT_MUTEX(ht);
386 318
@@ -392,64 +324,8 @@ int rhashtable_expand(struct rhashtable *ht)
392 324
393 atomic_inc(&ht->shift); 325 atomic_inc(&ht->shift);
394 326
395 /* Make insertions go into the new, empty table right away. Deletions 327 rhashtable_rehash(ht, new_tbl);
396 * and lookups will be attempted in both tables until we synchronize.
397 * The synchronize_rcu() guarantees for the new table to be picked up
398 * so no new additions go into the old table while we relink.
399 */
400 rcu_assign_pointer(ht->future_tbl, new_tbl);
401 synchronize_rcu();
402 328
403 /* For each new bucket, search the corresponding old bucket for the
404 * first entry that hashes to the new bucket, and link the end of
405 * newly formed bucket chain (containing entries added to future
406 * table) to that entry. Since all the entries which will end up in
407 * the new bucket appear in the same old bucket, this constructs an
408 * entirely valid new hash table, but with multiple buckets
409 * "zipped" together into a single imprecise chain.
410 */
411 for (new_hash = 0; new_hash < new_tbl->size; new_hash++) {
412 old_hash = rht_bucket_index(old_tbl, new_hash);
413 lock_buckets(new_tbl, old_tbl, new_hash);
414 rht_for_each(he, old_tbl, old_hash) {
415 if (head_hashfn(ht, new_tbl, he) == new_hash) {
416 link_old_to_new(ht, new_tbl, new_hash, he);
417 break;
418 }
419 }
420 unlock_buckets(new_tbl, old_tbl, new_hash);
421 cond_resched();
422 }
423
424 /* Unzip interleaved hash chains */
425 while (!complete && !ht->being_destroyed) {
426 /* Wait for readers. All new readers will see the new
427 * table, and thus no references to the old table will
428 * remain.
429 */
430 synchronize_rcu();
431
432 /* For each bucket in the old table (each of which
433 * contains items from multiple buckets of the new
434 * table): ...
435 */
436 complete = true;
437 for (old_hash = 0; old_hash < old_tbl->size; old_hash++) {
438 lock_buckets(new_tbl, old_tbl, old_hash);
439
440 if (hashtable_chain_unzip(ht, new_tbl, old_tbl,
441 old_hash))
442 complete = false;
443
444 unlock_buckets(new_tbl, old_tbl, old_hash);
445 cond_resched();
446 }
447 }
448
449 rcu_assign_pointer(ht->tbl, new_tbl);
450 synchronize_rcu();
451
452 bucket_table_free(old_tbl);
453 return 0; 329 return 0;
454} 330}
455EXPORT_SYMBOL_GPL(rhashtable_expand); 331EXPORT_SYMBOL_GPL(rhashtable_expand);
@@ -473,7 +349,6 @@ EXPORT_SYMBOL_GPL(rhashtable_expand);
473int rhashtable_shrink(struct rhashtable *ht) 349int rhashtable_shrink(struct rhashtable *ht)
474{ 350{
475 struct bucket_table *new_tbl, *tbl = rht_dereference(ht->tbl, ht); 351 struct bucket_table *new_tbl, *tbl = rht_dereference(ht->tbl, ht);
476 unsigned int new_hash;
477 352
478 ASSERT_RHT_MUTEX(ht); 353 ASSERT_RHT_MUTEX(ht);
479 354
@@ -483,39 +358,9 @@ int rhashtable_shrink(struct rhashtable *ht)
483 358
484 new_tbl->hash_rnd = tbl->hash_rnd; 359 new_tbl->hash_rnd = tbl->hash_rnd;
485 360
486 rcu_assign_pointer(ht->future_tbl, new_tbl);
487 synchronize_rcu();
488
489 /* Link the first entry in the old bucket to the end of the
490 * bucket in the new table. As entries are concurrently being
491 * added to the new table, lock down the new bucket. As we
492 * always divide the size in half when shrinking, each bucket
493 * in the new table maps to exactly two buckets in the old
494 * table.
495 */
496 for (new_hash = 0; new_hash < new_tbl->size; new_hash++) {
497 lock_buckets(new_tbl, tbl, new_hash);
498
499 rcu_assign_pointer(*bucket_tail(new_tbl, new_hash),
500 tbl->buckets[new_hash]);
501 ASSERT_BUCKET_LOCK(ht, tbl, new_hash + new_tbl->size);
502 rcu_assign_pointer(*bucket_tail(new_tbl, new_hash),
503 tbl->buckets[new_hash + new_tbl->size]);
504
505 unlock_buckets(new_tbl, tbl, new_hash);
506 cond_resched();
507 }
508
509 /* Publish the new, valid hash table */
510 rcu_assign_pointer(ht->tbl, new_tbl);
511 atomic_dec(&ht->shift); 361 atomic_dec(&ht->shift);
512 362
513 /* Wait for readers. No new readers will have references to the 363 rhashtable_rehash(ht, new_tbl);
514 * old hash table.
515 */
516 synchronize_rcu();
517
518 bucket_table_free(tbl);
519 364
520 return 0; 365 return 0;
521} 366}
@@ -545,18 +390,46 @@ unlock:
545 mutex_unlock(&ht->mutex); 390 mutex_unlock(&ht->mutex);
546} 391}
547 392
548static void __rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj, 393static bool __rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj,
549 struct bucket_table *tbl, 394 bool (*compare)(void *, void *), void *arg)
550 const struct bucket_table *old_tbl, u32 hash)
551{ 395{
552 bool no_resize_running = tbl == old_tbl; 396 struct bucket_table *tbl, *old_tbl;
553 struct rhash_head *head; 397 struct rhash_head *head;
398 bool no_resize_running;
399 unsigned hash;
400 bool success = true;
401
402 rcu_read_lock();
403
404 old_tbl = rht_dereference_rcu(ht->tbl, ht);
405 hash = obj_raw_hashfn(ht, old_tbl, rht_obj(ht, obj));
406
407 spin_lock_bh(bucket_lock(old_tbl, hash));
408
409 /* Because we have already taken the bucket lock in old_tbl,
410 * if we find that future_tbl is not yet visible then that
411 * guarantees all other insertions of the same entry will
412 * also grab the bucket lock in old_tbl because until the
413 * rehash completes ht->tbl won't be changed.
414 */
415 tbl = rht_dereference_rcu(ht->future_tbl, ht);
416 if (tbl != old_tbl) {
417 hash = obj_raw_hashfn(ht, tbl, rht_obj(ht, obj));
418 spin_lock(bucket_lock(tbl, hash));
419 }
420
421 if (compare &&
422 rhashtable_lookup_compare(ht, rht_obj(ht, obj) + ht->p.key_offset,
423 compare, arg)) {
424 success = false;
425 goto exit;
426 }
427
428 no_resize_running = tbl == old_tbl;
554 429
555 hash = rht_bucket_index(tbl, hash); 430 hash = rht_bucket_index(tbl, hash);
556 head = rht_dereference_bucket(tbl->buckets[hash], tbl, hash); 431 head = rht_dereference_bucket(tbl->buckets[hash], tbl, hash);
557 432
558 ASSERT_BUCKET_LOCK(ht, tbl, hash);
559
560 if (rht_is_a_nulls(head)) 433 if (rht_is_a_nulls(head))
561 INIT_RHT_NULLS_HEAD(obj->next, ht, hash); 434 INIT_RHT_NULLS_HEAD(obj->next, ht, hash);
562 else 435 else
@@ -567,6 +440,19 @@ static void __rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj,
567 atomic_inc(&ht->nelems); 440 atomic_inc(&ht->nelems);
568 if (no_resize_running && rht_grow_above_75(ht, tbl->size)) 441 if (no_resize_running && rht_grow_above_75(ht, tbl->size))
569 schedule_work(&ht->run_work); 442 schedule_work(&ht->run_work);
443
444exit:
445 if (tbl != old_tbl) {
446 hash = obj_raw_hashfn(ht, tbl, rht_obj(ht, obj));
447 spin_unlock(bucket_lock(tbl, hash));
448 }
449
450 hash = obj_raw_hashfn(ht, old_tbl, rht_obj(ht, obj));
451 spin_unlock_bh(bucket_lock(old_tbl, hash));
452
453 rcu_read_unlock();
454
455 return success;
570} 456}
571 457
572/** 458/**
@@ -586,22 +472,42 @@ static void __rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj,
586 */ 472 */
587void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj) 473void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj)
588{ 474{
589 struct bucket_table *tbl, *old_tbl; 475 __rhashtable_insert(ht, obj, NULL, NULL);
476}
477EXPORT_SYMBOL_GPL(rhashtable_insert);
478
479static bool __rhashtable_remove(struct rhashtable *ht,
480 struct bucket_table *tbl,
481 struct rhash_head *obj)
482{
483 struct rhash_head __rcu **pprev;
484 struct rhash_head *he;
485 spinlock_t * lock;
590 unsigned hash; 486 unsigned hash;
487 bool ret = false;
591 488
592 rcu_read_lock(); 489 hash = obj_raw_hashfn(ht, tbl, rht_obj(ht, obj));
490 lock = bucket_lock(tbl, hash);
491 hash = rht_bucket_index(tbl, hash);
593 492
594 tbl = rht_dereference_rcu(ht->future_tbl, ht); 493 spin_lock_bh(lock);
595 old_tbl = rht_dereference_rcu(ht->tbl, ht);
596 hash = obj_raw_hashfn(ht, rht_obj(ht, obj));
597 494
598 lock_buckets(tbl, old_tbl, hash); 495 pprev = &tbl->buckets[hash];
599 __rhashtable_insert(ht, obj, tbl, old_tbl, hash); 496 rht_for_each(he, tbl, hash) {
600 unlock_buckets(tbl, old_tbl, hash); 497 if (he != obj) {
498 pprev = &he->next;
499 continue;
500 }
601 501
602 rcu_read_unlock(); 502 rcu_assign_pointer(*pprev, obj->next);
503 ret = true;
504 break;
505 }
506
507 spin_unlock_bh(lock);
508
509 return ret;
603} 510}
604EXPORT_SYMBOL_GPL(rhashtable_insert);
605 511
606/** 512/**
607 * rhashtable_remove - remove object from hash table 513 * rhashtable_remove - remove object from hash table
@@ -620,68 +526,28 @@ EXPORT_SYMBOL_GPL(rhashtable_insert);
620 */ 526 */
621bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj) 527bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj)
622{ 528{
623 struct bucket_table *tbl, *new_tbl, *old_tbl; 529 struct bucket_table *tbl, *old_tbl;
624 struct rhash_head __rcu **pprev; 530 bool ret;
625 struct rhash_head *he, *he2;
626 unsigned int hash, new_hash;
627 bool ret = false;
628 531
629 rcu_read_lock(); 532 rcu_read_lock();
630 old_tbl = rht_dereference_rcu(ht->tbl, ht);
631 tbl = new_tbl = rht_dereference_rcu(ht->future_tbl, ht);
632 new_hash = obj_raw_hashfn(ht, rht_obj(ht, obj));
633
634 lock_buckets(new_tbl, old_tbl, new_hash);
635restart:
636 hash = rht_bucket_index(tbl, new_hash);
637 pprev = &tbl->buckets[hash];
638 rht_for_each(he, tbl, hash) {
639 if (he != obj) {
640 pprev = &he->next;
641 continue;
642 }
643 533
644 ASSERT_BUCKET_LOCK(ht, tbl, hash); 534 old_tbl = rht_dereference_rcu(ht->tbl, ht);
645 535 ret = __rhashtable_remove(ht, old_tbl, obj);
646 if (old_tbl->size > new_tbl->size && tbl == old_tbl &&
647 !rht_is_a_nulls(obj->next) &&
648 head_hashfn(ht, tbl, obj->next) != hash) {
649 rcu_assign_pointer(*pprev, (struct rhash_head *) rht_marker(ht, hash));
650 } else if (unlikely(old_tbl->size < new_tbl->size && tbl == new_tbl)) {
651 rht_for_each_continue(he2, obj->next, tbl, hash) {
652 if (head_hashfn(ht, tbl, he2) == hash) {
653 rcu_assign_pointer(*pprev, he2);
654 goto found;
655 }
656 }
657
658 rcu_assign_pointer(*pprev, (struct rhash_head *) rht_marker(ht, hash));
659 } else {
660 rcu_assign_pointer(*pprev, obj->next);
661 }
662
663found:
664 ret = true;
665 break;
666 }
667 536
668 /* The entry may be linked in either 'tbl', 'future_tbl', or both. 537 /* Because we have already taken (and released) the bucket
669 * 'future_tbl' only exists for a short period of time during 538 * lock in old_tbl, if we find that future_tbl is not yet
670 * resizing. Thus traversing both is fine and the added cost is 539 * visible then that guarantees the entry to still be in
671 * very rare. 540 * old_tbl if it exists.
672 */ 541 */
673 if (tbl != old_tbl) { 542 tbl = rht_dereference_rcu(ht->future_tbl, ht);
674 tbl = old_tbl; 543 if (!ret && old_tbl != tbl)
675 goto restart; 544 ret = __rhashtable_remove(ht, tbl, obj);
676 }
677
678 unlock_buckets(new_tbl, old_tbl, new_hash);
679 545
680 if (ret) { 546 if (ret) {
681 bool no_resize_running = new_tbl == old_tbl; 547 bool no_resize_running = tbl == old_tbl;
682 548
683 atomic_dec(&ht->nelems); 549 atomic_dec(&ht->nelems);
684 if (no_resize_running && rht_shrink_below_30(ht, new_tbl->size)) 550 if (no_resize_running && rht_shrink_below_30(ht, tbl->size))
685 schedule_work(&ht->run_work); 551 schedule_work(&ht->run_work);
686 } 552 }
687 553
@@ -753,9 +619,8 @@ void *rhashtable_lookup_compare(struct rhashtable *ht, const void *key,
753 619
754 rcu_read_lock(); 620 rcu_read_lock();
755 621
756 old_tbl = rht_dereference_rcu(ht->tbl, ht); 622 tbl = rht_dereference_rcu(ht->tbl, ht);
757 tbl = rht_dereference_rcu(ht->future_tbl, ht); 623 hash = key_hashfn(ht, tbl, key, ht->p.key_len);
758 hash = key_hashfn(ht, key, ht->p.key_len);
759restart: 624restart:
760 rht_for_each_rcu(he, tbl, rht_bucket_index(tbl, hash)) { 625 rht_for_each_rcu(he, tbl, rht_bucket_index(tbl, hash)) {
761 if (!compare(rht_obj(ht, he), arg)) 626 if (!compare(rht_obj(ht, he), arg))
@@ -764,10 +629,10 @@ restart:
764 return rht_obj(ht, he); 629 return rht_obj(ht, he);
765 } 630 }
766 631
767 if (unlikely(tbl != old_tbl)) { 632 old_tbl = tbl;
768 tbl = old_tbl; 633 tbl = rht_dereference_rcu(ht->future_tbl, ht);
634 if (unlikely(tbl != old_tbl))
769 goto restart; 635 goto restart;
770 }
771 rcu_read_unlock(); 636 rcu_read_unlock();
772 637
773 return NULL; 638 return NULL;
@@ -833,32 +698,9 @@ bool rhashtable_lookup_compare_insert(struct rhashtable *ht,
833 bool (*compare)(void *, void *), 698 bool (*compare)(void *, void *),
834 void *arg) 699 void *arg)
835{ 700{
836 struct bucket_table *new_tbl, *old_tbl;
837 u32 new_hash;
838 bool success = true;
839
840 BUG_ON(!ht->p.key_len); 701 BUG_ON(!ht->p.key_len);
841 702
842 rcu_read_lock(); 703 return __rhashtable_insert(ht, obj, compare, arg);
843 old_tbl = rht_dereference_rcu(ht->tbl, ht);
844 new_tbl = rht_dereference_rcu(ht->future_tbl, ht);
845 new_hash = obj_raw_hashfn(ht, rht_obj(ht, obj));
846
847 lock_buckets(new_tbl, old_tbl, new_hash);
848
849 if (rhashtable_lookup_compare(ht, rht_obj(ht, obj) + ht->p.key_offset,
850 compare, arg)) {
851 success = false;
852 goto exit;
853 }
854
855 __rhashtable_insert(ht, obj, new_tbl, old_tbl, new_hash);
856
857exit:
858 unlock_buckets(new_tbl, old_tbl, new_hash);
859 rcu_read_unlock();
860
861 return success;
862} 704}
863EXPORT_SYMBOL_GPL(rhashtable_lookup_compare_insert); 705EXPORT_SYMBOL_GPL(rhashtable_lookup_compare_insert);
864 706