All of lore.kernel.org
 help / color / mirror / Atom feed
From: Herbert Xu <herbert@gondor.apana.org.au>
To: Thomas Graf <tgraf@suug.ch>, netdev@vger.kernel.org
Subject: [PATCH 6/6] rhashtable: Move future_tbl into struct bucket_table
Date: Fri, 13 Mar 2015 20:57:15 +1100	[thread overview]
Message-ID: <E1YWMLD-0000CV-VK@gondolin.me.apana.org.au> (raw)
In-Reply-To: 20150313095607.GA598@gondor.apana.org.au

This patch moves future_tbl to open up the possibility of having
multiple rehashes on the same table.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
---

 include/linux/rhashtable.h |    5 +++--
 lib/rhashtable.c           |   27 +++++++++++----------------
 2 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index ed7562a..1695378 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -56,6 +56,7 @@ struct rhash_head {
  * @locks: Array of spinlocks protecting individual buckets
  * @walkers: List of active walkers
  * @rcu: RCU structure for freeing the table
+ * @future_tbl: Table under construction during rehashing
  * @buckets: size * hash buckets
  */
 struct bucket_table {
@@ -68,6 +69,8 @@ struct bucket_table {
 	struct list_head	walkers;
 	struct rcu_head		rcu;
 
+	struct bucket_table __rcu *future_tbl;
+
 	struct rhash_head __rcu	*buckets[] ____cacheline_aligned_in_smp;
 };
 
@@ -105,7 +108,6 @@ struct rhashtable_params {
 /**
  * struct rhashtable - Hash table handle
  * @tbl: Bucket table
- * @future_tbl: Table under construction during expansion/shrinking
  * @nelems: Number of elements in table
  * @p: Configuration parameters
  * @run_work: Deferred worker to expand/shrink asynchronously
@@ -114,7 +116,6 @@ struct rhashtable_params {
  */
 struct rhashtable {
 	struct bucket_table __rcu	*tbl;
-	struct bucket_table __rcu       *future_tbl;
 	atomic_t			nelems;
 	bool                            being_destroyed;
 	struct rhashtable_params	p;
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index ff4ea17..9d53a46 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -207,8 +207,9 @@ static bool rht_shrink_below_30(const struct rhashtable *ht,
 
 static int rhashtable_rehash_one(struct rhashtable *ht, unsigned old_hash)
 {
-	struct bucket_table *new_tbl = rht_dereference(ht->future_tbl, ht);
 	struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
+	struct bucket_table *new_tbl =
+		rht_dereference(old_tbl->future_tbl, ht) ?: old_tbl;
 	struct rhash_head __rcu **pprev = &old_tbl->buckets[old_hash];
 	int err = -ENOENT;
 	struct rhash_head *head, *next, *entry;
@@ -273,10 +274,8 @@ static void rhashtable_rehash(struct rhashtable *ht,
 
 	/* Make insertions go into the new, empty table right away. Deletions
 	 * and lookups will be attempted in both tables until we synchronize.
-	 * The synchronize_rcu() guarantees for the new table to be picked up
-	 * so no new additions go into the old table while we relink.
 	 */
-	rcu_assign_pointer(ht->future_tbl, new_tbl);
+	rcu_assign_pointer(old_tbl->future_tbl, new_tbl);
 
 	/* Ensure the new table is visible to readers. */
 	smp_wmb();
@@ -400,7 +399,7 @@ static bool __rhashtable_insert(struct rhashtable *ht, struct rhash_head *obj,
 	 * also grab the bucket lock in old_tbl because until the
 	 * rehash completes ht->tbl won't be changed.
 	 */
-	tbl = rht_dereference_rcu(ht->future_tbl, ht);
+	tbl = rht_dereference_rcu(old_tbl->future_tbl, ht) ?: old_tbl;
 	if (tbl != old_tbl) {
 		hash = head_hashfn(ht, tbl, obj);
 		spin_lock_nested(bucket_lock(tbl, hash), SINGLE_DEPTH_NESTING);
@@ -525,7 +524,7 @@ bool rhashtable_remove(struct rhashtable *ht, struct rhash_head *obj)
 	 * visible then that guarantees the entry to still be in
 	 * old_tbl if it exists.
 	 */
-	tbl = rht_dereference_rcu(ht->future_tbl, ht);
+	tbl = rht_dereference_rcu(old_tbl->future_tbl, ht) ?: old_tbl;
 	if (!ret && old_tbl != tbl)
 		ret = __rhashtable_remove(ht, tbl, obj);
 
@@ -599,7 +598,7 @@ EXPORT_SYMBOL_GPL(rhashtable_lookup);
 void *rhashtable_lookup_compare(struct rhashtable *ht, const void *key,
 				bool (*compare)(void *, void *), void *arg)
 {
-	const struct bucket_table *tbl, *old_tbl;
+	const struct bucket_table *tbl;
 	struct rhash_head *he;
 	u32 hash;
 
@@ -618,9 +617,8 @@ restart:
 	/* Ensure we see any new tables. */
 	smp_rmb();
 
-	old_tbl = tbl;
-	tbl = rht_dereference_rcu(ht->future_tbl, ht);
-	if (unlikely(tbl != old_tbl))
+	tbl = rht_dereference_rcu(tbl->future_tbl, ht);
+	if (unlikely(tbl))
 		goto restart;
 	rcu_read_unlock();
 
@@ -830,14 +828,13 @@ next:
 		iter->skip = 0;
 	}
 
-	iter->walker->tbl = rht_dereference_rcu(ht->future_tbl, ht);
-	if (iter->walker->tbl != tbl) {
+	iter->walker->tbl = rht_dereference_rcu(tbl->future_tbl, ht);
+	if (iter->walker->tbl) {
 		iter->slot = 0;
 		iter->skip = 0;
 		return ERR_PTR(-EAGAIN);
 	}
 
-	iter->walker->tbl = NULL;
 	iter->p = NULL;
 
 out:
@@ -865,8 +862,7 @@ void rhashtable_walk_stop(struct rhashtable_iter *iter)
 	ht = iter->ht;
 
 	mutex_lock(&ht->mutex);
-	if (rht_dereference(ht->tbl, ht) == tbl ||
-	    rht_dereference(ht->future_tbl, ht) == tbl)
+	if (tbl->rehash < tbl->size)
 		list_add(&iter->walker->list, &tbl->walkers);
 	else
 		iter->walker->tbl = NULL;
@@ -961,7 +957,6 @@ int rhashtable_init(struct rhashtable *ht, struct rhashtable_params *params)
 	atomic_set(&ht->nelems, 0);
 
 	RCU_INIT_POINTER(ht->tbl, tbl);
-	RCU_INIT_POINTER(ht->future_tbl, tbl);
 
 	INIT_WORK(&ht->run_work, rht_deferred_worker);
 

  parent reply	other threads:[~2015-03-13  9:57 UTC|newest]

Thread overview: 113+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-13  9:56 [PATCH 0/6] rhashtable: Fixes + cleanups + preparation for multiple rehash Herbert Xu
2015-03-13  9:57 ` [PATCH 1/6] rhashtable: Fix walker behaviour during rehash Herbert Xu
2015-03-13 15:50   ` Thomas Graf
2015-03-13 23:42     ` Herbert Xu
2015-03-14  0:06       ` Thomas Graf
2015-03-13  9:57 ` [PATCH 2/6] rhashtable: Use SINGLE_DEPTH_NESTING Herbert Xu
2015-03-13 15:40   ` Thomas Graf
2015-03-13  9:57 ` [PATCH 3/6] rhashtable: Move seed init into bucket_table_alloc Herbert Xu
2015-03-13 10:03   ` Daniel Borkmann
2015-03-13 11:33   ` David Laight
2015-03-13 11:40     ` Herbert Xu
2015-03-13 15:40   ` Thomas Graf
2015-03-13  9:57 ` [PATCH 4/6] rhashtable: Free bucket tables asynchronously after rehash Herbert Xu
2015-03-13 15:42   ` Thomas Graf
2015-03-13  9:57 ` [PATCH 5/6] rhashtable: Add rehash counter to bucket_table Herbert Xu
2015-03-13 13:51   ` Thomas Graf
2015-03-14  2:49     ` Herbert Xu
2015-03-13  9:57 ` Herbert Xu [this message]
2015-03-13 16:13   ` [PATCH 6/6] rhashtable: Move future_tbl into struct bucket_table Thomas Graf
2015-03-13 13:57 ` [PATCH 0/6] rhashtable: Fixes + cleanups + preparation for multiple rehash Thomas Graf
2015-03-13 16:25 ` David Miller
2015-03-14  2:51   ` Herbert Xu
2015-03-14  2:53 ` [v2 PATCH " Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 1/6] rhashtable: Fix walker behaviour during rehash Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 2/6] rhashtable: Use SINGLE_DEPTH_NESTING Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 3/6] rhashtable: Move seed init into bucket_table_alloc Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 4/6] rhashtable: Free bucket tables asynchronously after rehash Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 5/6] rhashtable: Add rehash counter to bucket_table Herbert Xu
2015-03-14  2:57   ` [v2 PATCH 6/6] rhashtable: Move future_tbl into struct bucket_table Herbert Xu
2015-03-15  5:36   ` [v2 PATCH 0/6] rhashtable: Fixes + cleanups + preparation for multiple rehash David Miller
2015-03-15 10:10     ` [v1 PATCH 0/6] rhashtable: Fix two bugs caused by multiple rehash preparation Herbert Xu
2015-03-15 10:12       ` [v1 PATCH 1/2] rhashtable: Fix use-after-free in rhashtable_walk_stop Herbert Xu
2015-03-15 10:12       ` [v1 PATCH 2/2] rhashtable: Fix rhashtable_remove failures Herbert Xu
2015-03-15 10:43       ` [v1 PATCH 0/14] rhashtable: Kill shift/Key netlink namespace/Merge jhash Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 1/14] rhashtable: Remove shift from bucket_table Herbert Xu
2015-03-17 10:51           ` David Laight
2015-03-17 10:56             ` tgraf
2015-03-17 11:00               ` Herbert Xu
2015-03-17 11:22                 ` tgraf
2015-03-17 11:27                   ` Herbert Xu
2015-03-17 11:57                     ` tgraf
2015-03-17 12:13                       ` David Laight
2015-03-17 12:18                         ` 'tgraf@suug.ch'
2015-03-17 12:20                         ` Herbert Xu
2015-03-17 12:40                           ` 'tgraf@suug.ch'
2015-03-17 13:06                             ` David Laight
2015-03-17 21:56                             ` Herbert Xu
2015-03-18  9:51                               ` 'tgraf@suug.ch'
2015-03-18  9:55                                 ` Herbert Xu
2015-03-18 10:08                                   ` 'tgraf@suug.ch'
2015-03-18 10:12                                     ` Herbert Xu
2015-03-18 10:26                                       ` David Laight
2015-03-18 10:44                                       ` 'tgraf@suug.ch'
2015-03-17 11:22                 ` David Laight
2015-03-17 11:25                   ` Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 2/14] rhashtable: Introduce max_size/min_size Herbert Xu
2015-03-15 15:12           ` Sergei Shtylyov
2015-03-15 20:21             ` Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 3/14] netlink: Use rhashtable max_size instead of max_shift Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 4/14] tipc: " Herbert Xu
2015-03-15 15:13           ` Sergei Shtylyov
2015-03-15 10:44         ` [v1 PATCH 5/14] test_rhashtable: " Herbert Xu
2015-03-16  3:50           ` David Miller
2015-03-15 10:44         ` [v1 PATCH 6/14] rhashtable: Remove max_shift and min_shift Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 7/14] netfilter: Use rhashtable_lookup instead of lookup_compare Herbert Xu
2015-03-16  8:28           ` Thomas Graf
2015-03-16  9:14             ` Herbert Xu
2015-03-16  9:28               ` Thomas Graf
2015-03-16 11:13               ` Patrick McHardy
2015-03-20  8:55                 ` Herbert Xu
2015-03-20  9:22                   ` Patrick McHardy
2015-03-20  9:27                     ` Herbert Xu
2015-03-20  9:59                       ` Patrick McHardy
2015-03-20 10:16                         ` Herbert Xu
2015-03-20 10:27                           ` Patrick McHardy
2015-03-20 21:47                             ` Herbert Xu
2015-03-20 21:56                               ` Thomas Graf
2015-03-20 21:57                                 ` Herbert Xu
2015-03-20 22:07                                   ` Thomas Graf
2015-03-20 22:10                                     ` Herbert Xu
2015-03-20 22:23                                       ` Thomas Graf
2015-03-20 22:25                                         ` Herbert Xu
2015-03-20 22:36                                           ` Thomas Graf
2015-03-21  5:25                                             ` Patrick McHardy
2015-03-21  5:23                               ` Patrick McHardy
2015-03-20  9:36               ` Herbert Xu
2015-03-20 10:02                 ` Patrick McHardy
2015-03-15 10:44         ` [v1 PATCH 8/14] rhashtable: Fix support of objects with no accessible keys Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 9/14] netlink: Move namespace into hash key Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 10/14] rhashtable: Rip out obsolete compare interface Herbert Xu
2015-03-16  9:35           ` Thomas Graf
2015-03-15 10:44         ` [v1 PATCH 11/14] rhashtable: Allow hashfn to be unset Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 12/14] netlink: Use default rhashtable hashfn Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 13/14] tipc: " Herbert Xu
2015-03-15 10:44         ` [v1 PATCH 14/14] netfilter: " Herbert Xu
2015-03-16  4:01         ` [v1 PATCH 0/14] rhashtable: Kill shift/Key netlink namespace/Merge jhash David Miller
2015-03-16  4:18           ` Herbert Xu
2015-03-16  4:30             ` David Miller
2015-03-16  4:33               ` Herbert Xu
2015-03-16  4:40                 ` David Miller
2015-03-16 11:26                   ` Herbert Xu
2015-03-16 20:25                     ` David Miller
2015-03-18  9:01         ` [v2 PATCH 1/6] rhashtable: Remove shift from bucket_table Herbert Xu
2015-03-18  9:01         ` [v2 PATCH 2/6] rhashtable: Introduce max_size/min_size Herbert Xu
2015-03-18 10:55           ` Thomas Graf
2015-03-18 16:47             ` David Miller
2015-03-18 16:51             ` David Laight
2015-03-18  9:01         ` [v2 PATCH 3/6] netlink: Use rhashtable max_size instead of max_shift Herbert Xu
2015-03-18  9:01         ` [v2 PATCH 4/6] tipc: Use rhashtable max/min_size instead of max/min_shift Herbert Xu
2015-03-18  9:01         ` [v2 PATCH 5/6] test_rhashtable: Use rhashtable max_size instead of max_shift Herbert Xu
2015-03-18  9:01         ` [v2 PATCH 6/6] rhashtable: Remove max_shift and min_shift Herbert Xu
2015-03-15 10:43       ` [v1 PATCH 0/6] rhashtable: Fix two bugs caused by multiple rehash preparation Herbert Xu
2015-03-16  2:23       ` David Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1YWMLD-0000CV-VK@gondolin.me.apana.org.au \
    --to=herbert@gondor.apana.org.au \
    --cc=netdev@vger.kernel.org \
    --cc=tgraf@suug.ch \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.