summaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-01-15 19:56:22 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 20:56:32 -0500
commit4b94ffdc4163bae1ec73b6e977ffb7a7da3d06d3 (patch)
treef653da252999e8c1f45a2c7ae18fb1c241b4a300 /mm/page_alloc.c
parent9476df7d80dfc425b37bfecf1d89edf8ec81fcb6 (diff)
x86, mm: introduce vmem_altmap to augment vmemmap_populate()
In support of providing struct page for large persistent memory capacities, use struct vmem_altmap to change the default policy for allocating memory for the memmap array. The default vmemmap_populate() allocates page table storage area from the page allocator. Given persistent memory capacities relative to DRAM it may not be feasible to store the memmap in 'System Memory'. Instead vmem_altmap represents pre-allocated "device pages" to satisfy vmemmap_alloc_block_buf() requests. Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reported-by: kbuild test robot <lkp@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 25409714160e..7ca3fe6ef92d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -43,6 +43,7 @@
43#include <linux/vmalloc.h> 43#include <linux/vmalloc.h>
44#include <linux/vmstat.h> 44#include <linux/vmstat.h>
45#include <linux/mempolicy.h> 45#include <linux/mempolicy.h>
46#include <linux/memremap.h>
46#include <linux/stop_machine.h> 47#include <linux/stop_machine.h>
47#include <linux/sort.h> 48#include <linux/sort.h>
48#include <linux/pfn.h> 49#include <linux/pfn.h>
@@ -4485,8 +4486,9 @@ static inline unsigned long wait_table_bits(unsigned long size)
4485void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone, 4486void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
4486 unsigned long start_pfn, enum memmap_context context) 4487 unsigned long start_pfn, enum memmap_context context)
4487{ 4488{
4488 pg_data_t *pgdat = NODE_DATA(nid); 4489 struct vmem_altmap *altmap = to_vmem_altmap(__pfn_to_phys(start_pfn));
4489 unsigned long end_pfn = start_pfn + size; 4490 unsigned long end_pfn = start_pfn + size;
4491 pg_data_t *pgdat = NODE_DATA(nid);
4490 unsigned long pfn; 4492 unsigned long pfn;
4491 struct zone *z; 4493 struct zone *z;
4492 unsigned long nr_initialised = 0; 4494 unsigned long nr_initialised = 0;
@@ -4494,6 +4496,13 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
4494 if (highest_memmap_pfn < end_pfn - 1) 4496 if (highest_memmap_pfn < end_pfn - 1)
4495 highest_memmap_pfn = end_pfn - 1; 4497 highest_memmap_pfn = end_pfn - 1;
4496 4498
4499 /*
4500 * Honor reservation requested by the driver for this ZONE_DEVICE
4501 * memory
4502 */
4503 if (altmap && start_pfn == altmap->base_pfn)
4504 start_pfn += altmap->reserve;
4505
4497 z = &pgdat->node_zones[zone]; 4506 z = &pgdat->node_zones[zone];
4498 for (pfn = start_pfn; pfn < end_pfn; pfn++) { 4507 for (pfn = start_pfn; pfn < end_pfn; pfn++) {
4499 /* 4508 /*