aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/mm/discontig.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/mm/discontig.c')
-rw-r--r--arch/i386/mm/discontig.c105
1 files changed, 44 insertions, 61 deletions
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index 7c392dc553b8..51e3739dd227 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -117,7 +117,8 @@ void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
117 117
118void *node_remap_end_vaddr[MAX_NUMNODES]; 118void *node_remap_end_vaddr[MAX_NUMNODES];
119void *node_remap_alloc_vaddr[MAX_NUMNODES]; 119void *node_remap_alloc_vaddr[MAX_NUMNODES];
120 120static unsigned long kva_start_pfn;
121static unsigned long kva_pages;
121/* 122/*
122 * FLAT - support for basic PC memory model with discontig enabled, essentially 123 * FLAT - support for basic PC memory model with discontig enabled, essentially
123 * a single node with all available processors in it with a flat 124 * a single node with all available processors in it with a flat
@@ -156,21 +157,6 @@ static void __init find_max_pfn_node(int nid)
156 BUG(); 157 BUG();
157} 158}
158 159
159/* Find the owning node for a pfn. */
160int early_pfn_to_nid(unsigned long pfn)
161{
162 int nid;
163
164 for_each_node(nid) {
165 if (node_end_pfn[nid] == 0)
166 break;
167 if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
168 return nid;
169 }
170
171 return 0;
172}
173
174/* 160/*
175 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem 161 * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
176 * method. For node zero take this from the bottom of memory, for 162 * method. For node zero take this from the bottom of memory, for
@@ -226,6 +212,8 @@ static unsigned long calculate_numa_remap_pages(void)
226 unsigned long pfn; 212 unsigned long pfn;
227 213
228 for_each_online_node(nid) { 214 for_each_online_node(nid) {
215 unsigned old_end_pfn = node_end_pfn[nid];
216
229 /* 217 /*
230 * The acpi/srat node info can show hot-add memroy zones 218 * The acpi/srat node info can show hot-add memroy zones
231 * where memory could be added but not currently present. 219 * where memory could be added but not currently present.
@@ -275,6 +263,7 @@ static unsigned long calculate_numa_remap_pages(void)
275 263
276 node_end_pfn[nid] -= size; 264 node_end_pfn[nid] -= size;
277 node_remap_start_pfn[nid] = node_end_pfn[nid]; 265 node_remap_start_pfn[nid] = node_end_pfn[nid];
266 shrink_active_range(nid, old_end_pfn, node_end_pfn[nid]);
278 } 267 }
279 printk("Reserving total of %ld pages for numa KVA remap\n", 268 printk("Reserving total of %ld pages for numa KVA remap\n",
280 reserve_pages); 269 reserve_pages);
@@ -286,7 +275,6 @@ unsigned long __init setup_memory(void)
286{ 275{
287 int nid; 276 int nid;
288 unsigned long system_start_pfn, system_max_low_pfn; 277 unsigned long system_start_pfn, system_max_low_pfn;
289 unsigned long reserve_pages;
290 278
291 /* 279 /*
292 * When mapping a NUMA machine we allocate the node_mem_map arrays 280 * When mapping a NUMA machine we allocate the node_mem_map arrays
@@ -298,14 +286,23 @@ unsigned long __init setup_memory(void)
298 find_max_pfn(); 286 find_max_pfn();
299 get_memcfg_numa(); 287 get_memcfg_numa();
300 288
301 reserve_pages = calculate_numa_remap_pages(); 289 kva_pages = calculate_numa_remap_pages();
302 290
303 /* partially used pages are not usable - thus round upwards */ 291 /* partially used pages are not usable - thus round upwards */
304 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); 292 system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end);
305 293
306 system_max_low_pfn = max_low_pfn = find_max_low_pfn() - reserve_pages; 294 kva_start_pfn = find_max_low_pfn() - kva_pages;
307 printk("reserve_pages = %ld find_max_low_pfn() ~ %ld\n", 295
308 reserve_pages, max_low_pfn + reserve_pages); 296#ifdef CONFIG_BLK_DEV_INITRD
297 /* Numa kva area is below the initrd */
298 if (LOADER_TYPE && INITRD_START)
299 kva_start_pfn = PFN_DOWN(INITRD_START) - kva_pages;
300#endif
301 kva_start_pfn -= kva_start_pfn & (PTRS_PER_PTE-1);
302
303 system_max_low_pfn = max_low_pfn = find_max_low_pfn();
304 printk("kva_start_pfn ~ %ld find_max_low_pfn() ~ %ld\n",
305 kva_start_pfn, max_low_pfn);
309 printk("max_pfn = %ld\n", max_pfn); 306 printk("max_pfn = %ld\n", max_pfn);
310#ifdef CONFIG_HIGHMEM 307#ifdef CONFIG_HIGHMEM
311 highstart_pfn = highend_pfn = max_pfn; 308 highstart_pfn = highend_pfn = max_pfn;
@@ -313,6 +310,11 @@ unsigned long __init setup_memory(void)
313 highstart_pfn = system_max_low_pfn; 310 highstart_pfn = system_max_low_pfn;
314 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", 311 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
315 pages_to_mb(highend_pfn - highstart_pfn)); 312 pages_to_mb(highend_pfn - highstart_pfn));
313 num_physpages = highend_pfn;
314 high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
315#else
316 num_physpages = system_max_low_pfn;
317 high_memory = (void *) __va(system_max_low_pfn * PAGE_SIZE - 1) + 1;
316#endif 318#endif
317 printk(KERN_NOTICE "%ldMB LOWMEM available.\n", 319 printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
318 pages_to_mb(system_max_low_pfn)); 320 pages_to_mb(system_max_low_pfn));
@@ -323,7 +325,7 @@ unsigned long __init setup_memory(void)
323 (ulong) pfn_to_kaddr(max_low_pfn)); 325 (ulong) pfn_to_kaddr(max_low_pfn));
324 for_each_online_node(nid) { 326 for_each_online_node(nid) {
325 node_remap_start_vaddr[nid] = pfn_to_kaddr( 327 node_remap_start_vaddr[nid] = pfn_to_kaddr(
326 highstart_pfn + node_remap_offset[nid]); 328 kva_start_pfn + node_remap_offset[nid]);
327 /* Init the node remap allocator */ 329 /* Init the node remap allocator */
328 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] + 330 node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
329 (node_remap_size[nid] * PAGE_SIZE); 331 (node_remap_size[nid] * PAGE_SIZE);
@@ -338,7 +340,6 @@ unsigned long __init setup_memory(void)
338 } 340 }
339 printk("High memory starts at vaddr %08lx\n", 341 printk("High memory starts at vaddr %08lx\n",
340 (ulong) pfn_to_kaddr(highstart_pfn)); 342 (ulong) pfn_to_kaddr(highstart_pfn));
341 vmalloc_earlyreserve = reserve_pages * PAGE_SIZE;
342 for_each_online_node(nid) 343 for_each_online_node(nid)
343 find_max_pfn_node(nid); 344 find_max_pfn_node(nid);
344 345
@@ -348,48 +349,30 @@ unsigned long __init setup_memory(void)
348 return max_low_pfn; 349 return max_low_pfn;
349} 350}
350 351
352void __init numa_kva_reserve(void)
353{
354 reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages));
355}
356
351void __init zone_sizes_init(void) 357void __init zone_sizes_init(void)
352{ 358{
353 int nid; 359 int nid;
354 360 unsigned long max_zone_pfns[MAX_NR_ZONES] = {
355 361 virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
356 for_each_online_node(nid) { 362 max_low_pfn,
357 unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; 363 highend_pfn
358 unsigned long *zholes_size; 364 };
359 unsigned int max_dma; 365
360 366 /* If SRAT has not registered memory, register it now */
361 unsigned long low = max_low_pfn; 367 if (find_max_pfn_with_active_regions() == 0) {
362 unsigned long start = node_start_pfn[nid]; 368 for_each_online_node(nid) {
363 unsigned long high = node_end_pfn[nid]; 369 if (node_has_online_mem(nid))
364 370 add_active_range(nid, node_start_pfn[nid],
365 max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; 371 node_end_pfn[nid]);
366
367 if (node_has_online_mem(nid)){
368 if (start > low) {
369#ifdef CONFIG_HIGHMEM
370 BUG_ON(start > high);
371 zones_size[ZONE_HIGHMEM] = high - start;
372#endif
373 } else {
374 if (low < max_dma)
375 zones_size[ZONE_DMA] = low;
376 else {
377 BUG_ON(max_dma > low);
378 BUG_ON(low > high);
379 zones_size[ZONE_DMA] = max_dma;
380 zones_size[ZONE_NORMAL] = low - max_dma;
381#ifdef CONFIG_HIGHMEM
382 zones_size[ZONE_HIGHMEM] = high - low;
383#endif
384 }
385 }
386 } 372 }
387
388 zholes_size = get_zholes_size(nid);
389
390 free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
391 zholes_size);
392 } 373 }
374
375 free_area_init_nodes(max_zone_pfns);
393 return; 376 return;
394} 377}
395 378
@@ -409,7 +392,7 @@ void __init set_highmem_pages_init(int bad_ppro)
409 zone_end_pfn = zone_start_pfn + zone->spanned_pages; 392 zone_end_pfn = zone_start_pfn + zone->spanned_pages;
410 393
411 printk("Initializing %s for node %d (%08lx:%08lx)\n", 394 printk("Initializing %s for node %d (%08lx:%08lx)\n",
412 zone->name, zone->zone_pgdat->node_id, 395 zone->name, zone_to_nid(zone),
413 zone_start_pfn, zone_end_pfn); 396 zone_start_pfn, zone_end_pfn);
414 397
415 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { 398 for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) {