aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/mm/numa.c41
-rw-r--r--arch/x86_64/mm/srat.c6
2 files changed, 38 insertions, 9 deletions
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index 779132af29a7..cc02573a3271 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -100,11 +100,30 @@ int early_pfn_to_nid(unsigned long pfn)
100} 100}
101#endif 101#endif
102 102
103static void * __init
104early_node_mem(int nodeid, unsigned long start, unsigned long end,
105 unsigned long size)
106{
107 unsigned long mem = find_e820_area(start, end, size);
108 void *ptr;
109 if (mem != -1L)
110 return __va(mem);
111 ptr = __alloc_bootmem_nopanic(size,
112 SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS));
113 if (ptr == 0) {
114 printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
115 size, nodeid);
116 return NULL;
117 }
118 return ptr;
119}
120
103/* Initialize bootmem allocator for a node */ 121/* Initialize bootmem allocator for a node */
104void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) 122void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end)
105{ 123{
106 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start; 124 unsigned long start_pfn, end_pfn, bootmap_pages, bootmap_size, bootmap_start;
107 unsigned long nodedata_phys; 125 unsigned long nodedata_phys;
126 void *bootmap;
108 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE); 127 const int pgdat_size = round_up(sizeof(pg_data_t), PAGE_SIZE);
109 128
110 start = round_up(start, ZONE_ALIGN); 129 start = round_up(start, ZONE_ALIGN);
@@ -114,13 +133,11 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
114 start_pfn = start >> PAGE_SHIFT; 133 start_pfn = start >> PAGE_SHIFT;
115 end_pfn = end >> PAGE_SHIFT; 134 end_pfn = end >> PAGE_SHIFT;
116 135
117 nodedata_phys = find_e820_area(start, end, pgdat_size); 136 node_data[nodeid] = early_node_mem(nodeid, start, end, pgdat_size);
118 if (nodedata_phys == -1L) 137 if (node_data[nodeid] == NULL)
119 panic("Cannot find memory pgdat in node %d\n", nodeid); 138 return;
120 139 nodedata_phys = __pa(node_data[nodeid]);
121 Dprintk("nodedata_phys %lx\n", nodedata_phys);
122 140
123 node_data[nodeid] = phys_to_virt(nodedata_phys);
124 memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t)); 141 memset(NODE_DATA(nodeid), 0, sizeof(pg_data_t));
125 NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid]; 142 NODE_DATA(nodeid)->bdata = &plat_node_bdata[nodeid];
126 NODE_DATA(nodeid)->node_start_pfn = start_pfn; 143 NODE_DATA(nodeid)->node_start_pfn = start_pfn;
@@ -129,9 +146,15 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en
129 /* Find a place for the bootmem map */ 146 /* Find a place for the bootmem map */
130 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); 147 bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
131 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE); 148 bootmap_start = round_up(nodedata_phys + pgdat_size, PAGE_SIZE);
132 bootmap_start = find_e820_area(bootmap_start, end, bootmap_pages<<PAGE_SHIFT); 149 bootmap = early_node_mem(nodeid, bootmap_start, end,
133 if (bootmap_start == -1L) 150 bootmap_pages<<PAGE_SHIFT);
134 panic("Not enough continuous space for bootmap on node %d", nodeid); 151 if (bootmap == NULL) {
152 if (nodedata_phys < start || nodedata_phys >= end)
153 free_bootmem((unsigned long)node_data[nodeid],pgdat_size);
154 node_data[nodeid] = NULL;
155 return;
156 }
157 bootmap_start = __pa(bootmap);
135 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages); 158 Dprintk("bootmap start %lu pages %lu\n", bootmap_start, bootmap_pages);
136 159
137 bootmap_size = init_bootmem_node(NODE_DATA(nodeid), 160 bootmap_size = init_bootmem_node(NODE_DATA(nodeid),
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 443875eb15a2..15ae9fcd65a7 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -415,6 +415,12 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
415 /* Finally register nodes */ 415 /* Finally register nodes */
416 for_each_node_mask(i, nodes_parsed) 416 for_each_node_mask(i, nodes_parsed)
417 setup_node_bootmem(i, nodes[i].start, nodes[i].end); 417 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
418 /* Try again in case setup_node_bootmem missed one due
419 to missing bootmem */
420 for_each_node_mask(i, nodes_parsed)
421 if (!node_online(i))
422 setup_node_bootmem(i, nodes[i].start, nodes[i].end);
423
418 for (i = 0; i < NR_CPUS; i++) { 424 for (i = 0; i < NR_CPUS; i++) {
419 if (cpu_to_node[i] == NUMA_NO_NODE) 425 if (cpu_to_node[i] == NUMA_NO_NODE)
420 continue; 426 continue;