summaryrefslogtreecommitdiffstats
path: root/mm/sparse-vmemmap.c
diff options
context:
space:
mode:
authorPavel Tatashin <pasha.tatashin@oracle.com>2017-11-15 20:36:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-15 21:21:05 -0500
commitf7f99100d8d95dbcf09e0216a143211e79418b9f (patch)
tree58e42a439b1acbf5d8c76f3c3820d896b4f71c8c /mm/sparse-vmemmap.c
parente17d8025f07e4fd9d73b137a8bcab04548126b83 (diff)
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>
Diffstat (limited to 'mm/sparse-vmemmap.c')
-rw-r--r--mm/sparse-vmemmap.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 478ce6d4a2c4..4e49762599c8 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -42,7 +42,7 @@ static void * __ref __earlyonly_bootmem_alloc(int node,
42 unsigned long align, 42 unsigned long align,
43 unsigned long goal) 43 unsigned long goal)
44{ 44{
45 return memblock_virt_alloc_try_nid(size, align, goal, 45 return memblock_virt_alloc_try_nid_raw(size, align, goal,
46 BOOTMEM_ALLOC_ACCESSIBLE, node); 46 BOOTMEM_ALLOC_ACCESSIBLE, node);
47} 47}
48 48
@@ -55,9 +55,8 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
55 if (slab_is_available()) { 55 if (slab_is_available()) {
56 struct page *page; 56 struct page *page;
57 57
58 page = alloc_pages_node(node, 58 page = alloc_pages_node(node, GFP_KERNEL | __GFP_RETRY_MAYFAIL,
59 GFP_KERNEL | __GFP_ZERO | __GFP_RETRY_MAYFAIL, 59 get_order(size));
60 get_order(size));
61 if (page) 60 if (page)
62 return page_address(page); 61 return page_address(page);
63 return NULL; 62 return NULL;
@@ -180,11 +179,22 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
180 return pte; 179 return pte;
181} 180}
182 181
182static 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
183pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node) 193pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
184{ 194{
185 pmd_t *pmd = pmd_offset(pud, addr); 195 pmd_t *pmd = pmd_offset(pud, addr);
186 if (pmd_none(*pmd)) { 196 if (pmd_none(*pmd)) {
187 void *p = vmemmap_alloc_block(PAGE_SIZE, node); 197 void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
188 if (!p) 198 if (!p)
189 return NULL; 199 return NULL;
190 pmd_populate_kernel(&init_mm, pmd, p); 200 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)
196{ 206{
197 pud_t *pud = pud_offset(p4d, addr); 207 pud_t *pud = pud_offset(p4d, addr);
198 if (pud_none(*pud)) { 208 if (pud_none(*pud)) {
199 void *p = vmemmap_alloc_block(PAGE_SIZE, node); 209 void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
200 if (!p) 210 if (!p)
201 return NULL; 211 return NULL;
202 pud_populate(&init_mm, pud, p); 212 pud_populate(&init_mm, pud, p);
@@ -208,7 +218,7 @@ p4d_t * __meminit vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node)
208{ 218{
209 p4d_t *p4d = p4d_offset(pgd, addr); 219 p4d_t *p4d = p4d_offset(pgd, addr);
210 if (p4d_none(*p4d)) { 220 if (p4d_none(*p4d)) {
211 void *p = vmemmap_alloc_block(PAGE_SIZE, node); 221 void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
212 if (!p) 222 if (!p)
213 return NULL; 223 return NULL;
214 p4d_populate(&init_mm, p4d, p); 224 p4d_populate(&init_mm, p4d, p);
@@ -220,7 +230,7 @@ pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
220{ 230{
221 pgd_t *pgd = pgd_offset_k(addr); 231 pgd_t *pgd = pgd_offset_k(addr);
222 if (pgd_none(*pgd)) { 232 if (pgd_none(*pgd)) {
223 void *p = vmemmap_alloc_block(PAGE_SIZE, node); 233 void *p = vmemmap_alloc_block_zero(PAGE_SIZE, node);
224 if (!p) 234 if (!p)
225 return NULL; 235 return NULL;
226 pgd_populate(&init_mm, pgd, p); 236 pgd_populate(&init_mm, pgd, p);