netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/2] rhashtable rehashing fixes
@ 2015-04-21 12:55 Thomas Graf
  2015-04-21 12:55 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
  2015-04-21 12:55 ` [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further Thomas Graf
  0 siblings, 2 replies; 9+ messages in thread
From: Thomas Graf @ 2015-04-21 12:55 UTC (permalink / raw)
  To: davem; +Cc: herbert, kaber, netdev

Some rhashtable rehashing bugs found while testing with the
next rhashtable self-test queued up for the next devel cycle:

https://github.com/tgraf/net-next/commits/rht

Thomas Graf (2):
  rhashtable: Schedule async resize when sync realloc fails
  rhashtable: Do not schedule more than one rehash if we can't grow
    further

 include/linux/rhashtable.h | 2 ++
 lib/rhashtable.c           | 4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

-- 
2.3.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-21 12:55 [PATCH net 0/2] rhashtable rehashing fixes Thomas Graf
@ 2015-04-21 12:55 ` Thomas Graf
  2015-04-22  0:36   ` Herbert Xu
  2015-04-21 12:55 ` [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further Thomas Graf
  1 sibling, 1 reply; 9+ messages in thread
From: Thomas Graf @ 2015-04-21 12:55 UTC (permalink / raw)
  To: davem; +Cc: herbert, kaber, netdev

When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
we can't allocate the necessary memory in the current context but the
limits as set by the user would still allow to grow.

Thus attempt an async resize in the background where we can allocate
using GFP_KERNEL which is more likely to succeed. The insertion itself
will still fail to indicate pressure.

This fixes a bug where the table would never continue growing once the
utilization is above 100%.

Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
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 e23d242..7040b5c 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -593,6 +593,8 @@ slow_path:
 		spin_unlock_bh(lock);
 		err = rhashtable_insert_rehash(ht);
 		rcu_read_unlock();
+		if (err == -ENOMEM)
+			schedule_work(&ht->run_work);
 		if (err)
 			return err;
 
-- 
2.3.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further
  2015-04-21 12:55 [PATCH net 0/2] rhashtable rehashing fixes Thomas Graf
  2015-04-21 12:55 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
@ 2015-04-21 12:55 ` Thomas Graf
  2015-04-22  0:37   ` Herbert Xu
  1 sibling, 1 reply; 9+ messages in thread
From: Thomas Graf @ 2015-04-21 12:55 UTC (permalink / raw)
  To: davem; +Cc: herbert, kaber, netdev

The current code currently only stops inserting rehashes into the
chain when no resizes are currently scheduled. As long as resizes
are scheduled and while inserting above the utilization watermark,
more and more rehashes will be scheduled.

This lead to a perfect DoS storm with thousands of rehashes
scheduled which lead to thousands of spinlocks to be taken
sequentially.

Instead, only allow either a series of resizes or a single rehash.
Drop any further rehashes and return -EBUSY.

Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
 lib/rhashtable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 4898442..cb819ed 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -405,8 +405,8 @@ int rhashtable_insert_rehash(struct rhashtable *ht)
 
 	if (rht_grow_above_75(ht, tbl))
 		size *= 2;
-	/* More than two rehashes (not resizes) detected. */
-	else if (WARN_ON(old_tbl != tbl && old_tbl->size == size))
+	/* Do not schedule more than one rehash */
+	else if (old_tbl != tbl)
 		return -EBUSY;
 
 	new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);
-- 
2.3.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-21 12:55 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
@ 2015-04-22  0:36   ` Herbert Xu
  2015-04-22  2:10     ` David Miller
  0 siblings, 1 reply; 9+ messages in thread
From: Herbert Xu @ 2015-04-22  0:36 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, kaber, netdev

On Tue, Apr 21, 2015 at 02:55:34PM +0200, Thomas Graf wrote:
> When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
> we can't allocate the necessary memory in the current context but the
> limits as set by the user would still allow to grow.
> 
> Thus attempt an async resize in the background where we can allocate
> using GFP_KERNEL which is more likely to succeed. The insertion itself
> will still fail to indicate pressure.
> 
> This fixes a bug where the table would never continue growing once the
> utilization is above 100%.
> 
> Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Good catch.  But I think this call should happen in
rhashtable_insert_rehash since it's on the slow-path.

Thanks,
-- 
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] 9+ messages in thread

* Re: [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further
  2015-04-21 12:55 ` [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further Thomas Graf
@ 2015-04-22  0:37   ` Herbert Xu
  0 siblings, 0 replies; 9+ messages in thread
From: Herbert Xu @ 2015-04-22  0:37 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, kaber, netdev

On Tue, Apr 21, 2015 at 02:55:35PM +0200, Thomas Graf wrote:
> The current code currently only stops inserting rehashes into the
> chain when no resizes are currently scheduled. As long as resizes
> are scheduled and while inserting above the utilization watermark,
> more and more rehashes will be scheduled.
> 
> This lead to a perfect DoS storm with thousands of rehashes
> scheduled which lead to thousands of spinlocks to be taken
> sequentially.
> 
> Instead, only allow either a series of resizes or a single rehash.
> Drop any further rehashes and return -EBUSY.
> 
> Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-- 
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] 9+ messages in thread

* Re: [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-22  0:36   ` Herbert Xu
@ 2015-04-22  2:10     ` David Miller
  2015-04-22  7:18       ` Thomas Graf
  0 siblings, 1 reply; 9+ messages in thread
From: David Miller @ 2015-04-22  2:10 UTC (permalink / raw)
  To: herbert; +Cc: tgraf, kaber, netdev

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 22 Apr 2015 08:36:34 +0800

> On Tue, Apr 21, 2015 at 02:55:34PM +0200, Thomas Graf wrote:
>> When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
>> we can't allocate the necessary memory in the current context but the
>> limits as set by the user would still allow to grow.
>> 
>> Thus attempt an async resize in the background where we can allocate
>> using GFP_KERNEL which is more likely to succeed. The insertion itself
>> will still fail to indicate pressure.
>> 
>> This fixes a bug where the table would never continue growing once the
>> utilization is above 100%.
>> 
>> Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
>> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> 
> Good catch.  But I think this call should happen in
> rhashtable_insert_rehash since it's on the slow-path.

Ok, then I expect a respin of this series.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-22  2:10     ` David Miller
@ 2015-04-22  7:18       ` Thomas Graf
  0 siblings, 0 replies; 9+ messages in thread
From: Thomas Graf @ 2015-04-22  7:18 UTC (permalink / raw)
  To: David Miller; +Cc: herbert, kaber, netdev

On 04/21/15 at 10:10pm, David Miller wrote:
> From: Herbert Xu <herbert@gondor.apana.org.au>
> Date: Wed, 22 Apr 2015 08:36:34 +0800
> 
> > On Tue, Apr 21, 2015 at 02:55:34PM +0200, Thomas Graf wrote:
> >> When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
> >> we can't allocate the necessary memory in the current context but the
> >> limits as set by the user would still allow to grow.
> >> 
> >> Thus attempt an async resize in the background where we can allocate
> >> using GFP_KERNEL which is more likely to succeed. The insertion itself
> >> will still fail to indicate pressure.
> >> 
> >> This fixes a bug where the table would never continue growing once the
> >> utilization is above 100%.
> >> 
> >> Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
> >> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> > 
> > Good catch.  But I think this call should happen in
> > rhashtable_insert_rehash since it's on the slow-path.
> 
> Ok, then I expect a respin of this series.

Agreed, respinning.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-22  7:41 [PATCH net 0/2 v2] rhashtable rehashing fixes Thomas Graf
@ 2015-04-22  7:41 ` Thomas Graf
  2015-04-22  7:43   ` Herbert Xu
  0 siblings, 1 reply; 9+ messages in thread
From: Thomas Graf @ 2015-04-22  7:41 UTC (permalink / raw)
  To: davem; +Cc: netdev, herbert, kaber

When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
we can't allocate the necessary memory in the current context but the
limits as set by the user would still allow to grow.

Thus attempt an async resize in the background where we can allocate
using GFP_KERNEL which is more likely to succeed. The insertion itself
will still fail to indicate pressure.

This fixes a bug where the table would never continue growing once the
utilization is above 100%.

Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
Signed-off-by: Thomas Graf <tgraf@suug.ch>
---
 lib/rhashtable.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 4898442..f648cfd 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -410,8 +410,13 @@ int rhashtable_insert_rehash(struct rhashtable *ht)
 		return -EBUSY;
 
 	new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);
-	if (new_tbl == NULL)
+	if (new_tbl == NULL) {
+		/* Schedule async resize/rehash to try allocation
+		 * non-atomic context.
+		 */
+		schedule_work(&ht->run_work);
 		return -ENOMEM;
+	}
 
 	err = rhashtable_rehash_attach(ht, tbl, new_tbl);
 	if (err) {
-- 
2.3.5

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails
  2015-04-22  7:41 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
@ 2015-04-22  7:43   ` Herbert Xu
  0 siblings, 0 replies; 9+ messages in thread
From: Herbert Xu @ 2015-04-22  7:43 UTC (permalink / raw)
  To: Thomas Graf; +Cc: davem, netdev, kaber

On Wed, Apr 22, 2015 at 09:41:45AM +0200, Thomas Graf wrote:
> When rhashtable_insert_rehash() fails with ENOMEM, this indicates that
> we can't allocate the necessary memory in the current context but the
> limits as set by the user would still allow to grow.
> 
> Thus attempt an async resize in the background where we can allocate
> using GFP_KERNEL which is more likely to succeed. The insertion itself
> will still fail to indicate pressure.
> 
> This fixes a bug where the table would never continue growing once the
> utilization is above 100%.
> 
> Fixes: ccd57b1bd324 ("rhashtable: Add immediate rehash during insertion")
> Signed-off-by: Thomas Graf <tgraf@suug.ch>

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
-- 
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] 9+ messages in thread

end of thread, other threads:[~2015-04-22  7:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-21 12:55 [PATCH net 0/2] rhashtable rehashing fixes Thomas Graf
2015-04-21 12:55 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
2015-04-22  0:36   ` Herbert Xu
2015-04-22  2:10     ` David Miller
2015-04-22  7:18       ` Thomas Graf
2015-04-21 12:55 ` [PATCH net 2/2] rhashtable: Do not schedule more than one rehash if we can't grow further Thomas Graf
2015-04-22  0:37   ` Herbert Xu
  -- strict thread matches above, loose matches on Subject: below --
2015-04-22  7:41 [PATCH net 0/2 v2] rhashtable rehashing fixes Thomas Graf
2015-04-22  7:41 ` [PATCH net 1/2] rhashtable: Schedule async resize when sync realloc fails Thomas Graf
2015-04-22  7:43   ` Herbert Xu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).