From: Thomas Graf Date: Wed, 22 Apr 2015 07:41:45 +0000 (+0200) Subject: rhashtable: Schedule async resize when sync realloc fails X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e2307ed6cbe71c74e291681aaa7e92ab98bc3177;p=openwrt%2Fstaging%2Fblogic.git 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 Acked-by: Herbert Xu Signed-off-by: David S. Miller --- 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) 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) {