Skip to content

Commit 3749a8f

Browse files
Pavel Tatashintorvalds
authored andcommitted
mm: zero hash tables in allocator
Add a new flag HASH_ZERO which when provided grantees that the hash table that is returned by alloc_large_system_hash() is zeroed. In most cases that is what is needed by the caller. Use page level allocator's __GFP_ZERO flags to zero the memory. It is using memset() which is efficient method to zero memory and is optimized for most platforms. Link: http://lkml.kernel.org/r/1488432825-92126-3-git-send-email-pasha.tatashin@oracle.com Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> Reviewed-by: Babu Moger <babu.moger@oracle.com> Cc: David Miller <davem@davemloft.net> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent f7fb506 commit 3749a8f

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

include/linux/bootmem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ extern void *alloc_large_system_hash(const char *tablename,
358358
#define HASH_EARLY 0x00000001 /* Allocating during early boot? */
359359
#define HASH_SMALL 0x00000002 /* sub-page allocation allowed, min
360360
* shift passed via *_hash_shift */
361+
#define HASH_ZERO 0x00000004 /* Zero allocated hash table */
361362

362363
/* Only NUMA needs hash distribution. 64bit NUMA architectures have
363364
* sufficient vmalloc space.

mm/page_alloc.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7198,6 +7198,7 @@ void *__init alloc_large_system_hash(const char *tablename,
71987198
unsigned long long max = high_limit;
71997199
unsigned long log2qty, size;
72007200
void *table = NULL;
7201+
gfp_t gfp_flags;
72017202

72027203
/* allow the kernel cmdline to have a say */
72037204
if (!numentries) {
@@ -7242,21 +7243,26 @@ void *__init alloc_large_system_hash(const char *tablename,
72427243

72437244
log2qty = ilog2(numentries);
72447245

7246+
/*
7247+
* memblock allocator returns zeroed memory already, so HASH_ZERO is
7248+
* currently not used when HASH_EARLY is specified.
7249+
*/
7250+
gfp_flags = (flags & HASH_ZERO) ? GFP_ATOMIC | __GFP_ZERO : GFP_ATOMIC;
72457251
do {
72467252
size = bucketsize << log2qty;
72477253
if (flags & HASH_EARLY)
72487254
table = memblock_virt_alloc_nopanic(size, 0);
72497255
else if (hashdist)
7250-
table = __vmalloc(size, GFP_ATOMIC, PAGE_KERNEL);
7256+
table = __vmalloc(size, gfp_flags, PAGE_KERNEL);
72517257
else {
72527258
/*
72537259
* If bucketsize is not a power-of-two, we may free
72547260
* some pages at the end of hash table which
72557261
* alloc_pages_exact() automatically does
72567262
*/
72577263
if (get_order(size) < MAX_ORDER) {
7258-
table = alloc_pages_exact(size, GFP_ATOMIC);
7259-
kmemleak_alloc(table, size, 1, GFP_ATOMIC);
7264+
table = alloc_pages_exact(size, gfp_flags);
7265+
kmemleak_alloc(table, size, 1, gfp_flags);
72607266
}
72617267
}
72627268
} while (!table && size > PAGE_SIZE && --log2qty);

0 commit comments

Comments
 (0)