* [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work
@ 2015-03-24 13:18 Thomas Graf
2015-03-24 13:18 ` [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash() Thomas Graf
` (4 more replies)
0 siblings, 5 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Patch 1 is a bugfix for an RCU splash I encountered while testing.
Patch 2 & 3 are pure cleanups. Patch 4 disables automatic shrinking
by default as discussed in previous thread. Patch 5 removes some
rhashtable internal knowledge from nft_hash and fixes another RCU
splash.
I've pushed various rhashtable tests (Netlink, nft) together with a
Makefile to a git tree [0] for easier stress testing.
[0] https://github.com/tgraf/rhashtable
Thomas Graf (5):
rhashtable: Extend RCU read lock into rhashtable_insert_rehash()
rhashtable: Use 'unsigned int' consistently
rhashtable: Mark internal/private inline functions as such
rhashtable: Disable automatic shrinking by default
rhashtable: Add rhashtable_free_and_destroy()
include/linux/rhashtable.h | 50 +++++++++++++++++++++++-----------
lib/rhashtable.c | 67 +++++++++++++++++++++++++++++++++-------------
lib/test_rhashtable.c | 2 +-
net/netfilter/nft_hash.c | 27 ++++++-------------
net/netlink/af_netlink.c | 4 +--
net/tipc/socket.c | 3 ++-
6 files changed, 96 insertions(+), 57 deletions(-)
--
1.9.3
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash()
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
@ 2015-03-24 13:18 ` Thomas Graf
2015-03-24 19:40 ` Thomas Graf
2015-03-24 13:18 ` [PATCH 2/5 net-next] rhashtable: Use 'unsigned int' consistently Thomas Graf
` (3 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
rhashtable_insert_rehash() requires RCU locks to be held in order
to access ht->tbl and traverse to the last table.
Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index d7be9cb..5976ab5 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -585,8 +585,8 @@ restart:
if (unlikely(rht_grow_above_100(ht, tbl))) {
slow_path:
spin_unlock_bh(lock);
- rcu_read_unlock();
err = rhashtable_insert_rehash(ht);
+ rcu_read_unlock();
if (err)
return err;
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/5 net-next] rhashtable: Use 'unsigned int' consistently
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
2015-03-24 13:18 ` [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash() Thomas Graf
@ 2015-03-24 13:18 ` Thomas Graf
2015-03-24 13:18 ` [PATCH 3/5 net-next] rhashtable: Mark internal/private inline functions as such Thomas Graf
` (2 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 14 +++++++-------
lib/rhashtable.c | 18 ++++++++++--------
2 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 5976ab5..f89cda0 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -208,13 +208,13 @@ static inline unsigned int rht_key_hashfn(
struct rhashtable *ht, const struct bucket_table *tbl,
const void *key, const struct rhashtable_params params)
{
- unsigned hash;
+ unsigned int hash;
/* params must be equal to ht->p if it isn't constant. */
if (!__builtin_constant_p(params.key_len))
hash = ht->p.hashfn(key, ht->key_len, tbl->hash_rnd);
else if (params.key_len) {
- unsigned key_len = params.key_len;
+ unsigned int key_len = params.key_len;
if (params.hashfn)
hash = params.hashfn(key, key_len, tbl->hash_rnd);
@@ -224,7 +224,7 @@ static inline unsigned int rht_key_hashfn(
hash = jhash2(key, key_len / sizeof(u32),
tbl->hash_rnd);
} else {
- unsigned key_len = ht->p.key_len;
+ unsigned int key_len = ht->p.key_len;
if (params.hashfn)
hash = params.hashfn(key, key_len, tbl->hash_rnd);
@@ -512,7 +512,7 @@ static inline void *rhashtable_lookup_fast(
};
const struct bucket_table *tbl;
struct rhash_head *he;
- unsigned hash;
+ unsigned int hash;
rcu_read_lock();
@@ -550,8 +550,8 @@ static inline int __rhashtable_insert_fast(
struct bucket_table *tbl, *new_tbl;
struct rhash_head *head;
spinlock_t *lock;
- unsigned elasticity;
- unsigned hash;
+ unsigned int elasticity;
+ unsigned int hash;
int err;
restart:
@@ -718,7 +718,7 @@ static inline int __rhashtable_remove_fast(
struct rhash_head __rcu **pprev;
struct rhash_head *he;
spinlock_t * lock;
- unsigned hash;
+ unsigned int hash;
int err = -ENOENT;
hash = rht_head_hashfn(ht, tbl, obj, params);
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index e96ad1a..93374d7 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -153,7 +153,7 @@ static struct bucket_table *rhashtable_last_table(struct rhashtable *ht,
return new_tbl;
}
-static int rhashtable_rehash_one(struct rhashtable *ht, unsigned old_hash)
+static int rhashtable_rehash_one(struct rhashtable *ht, unsigned int old_hash)
{
struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
struct bucket_table *new_tbl = rhashtable_last_table(ht,
@@ -162,7 +162,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht, unsigned old_hash)
int err = -ENOENT;
struct rhash_head *head, *next, *entry;
spinlock_t *new_bucket_lock;
- unsigned new_hash;
+ unsigned int new_hash;
rht_for_each(entry, old_tbl, old_hash) {
err = 0;
@@ -199,7 +199,8 @@ out:
return err;
}
-static void rhashtable_rehash_chain(struct rhashtable *ht, unsigned old_hash)
+static void rhashtable_rehash_chain(struct rhashtable *ht,
+ unsigned int old_hash)
{
struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
spinlock_t *old_bucket_lock;
@@ -244,7 +245,7 @@ static int rhashtable_rehash_table(struct rhashtable *ht)
struct bucket_table *old_tbl = rht_dereference(ht->tbl, ht);
struct bucket_table *new_tbl;
struct rhashtable_walker *walker;
- unsigned old_hash;
+ unsigned int old_hash;
new_tbl = rht_dereference(old_tbl->future_tbl, ht);
if (!new_tbl)
@@ -324,11 +325,12 @@ static int rhashtable_expand(struct rhashtable *ht)
static int rhashtable_shrink(struct rhashtable *ht)
{
struct bucket_table *new_tbl, *old_tbl = rht_dereference(ht->tbl, ht);
- unsigned size = roundup_pow_of_two(atomic_read(&ht->nelems) * 3 / 2);
+ unsigned int size;
int err;
ASSERT_RHT_MUTEX(ht);
+ size = roundup_pow_of_two(atomic_read(&ht->nelems) * 3 / 2);
if (size < ht->p.min_size)
size = ht->p.min_size;
@@ -379,9 +381,9 @@ unlock:
static bool rhashtable_check_elasticity(struct rhashtable *ht,
struct bucket_table *tbl,
- unsigned hash)
+ unsigned int hash)
{
- unsigned elasticity = ht->elasticity;
+ unsigned int elasticity = ht->elasticity;
struct rhash_head *head;
rht_for_each(head, tbl, hash)
@@ -431,7 +433,7 @@ int rhashtable_insert_slow(struct rhashtable *ht, const void *key,
struct bucket_table *tbl)
{
struct rhash_head *head;
- unsigned hash;
+ unsigned int hash;
int err;
tbl = rhashtable_last_table(ht, tbl);
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/5 net-next] rhashtable: Mark internal/private inline functions as such
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
2015-03-24 13:18 ` [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash() Thomas Graf
2015-03-24 13:18 ` [PATCH 2/5 net-next] rhashtable: Use 'unsigned int' consistently Thomas Graf
@ 2015-03-24 13:18 ` Thomas Graf
2015-03-24 13:18 ` [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default Thomas Graf
2015-03-24 13:18 ` [PATCH 5/5 net-next] rhashtable: Add rhashtable_free_and_destroy() Thomas Graf
4 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index f89cda0..0e1f975 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -539,6 +539,7 @@ restart:
return NULL;
}
+/* Internal function, please use rhashtable_insert_fast() instead */
static inline int __rhashtable_insert_fast(
struct rhashtable *ht, const void *key, struct rhash_head *obj,
const struct rhashtable_params params)
@@ -711,6 +712,7 @@ static inline int rhashtable_lookup_insert_key(
return __rhashtable_insert_fast(ht, key, obj, params);
}
+/* Internal function, please use rhashtable_remove_fast() instead */
static inline int __rhashtable_remove_fast(
struct rhashtable *ht, struct bucket_table *tbl,
struct rhash_head *obj, const struct rhashtable_params params)
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
` (2 preceding siblings ...)
2015-03-24 13:18 ` [PATCH 3/5 net-next] rhashtable: Mark internal/private inline functions as such Thomas Graf
@ 2015-03-24 13:18 ` Thomas Graf
2015-03-24 18:55 ` Herbert Xu
2015-03-24 13:18 ` [PATCH 5/5 net-next] rhashtable: Add rhashtable_free_and_destroy() Thomas Graf
4 siblings, 1 reply; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
Using rhashtable_remove_fast() will no longer automatically
shrink the table. Users need to opt-in to shrinking by
explicitly using rhashtable_remove_and_shrink()
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 27 +++++++++++++++++++++------
lib/test_rhashtable.c | 2 +-
net/netfilter/nft_hash.c | 2 +-
net/netlink/af_netlink.c | 4 ++--
net/tipc/socket.c | 3 ++-
5 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 0e1f975..d0ca452 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -2,7 +2,7 @@
* Resizable, Scalable, Concurrent Hash Table
*
* Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
- * Copyright (c) 2014 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2014-2015 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2008-2014 Patrick McHardy <kaber@trash.net>
*
* Code partially derived from nft_hash
@@ -780,14 +780,29 @@ static inline int rhashtable_remove_fast(
(tbl = rht_dereference_rcu(tbl->future_tbl, ht)))
;
- if (err)
- goto out;
+ if (likely(!err))
+ atomic_dec(&ht->nelems);
+
+ rcu_read_unlock();
- atomic_dec(&ht->nelems);
- if (rht_shrink_below_30(ht, tbl))
+ return err;
+}
+
+static inline int rhashtable_remove_and_shrink(
+ struct rhashtable *ht, struct rhash_head *obj,
+ const struct rhashtable_params params)
+{
+ struct bucket_table *tbl;
+ int err;
+
+ rcu_read_lock();
+
+ tbl = rht_dereference_rcu(ht->tbl, ht);
+
+ err = rhashtable_remove_fast(ht, obj, params);
+ if (!err && rht_shrink_below_30(ht, tbl))
schedule_work(&ht->run_work);
-out:
rcu_read_unlock();
return err;
diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c
index a42a0d4..fe6d4a9 100644
--- a/lib/test_rhashtable.c
+++ b/lib/test_rhashtable.c
@@ -166,7 +166,7 @@ static int __init test_rhashtable(struct rhashtable *ht)
obj = rhashtable_lookup_fast(ht, &key, test_rht_params);
BUG_ON(!obj);
- rhashtable_remove_fast(ht, &obj->node, test_rht_params);
+ rhashtable_remove_and_shrink(ht, &obj->node, test_rht_params);
kfree(obj);
}
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index ad39669..2986f1d 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -89,7 +89,7 @@ static void nft_hash_remove(const struct nft_set *set,
{
struct rhashtable *priv = nft_set_priv(set);
- rhashtable_remove_fast(priv, elem->cookie, nft_hash_params);
+ rhashtable_remove_and_shrink(priv, elem->cookie, nft_hash_params);
synchronize_rcu();
kfree(elem->cookie);
}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e2f7f28..b9d3215 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1094,8 +1094,8 @@ static void netlink_remove(struct sock *sk)
struct netlink_table *table;
table = &nl_table[sk->sk_protocol];
- if (!rhashtable_remove_fast(&table->hash, &nlk_sk(sk)->node,
- netlink_rhashtable_params)) {
+ if (!rhashtable_remove_and_shrink(&table->hash, &nlk_sk(sk)->node,
+ netlink_rhashtable_params)) {
WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6dd5bd9..33338b4 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2282,7 +2282,8 @@ static void tipc_sk_remove(struct tipc_sock *tsk)
struct sock *sk = &tsk->sk;
struct tipc_net *tn = net_generic(sock_net(sk), tipc_net_id);
- if (!rhashtable_remove_fast(&tn->sk_rht, &tsk->node, tsk_rht_params)) {
+ if (!rhashtable_remove_and_shrink(&tn->sk_rht, &tsk->node,
+ tsk_rht_params)) {
WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
__sock_put(sk);
}
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/5 net-next] rhashtable: Add rhashtable_free_and_destroy()
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
` (3 preceding siblings ...)
2015-03-24 13:18 ` [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default Thomas Graf
@ 2015-03-24 13:18 ` Thomas Graf
4 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 13:18 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
rhashtable_destroy() variant which stops rehashes, iterates over
the table and calls a callback to release resources.
Avoids need for nft_hash to embed rhashtable internals and allows to
get rid of the being_destroyed flag. It also saves a 2nd mutex
lock upon destruction.
Also fixes an RCU lockdep splash on nft set destruction due to
calling rht_for_each_entry_safe() without holding bucket locks.
Open code this loop as we need know that no mutations may occur in
parallel.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
include/linux/rhashtable.h | 5 +++--
lib/rhashtable.c | 49 ++++++++++++++++++++++++++++++++++++----------
net/netfilter/nft_hash.c | 25 +++++++----------------
3 files changed, 49 insertions(+), 30 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index d0ca452..1995db3 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -134,12 +134,10 @@ struct rhashtable_params {
* @run_work: Deferred worker to expand/shrink asynchronously
* @mutex: Mutex to protect current/future table swapping
* @lock: Spin lock to protect walker list
- * @being_destroyed: True if table is set up for destruction
*/
struct rhashtable {
struct bucket_table __rcu *tbl;
atomic_t nelems;
- bool being_destroyed;
unsigned int key_len;
unsigned int elasticity;
struct rhashtable_params p;
@@ -332,6 +330,9 @@ int rhashtable_walk_start(struct rhashtable_iter *iter) __acquires(RCU);
void *rhashtable_walk_next(struct rhashtable_iter *iter);
void rhashtable_walk_stop(struct rhashtable_iter *iter) __releases(RCU);
+void rhashtable_free_and_destroy(struct rhashtable *ht,
+ void (*free_fn)(void *ptr, void *arg),
+ void *arg);
void rhashtable_destroy(struct rhashtable *ht);
#define rht_dereference(p, ht) \
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 93374d7..bb3a792 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -359,8 +359,6 @@ static void rht_deferred_worker(struct work_struct *work)
ht = container_of(work, struct rhashtable, run_work);
mutex_lock(&ht->mutex);
- if (ht->being_destroyed)
- goto unlock;
tbl = rht_dereference(ht->tbl, ht);
tbl = rhashtable_last_table(ht, tbl);
@@ -372,7 +370,6 @@ static void rht_deferred_worker(struct work_struct *work)
err = rhashtable_rehash_table(ht);
-unlock:
mutex_unlock(&ht->mutex);
if (err)
@@ -771,21 +768,53 @@ int rhashtable_init(struct rhashtable *ht,
EXPORT_SYMBOL_GPL(rhashtable_init);
/**
- * rhashtable_destroy - destroy hash table
+ * rhashtable_free_and_destroy - free elements and destroy hash table
* @ht: the hash table to destroy
+ * @free_fn: callback to release resources of element
+ * @arg: pointer passed to free_fn
*
- * Frees the bucket array. This function is not rcu safe, therefore the caller
- * has to make sure that no resizing may happen by unpublishing the hashtable
- * and waiting for the quiescent cycle before releasing the bucket array.
+ * Stops an eventual async resize. If defined, invokes free_fn for each
+ * element to releasal resources. Please note that RCU protected
+ * readers may still be accessing the elements. Releasing of resources
+ * must occur in a compatible manner. Then frees the bucket array.
+ *
+ * This function will eventually sleep to wait for an async resize
+ * to complete. The caller is responsible that no further write operations
+ * occurs in parallel.
*/
-void rhashtable_destroy(struct rhashtable *ht)
+void rhashtable_free_and_destroy(struct rhashtable *ht,
+ void (*free_fn)(void *ptr, void *arg),
+ void *arg)
{
- ht->being_destroyed = true;
+ const struct bucket_table *tbl;
+ unsigned int i;
cancel_work_sync(&ht->run_work);
mutex_lock(&ht->mutex);
- bucket_table_free(rht_dereference(ht->tbl, ht));
+ tbl = rht_dereference(ht->tbl, ht);
+ if (free_fn) {
+ for (i = 0; i < tbl->size; i++) {
+ struct rhash_head *pos, *next;
+
+ for (pos = rht_dereference(tbl->buckets[i], ht),
+ next = !rht_is_a_nulls(pos) ?
+ rht_dereference(pos->next, ht) : NULL;
+ !rht_is_a_nulls(pos);
+ pos = next,
+ next = !rht_is_a_nulls(pos) ?
+ rht_dereference(pos->next, ht) : NULL)
+ free_fn(rht_obj(ht, pos), arg);
+ }
+ }
+
+ bucket_table_free(tbl);
mutex_unlock(&ht->mutex);
}
+EXPORT_SYMBOL_GPL(rhashtable_free_and_destroy);
+
+void rhashtable_destroy(struct rhashtable *ht)
+{
+ return rhashtable_free_and_destroy(ht, NULL, NULL);
+}
EXPORT_SYMBOL_GPL(rhashtable_destroy);
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index 2986f1d..ad29965 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -187,26 +187,15 @@ static int nft_hash_init(const struct nft_set *set,
return rhashtable_init(priv, ¶ms);
}
-static void nft_hash_destroy(const struct nft_set *set)
+static void nft_free_element(void *ptr, void *arg)
{
- struct rhashtable *priv = nft_set_priv(set);
- const struct bucket_table *tbl;
- struct nft_hash_elem *he;
- struct rhash_head *pos, *next;
- unsigned int i;
-
- /* Stop an eventual async resizing */
- priv->being_destroyed = true;
- mutex_lock(&priv->mutex);
-
- tbl = rht_dereference(priv->tbl, priv);
- for (i = 0; i < tbl->size; i++) {
- rht_for_each_entry_safe(he, pos, next, tbl, i, node)
- nft_hash_elem_destroy(set, he);
- }
- mutex_unlock(&priv->mutex);
+ nft_hash_elem_destroy((const struct nft_set *)arg, ptr);
+}
- rhashtable_destroy(priv);
+static void nft_hash_destroy(const struct nft_set *set)
+{
+ rhashtable_free_and_destroy(nft_set_priv(set), nft_free_element,
+ (void *)set);
}
static bool nft_hash_estimate(const struct nft_set_desc *desc, u32 features,
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default
2015-03-24 13:18 ` [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default Thomas Graf
@ 2015-03-24 18:55 ` Herbert Xu
2015-03-24 19:28 ` Thomas Graf
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Herbert Xu @ 2015-03-24 18:55 UTC (permalink / raw)
To: Thomas Graf; +Cc: davem, netdev
On Tue, Mar 24, 2015 at 02:18:19PM +0100, Thomas Graf wrote:
> Using rhashtable_remove_fast() will no longer automatically
> shrink the table. Users need to opt-in to shrinking by
> explicitly using rhashtable_remove_and_shrink()
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
Note that this patch doesn't completely disable automatic shrinking
since the worker thread can still trigger it.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default
2015-03-24 18:55 ` Herbert Xu
@ 2015-03-24 19:28 ` Thomas Graf
2015-03-24 19:29 ` David Miller
2015-03-24 20:42 ` [PATCH 4/5 net-next v2] " Thomas Graf
2 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 19:28 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, netdev
On 03/25/15 at 05:55am, Herbert Xu wrote:
> On Tue, Mar 24, 2015 at 02:18:19PM +0100, Thomas Graf wrote:
> > Using rhashtable_remove_fast() will no longer automatically
> > shrink the table. Users need to opt-in to shrinking by
> > explicitly using rhashtable_remove_and_shrink()
> >
> > Signed-off-by: Thomas Graf <tgraf@suug.ch>
>
> Note that this patch doesn't completely disable automatic shrinking
> since the worker thread can still trigger it.
Right. I'll send a v2.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default
2015-03-24 18:55 ` Herbert Xu
2015-03-24 19:28 ` Thomas Graf
@ 2015-03-24 19:29 ` David Miller
2015-03-24 20:42 ` [PATCH 4/5 net-next v2] " Thomas Graf
2 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2015-03-24 19:29 UTC (permalink / raw)
To: herbert; +Cc: tgraf, netdev
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 25 Mar 2015 05:55:45 +1100
> On Tue, Mar 24, 2015 at 02:18:19PM +0100, Thomas Graf wrote:
>> Using rhashtable_remove_fast() will no longer automatically
>> shrink the table. Users need to opt-in to shrinking by
>> explicitly using rhashtable_remove_and_shrink()
>>
>> Signed-off-by: Thomas Graf <tgraf@suug.ch>
>
> Note that this patch doesn't completely disable automatic shrinking
> since the worker thread can still trigger it.
Ok, but how do you feel about Thomas's series otherwise?
It looks fine to me.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash()
2015-03-24 13:18 ` [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash() Thomas Graf
@ 2015-03-24 19:40 ` Thomas Graf
0 siblings, 0 replies; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 19:40 UTC (permalink / raw)
To: davem; +Cc: netdev, herbert
On 03/24/15 at 02:18pm, Thomas Graf wrote:
> @@ -585,8 +585,8 @@ restart:
> if (unlikely(rht_grow_above_100(ht, tbl))) {
> slow_path:
> spin_unlock_bh(lock);
> - rcu_read_unlock();
> err = rhashtable_insert_rehash(ht);
> + rcu_read_unlock();
> if (err)
> return err;
An alternative would be to start a new RCU section inside
rhashtable_insert_rehash(). This was the easier fix but I'm
fine either way.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/5 net-next v2] rhashtable: Disable automatic shrinking by default
2015-03-24 18:55 ` Herbert Xu
2015-03-24 19:28 ` Thomas Graf
2015-03-24 19:29 ` David Miller
@ 2015-03-24 20:42 ` Thomas Graf
2015-03-24 22:01 ` David Miller
2 siblings, 1 reply; 12+ messages in thread
From: Thomas Graf @ 2015-03-24 20:42 UTC (permalink / raw)
To: Herbert Xu; +Cc: davem, netdev
Introduce a new bool automatic_shrinking to require the
user to explicitly opt-in to automatic shrinking of tables.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
v2: Use bool in params to also disable shrinking in worker as
pointed out by Herbert.
@Dave: Patch 5 still applied on top with some fuzz. If not,
let me know and I will respin.
include/linux/rhashtable.h | 7 +++++--
lib/rhashtable.c | 2 +-
net/netfilter/nft_hash.c | 1 +
net/netlink/af_netlink.c | 1 +
net/tipc/socket.c | 1 +
5 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 0e1f975..ae26c49 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -2,7 +2,7 @@
* Resizable, Scalable, Concurrent Hash Table
*
* Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
- * Copyright (c) 2014 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2014-2015 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2008-2014 Patrick McHardy <kaber@trash.net>
*
* Code partially derived from nft_hash
@@ -104,6 +104,7 @@ struct rhashtable;
* @min_size: Minimum size while shrinking
* @nulls_base: Base value to generate nulls marker
* @insecure_elasticity: Set to true to disable chain length checks
+ * @automatic_shrinking: Enable automatic shrinking of tables
* @locks_mul: Number of bucket locks to allocate per cpu (default: 128)
* @hashfn: Hash function (default: jhash2 if !(key_len % 4), or jhash)
* @obj_hashfn: Function to hash object
@@ -118,6 +119,7 @@ struct rhashtable_params {
unsigned int min_size;
u32 nulls_base;
bool insecure_elasticity;
+ bool automatic_shrinking;
size_t locks_mul;
rht_hashfn_t hashfn;
rht_obj_hashfn_t obj_hashfn;
@@ -784,7 +786,8 @@ static inline int rhashtable_remove_fast(
goto out;
atomic_dec(&ht->nelems);
- if (rht_shrink_below_30(ht, tbl))
+ if (unlikely(ht->p.automatic_shrinking &&
+ rht_shrink_below_30(ht, tbl)))
schedule_work(&ht->run_work);
out:
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 93374d7..a0ad777 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -367,7 +367,7 @@ static void rht_deferred_worker(struct work_struct *work)
if (rht_grow_above_75(ht, tbl))
rhashtable_expand(ht);
- else if (rht_shrink_below_30(ht, tbl))
+ else if (ht->p.automatic_shrinking && rht_shrink_below_30(ht, tbl))
rhashtable_shrink(ht);
err = rhashtable_rehash_table(ht);
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index ad39669..8577a37 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -172,6 +172,7 @@ static const struct rhashtable_params nft_hash_params = {
.head_offset = offsetof(struct nft_hash_elem, node),
.key_offset = offsetof(struct nft_hash_elem, key),
.hashfn = jhash,
+ .automatic_shrinking = true,
};
static int nft_hash_init(const struct nft_set *set,
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index e2f7f28..4caa809 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -3142,6 +3142,7 @@ static const struct rhashtable_params netlink_rhashtable_params = {
.obj_hashfn = netlink_hash,
.obj_cmpfn = netlink_compare,
.max_size = 65536,
+ .automatic_shrinking = true,
};
static int __init netlink_proto_init(void)
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 6dd5bd9..3cc099d 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -2295,6 +2295,7 @@ static const struct rhashtable_params tsk_rht_params = {
.key_len = sizeof(u32), /* portid */
.max_size = 1048576,
.min_size = 256,
+ .automatic_shrinking = true,
};
int tipc_sk_rht_init(struct net *net)
--
1.9.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 4/5 net-next v2] rhashtable: Disable automatic shrinking by default
2015-03-24 20:42 ` [PATCH 4/5 net-next v2] " Thomas Graf
@ 2015-03-24 22:01 ` David Miller
0 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2015-03-24 22:01 UTC (permalink / raw)
To: tgraf; +Cc: herbert, netdev
From: Thomas Graf <tgraf@suug.ch>
Date: Tue, 24 Mar 2015 20:42:19 +0000
> Introduce a new bool automatic_shrinking to require the
> user to explicitly opt-in to automatic shrinking of tables.
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> ---
> v2: Use bool in params to also disable shrinking in worker as
> pointed out by Herbert.
>
> @Dave: Patch 5 still applied on top with some fuzz. If not,
> let me know and I will respin.
Ok I applied this series with the updated patch #4, thanks!
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2015-03-24 22:01 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-24 13:18 [PATCH 0/5 net-next] rhashtable updates on top of Herbert's work Thomas Graf
2015-03-24 13:18 ` [PATCH 1/5 net-next] rhashtable: Extend RCU read lock into rhashtable_insert_rehash() Thomas Graf
2015-03-24 19:40 ` Thomas Graf
2015-03-24 13:18 ` [PATCH 2/5 net-next] rhashtable: Use 'unsigned int' consistently Thomas Graf
2015-03-24 13:18 ` [PATCH 3/5 net-next] rhashtable: Mark internal/private inline functions as such Thomas Graf
2015-03-24 13:18 ` [PATCH 4/5 net-next] rhashtable: Disable automatic shrinking by default Thomas Graf
2015-03-24 18:55 ` Herbert Xu
2015-03-24 19:28 ` Thomas Graf
2015-03-24 19:29 ` David Miller
2015-03-24 20:42 ` [PATCH 4/5 net-next v2] " Thomas Graf
2015-03-24 22:01 ` David Miller
2015-03-24 13:18 ` [PATCH 5/5 net-next] rhashtable: Add rhashtable_free_and_destroy() Thomas Graf
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.