|
@@ -178,10 +178,11 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht,
|
|
|
|
|
|
size = nbuckets;
|
|
|
|
|
|
- if (tbl == NULL && gfp != GFP_KERNEL) {
|
|
|
+ if (tbl == NULL && (gfp & ~__GFP_NOFAIL) != GFP_KERNEL) {
|
|
|
tbl = nested_bucket_table_alloc(ht, nbuckets, gfp);
|
|
|
nbuckets = 0;
|
|
|
}
|
|
|
+
|
|
|
if (tbl == NULL)
|
|
|
return NULL;
|
|
|
|
|
@@ -1057,9 +1058,16 @@ int rhashtable_init(struct rhashtable *ht,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * This is api initialization and thus we need to guarantee the
|
|
|
+ * initial rhashtable allocation. Upon failure, retry with the
|
|
|
+ * smallest possible size with __GFP_NOFAIL semantics.
|
|
|
+ */
|
|
|
tbl = bucket_table_alloc(ht, size, GFP_KERNEL);
|
|
|
- if (tbl == NULL)
|
|
|
- return -ENOMEM;
|
|
|
+ if (unlikely(tbl == NULL)) {
|
|
|
+ size = max_t(u16, ht->p.min_size, HASH_MIN_SIZE);
|
|
|
+ tbl = bucket_table_alloc(ht, size, GFP_KERNEL | __GFP_NOFAIL);
|
|
|
+ }
|
|
|
|
|
|
atomic_set(&ht->nelems, 0);
|
|
|
|