--- a/compat/lib-rhashtable.c +++ b/compat/lib-rhashtable.c @@ -86,11 +86,26 @@ static int alloc_bucket_locks(struct rha size = min(size, 1U << tbl->nest); if (sizeof(spinlock_t) != 0) { +#if LINUX_VERSION_IS_LESS(4,12,0) + tbl->locks = NULL; +#ifdef CONFIG_NUMA + if (size * sizeof(spinlock_t) > PAGE_SIZE && + gfp == GFP_KERNEL) + tbl->locks = vmalloc(size * sizeof(spinlock_t)); +#endif + if (gfp != GFP_KERNEL) + gfp |= __GFP_NOWARN | __GFP_NORETRY; + + if (!tbl->locks) + tbl->locks = kmalloc_array(size, sizeof(spinlock_t), + gfp); +#else if (gfpflags_allow_blocking(gfp)) tbl->locks = kvmalloc(size * sizeof(spinlock_t), gfp); else tbl->locks = kmalloc_array(size, sizeof(spinlock_t), gfp); +#endif if (!tbl->locks) return -ENOMEM; for (i = 0; i < size; i++) @@ -211,10 +226,11 @@ static struct bucket_table *bucket_table int i; size = sizeof(*tbl) + nbuckets * sizeof(tbl->buckets[0]); - if (gfp != GFP_KERNEL) + if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER) || + gfp != GFP_KERNEL) tbl = kzalloc(size, gfp | __GFP_NOWARN | __GFP_NORETRY); - else - tbl = kvzalloc(size, gfp); + if (tbl == NULL && gfp == GFP_KERNEL) + tbl = vzalloc(size); size = nbuckets;