diff options
Diffstat (limited to 'arch/i386/mm/discontig.c')
| -rw-r--r-- | arch/i386/mm/discontig.c | 105 |
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 | ||
| 118 | void *node_remap_end_vaddr[MAX_NUMNODES]; | 118 | void *node_remap_end_vaddr[MAX_NUMNODES]; |
| 119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; | 119 | void *node_remap_alloc_vaddr[MAX_NUMNODES]; |
| 120 | 120 | static unsigned long kva_start_pfn; | |
| 121 | static 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. */ | ||
| 160 | int 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 | ||
| 352 | void __init numa_kva_reserve(void) | ||
| 353 | { | ||
| 354 | reserve_bootmem(PFN_PHYS(kva_start_pfn),PFN_PHYS(kva_pages)); | ||
| 355 | } | ||
| 356 | |||
| 351 | void __init zone_sizes_init(void) | 357 | void __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++) { |
