aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rhashtable.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-01-02 17:00:18 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-03 14:32:57 -0500
commit897362e446436d245972e72c6bc5b33bd7a5c659 (patch)
treeefddc040f4d1042b486100cb20c3c3036b292420 /lib/rhashtable.c
parentb8e1943e9f754219bcfb40bac4a605b5348acb25 (diff)
nft_hash: Remove rhashtable_remove_pprev()
The removal function of nft_hash currently stores a reference to the previous element during lookup which is used to optimize removal later on. This was possible because a lock is held throughout calling rhashtable_lookup() and rhashtable_remove(). With the introdution of deferred table resizing in parallel to lookups and insertions, the nftables lock will no longer synchronize all table mutations and the stored pprev may become invalid. Removing this optimization makes removal slightly more expensive on average but allows taking the resize cost out of the insert and remove path. Signed-off-by: Thomas Graf <tgraf@suug.ch> Cc: netfilter-devel@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib/rhashtable.c')
-rw-r--r--lib/rhashtable.c34
1 files changed, 7 insertions, 27 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 0bd29c178910..e6b85c4a5828 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -345,32 +345,6 @@ void rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj)
345EXPORT_SYMBOL_GPL(rhashtable_insert); 345EXPORT_SYMBOL_GPL(rhashtable_insert);
346 346
347/** 347/**
348 * rhashtable_remove_pprev - remove object from hash table given previous element
349 * @ht: hash table
350 * @obj: pointer to hash head inside object
351 * @pprev: pointer to previous element
352 *
353 * Identical to rhashtable_remove() but caller is alreayd aware of the element
354 * in front of the element to be deleted. This is in particular useful for
355 * deletion when combined with walking or lookup.
356 */
357void rhashtable_remove_pprev(struct rhashtable *ht, struct rhash_head *obj,
358 struct rhash_head __rcu **pprev)
359{
360 struct bucket_table *tbl = rht_dereference(ht->tbl, ht);
361
362 ASSERT_RHT_MUTEX(ht);
363
364 RCU_INIT_POINTER(*pprev, obj->next);
365 ht->nelems--;
366
367 if (ht->p.shrink_decision &&
368 ht->p.shrink_decision(ht, tbl->size))
369 rhashtable_shrink(ht);
370}
371EXPORT_SYMBOL_GPL(rhashtable_remove_pprev);
372
373/**
374 * rhashtable_remove - remove object from hash table 348 * rhashtable_remove - remove object from hash table
375 * @ht: hash table 349 * @ht: hash table
376 * @obj: pointer to hash head inside object 350 * @obj: pointer to hash head inside object
@@ -403,7 +377,13 @@ bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj)
403 continue; 377 continue;
404 } 378 }
405 379
406 rhashtable_remove_pprev(ht, he, pprev); 380 RCU_INIT_POINTER(*pprev, he->next);
381 ht->nelems--;
382
383 if (ht->p.shrink_decision &&
384 ht->p.shrink_decision(ht, tbl->size))
385 rhashtable_shrink(ht);
386
407 return true; 387 return true;
408 } 388 }
409 389