Skip to content

Commit ec11408

Browse files
npiggintorvalds
authored andcommitted
mm/large system hash: use vmalloc for size > MAX_ORDER when !hashdist
The kernel currently clamps large system hashes to MAX_ORDER when hashdist is not set, which is rather arbitrary. vmalloc space is limited on 32-bit machines, but this shouldn't result in much more used because of small physical memory limiting system hash sizes. Include "vmalloc" or "linear" in the kernel log message. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Nicholas Piggin <[email protected]> Reviewed-by: Andrew Morton <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent d9009d6 commit ec11408

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

mm/page_alloc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7981,6 +7981,7 @@ void *__init alloc_large_system_hash(const char *tablename,
79817981
unsigned long log2qty, size;
79827982
void *table = NULL;
79837983
gfp_t gfp_flags;
7984+
bool virt;
79847985

79857986
/* allow the kernel cmdline to have a say */
79867987
if (!numentries) {
@@ -8037,33 +8038,34 @@ void *__init alloc_large_system_hash(const char *tablename,
80378038

80388039
gfp_flags = (flags & HASH_ZERO) ? GFP_ATOMIC | __GFP_ZERO : GFP_ATOMIC;
80398040
do {
8041+
virt = false;
80408042
size = bucketsize << log2qty;
80418043
if (flags & HASH_EARLY) {
80428044
if (flags & HASH_ZERO)
80438045
table = memblock_alloc(size, SMP_CACHE_BYTES);
80448046
else
80458047
table = memblock_alloc_raw(size,
80468048
SMP_CACHE_BYTES);
8047-
} else if (hashdist) {
8049+
} else if (get_order(size) >= MAX_ORDER || hashdist) {
80488050
table = __vmalloc(size, gfp_flags, PAGE_KERNEL);
8051+
virt = true;
80498052
} else {
80508053
/*
80518054
* If bucketsize is not a power-of-two, we may free
80528055
* some pages at the end of hash table which
80538056
* alloc_pages_exact() automatically does
80548057
*/
8055-
if (get_order(size) < MAX_ORDER) {
8056-
table = alloc_pages_exact(size, gfp_flags);
8057-
kmemleak_alloc(table, size, 1, gfp_flags);
8058-
}
8058+
table = alloc_pages_exact(size, gfp_flags);
8059+
kmemleak_alloc(table, size, 1, gfp_flags);
80598060
}
80608061
} while (!table && size > PAGE_SIZE && --log2qty);
80618062

80628063
if (!table)
80638064
panic("Failed to allocate %s hash table\n", tablename);
80648065

8065-
pr_info("%s hash table entries: %ld (order: %d, %lu bytes)\n",
8066-
tablename, 1UL << log2qty, ilog2(size) - PAGE_SHIFT, size);
8066+
pr_info("%s hash table entries: %ld (order: %d, %lu bytes, %s)\n",
8067+
tablename, 1UL << log2qty, ilog2(size) - PAGE_SHIFT, size,
8068+
virt ? "vmalloc" : "linear");
80678069

80688070
if (_hash_shift)
80698071
*_hash_shift = log2qty;

0 commit comments

Comments
 (0)