summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-03-14 13:57:20 +1100
committerDavid S. Miller <davem@davemloft.net>2015-03-15 01:35:34 -0400
commiteddee5ba34eb6c9890ef106f19ead2b370e5342f (patch)
tree2cf7fcc92a1e2c2f541eda13aef5efd38501a0fb /include
parent96026d057a1fb7da1e314a24e3a1c528321ed45e (diff)
downloadlinux-eddee5ba34eb6c9890ef106f19ead2b370e5342f.tar.gz
linux-eddee5ba34eb6c9890ef106f19ead2b370e5342f.tar.bz2
linux-eddee5ba34eb6c9890ef106f19ead2b370e5342f.zip
rhashtable: Fix walker behaviour during rehash
Previously whenever the walker encountered a resize it simply snaps back to the beginning and starts again. However, this only works if the rehash started and completed while the walker was idle. If the walker attempts to restart while the rehash is still ongoing, we may miss objects that we shouldn't have. This patch fixes this by making the walker walk the old table followed by the new table just like all other readers. If a rehash is detected we will still signal our caller of the fact so they can prepare for duplicates but we will simply continue the walk onto the new table after the old one is finished either by us or by the rehasher. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/linux/rhashtable.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index c93ff8ac474a..4192682c1d5c 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -53,6 +53,7 @@ struct rhash_head {
* @shift: Current size (1 << shift)
* @locks_mask: Mask to apply before accessing locks[]
* @locks: Array of spinlocks protecting individual buckets
+ * @walkers: List of active walkers
* @buckets: size * hash buckets
*/
struct bucket_table {
@@ -61,6 +62,7 @@ struct bucket_table {
u32 shift;
unsigned int locks_mask;
spinlock_t *locks;
+ struct list_head walkers;
struct rhash_head __rcu *buckets[] ____cacheline_aligned_in_smp;
};
@@ -104,7 +106,6 @@ struct rhashtable_params {
* @p: Configuration parameters
* @run_work: Deferred worker to expand/shrink asynchronously
* @mutex: Mutex to protect current/future table swapping
- * @walkers: List of active walkers
* @being_destroyed: True if table is set up for destruction
*/
struct rhashtable {
@@ -115,17 +116,16 @@ struct rhashtable {
struct rhashtable_params p;
struct work_struct run_work;
struct mutex mutex;
- struct list_head walkers;
};
/**
* struct rhashtable_walker - Hash table walker
* @list: List entry on list of walkers
- * @resize: Resize event occured
+ * @tbl: The table that we were walking over
*/
struct rhashtable_walker {
struct list_head list;
- bool resize;
+ struct bucket_table *tbl;
};
/**