Skip to content

Commit f7f9910

Browse files
Pavel Tatashintorvalds
authored andcommitted
mm: stop zeroing memory during allocation in vmemmap
vmemmap_alloc_block() will no longer zero the block, so zero memory at its call sites for everything except struct pages. Struct page memory is zero'd by struct page initialization. Replace allocators in sparse-vmemmap to use the non-zeroing version. So, we will get the performance improvement by zeroing the memory in parallel when struct pages are zeroed. Add struct page zeroing as a part of initialization of other fields in __init_single_page(). This single thread performance collected on: Intel(R) Xeon(R) CPU E7-8895 v3 @ 2.60GHz with 1T of memory (268400646 pages in 8 nodes): BASE FIX sparse_init 11.244671836s 0.007199623s zone_sizes_init 4.879775891s 8.355182299s -------------------------- Total 16.124447727s 8.362381922s sparse_init is where memory for struct pages is zeroed, and the zeroing part is moved later in this patch into __init_single_page(), which is called from zone_sizes_init(). [akpm@linux-foundation.org: make vmemmap_alloc_block_zero() private to sparse-vmemmap.c] Link: http://lkml.kernel.org/r/20171013173214.27300-10-pasha.tatashin@oracle.com Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com> Reviewed-by: Steven Sistare <steven.sistare@oracle.com> Reviewed-by: Daniel Jordan <daniel.m.jordan@oracle.com> Reviewed-by: Bob Picco <bob.picco@oracle.com> Tested-by: Bob Picco <bob.picco@oracle.com> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: David S. Miller <davem@davemloft.net> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Michal Hocko <mhocko@kernel.org> Cc: Sam Ravnborg <sam@ravnborg.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent e17d802 commit f7f9910

File tree

3 files changed

+22
-11
lines changed

3 files changed

+22
-11
lines changed

mm/page_alloc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,7 @@ static void free_one_page(struct zone *zone,
11681168
static void __meminit __init_single_page(struct page *page, unsigned long pfn,
11691169
unsigned long zone, int nid)
11701170
{
1171+
mm_zero_struct_page(page);
11711172
set_page_links(page, zone, nid, pfn);
11721173
init_page_count(page);
11731174
page_mapcount_reset(page);

mm/sparse-vmemmap.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static void * __ref __earlyonly_bootmem_alloc(int node,
4242
unsigned long align,
4343
unsigned long goal)
4444
{
45-
return memblock_virt_alloc_try_nid(size, align, goal,
45+
return memblock_virt_alloc_try_nid_raw(size, align, goal,
4646
BOOTMEM_ALLOC_ACCESSIBLE, node);
4747
}
4848

@@ -55,9 +55,8 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
5555
if (slab_is_available()) {
5656
struct page *page;
5757

58-
page = alloc_pages_node(node,
59-
GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL,
60-
get_order(size));
58+
page = alloc_pages_node(node, GFP_KERNEL | __GFP_RETRY_MAYFAIL,
59+
get_order(size));
6160
if (page)
6261
return page_address(page);
6362
return NULL;
@@ -180,11 +179,22 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
180179
return pte;
181180
}
182181

182+
static void * __meminit vmemmap_alloc_block_zero(unsigned long size, int node)
183+
{
184+
void *p = vmemmap_alloc_block(size, node);
185+
186+
if (!p)
187+
return NULL;
188+
memset(p, 0, size);
189+
190+
return p;
191+
}
192+
183193
pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
184194
{
185195
pmd_t *pmd = pmd_offset(pud, addr);
186196
if (pmd_none(*pmd)) {
187-
void *p = vmemmap_alloc_block(PAGE_SIZE, node);
197+
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
188198
if (!p)
189199
return NULL;
190200
pmd_populate_kernel(&init_mm, pmd, p);
@@ -196,7 +206,7 @@ pud_t * __meminit vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node)
196206
{
197207
pud_t *pud = pud_offset(p4d, addr);
198208
if (pud_none(*pud)) {
199-
void *p = vmemmap_alloc_block(PAGE_SIZE, node);
209+
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
200210
if (!p)
201211
return NULL;
202212
pud_populate(&init_mm, pud, p);
@@ -208,7 +218,7 @@ p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
208218
{
209219
p4d_t *p4d = p4d_offset(pgd, addr);
210220
if (p4d_none(*p4d)) {
211-
void *p = vmemmap_alloc_block(PAGE_SIZE, node);
221+
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
212222
if (!p)
213223
return NULL;
214224
p4d_populate(&init_mm, p4d, p);
@@ -220,7 +230,7 @@ pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
220230
{
221231
pgd_t *pgd = pgd_offset_k(addr);
222232
if (pgd_none(*pgd)) {
223-
void *p = vmemmap_alloc_block(PAGE_SIZE, node);
233+
void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
224234
if (!p)
225235
return NULL;
226236
pgd_populate(&init_mm, pgd, p);

mm/sparse.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,9 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
453453
}
454454

455455
size = PAGE_ALIGN(size);
456-
map = memblock_virt_alloc_try_nid(size * map_count,
457-
PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
458-
BOOTMEM_ALLOC_ACCESSIBLE, nodeid);
456+
map = memblock_virt_alloc_try_nid_raw(size * map_count,
457+
PAGE_SIZE, __pa(MAX_DMA_ADDRESS),
458+
BOOTMEM_ALLOC_ACCESSIBLE, nodeid);
459459
if (map) {
460460
for (pnum = pnum_begin; pnum < pnum_end; pnum++) {
461461
if (!present_section_nr(pnum))

0 commit comments

Comments
 (0)