aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2015-04-22 03:41:45 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-22 14:17:22 -0400
commite2307ed6cbe71c74e291681aaa7e92ab98bc3177 (patch)
tree85280146bb297aaf40b4f921f0a1983fe01fe80d /lib
parentd83769a580f1132ac26439f50068a29b02be535e (diff)
rhashtable: Schedule async resize when sync realloc fails
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r--lib/rhashtable.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 4898442b837f..f648cfde8520 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -410,8 +410,13 @@ int rhashtable_insert_rehash(struct rhashtable *ht)
410 return -EBUSY; 410 return -EBUSY;
411 411
412 new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC); 412 new_tbl = bucket_table_alloc(ht, size, GFP_ATOMIC);
413 if (new_tbl == NULL) 413 if (new_tbl == NULL) {
414 /* Schedule async resize/rehash to try allocation
415 * non-atomic context.
416 */
417 schedule_work(&ht->run_work);
414 return -ENOMEM; 418 return -ENOMEM;
419 }
415 420
416 err = rhashtable_rehash_attach(ht, tbl, new_tbl); 421 err = rhashtable_rehash_attach(ht, tbl, new_tbl);
417 if (err) { 422 if (err) {