diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-06-03 22:35:04 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-04 06:01:58 -0400 |
commit | 7b2a0a6c4866cac146dcb0433e6984eb19a81335 (patch) | |
tree | d498d35f1281894fddbf39dcfd5c8d848ab87bb9 | |
parent | ee0c80fadfa56bf4f9d90c1c023429a6bd8edd69 (diff) |
x86: make 32-bit use e820_register_active_regions()
this way 32-bit is more similar to 64-bit, and smarter e820 and numa.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/kernel/e820_32.c | 68 | ||||
-rw-r--r-- | arch/x86/kernel/numaq_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/srat_32.c | 4 | ||||
-rw-r--r-- | arch/x86/mm/discontig_32.c | 19 | ||||
-rw-r--r-- | include/asm-x86/e820_32.h | 2 |
6 files changed, 33 insertions, 87 deletions
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c index 0c025d04fc2e..e8a3b968c9fa 100644 --- a/arch/x86/kernel/e820_32.c +++ b/arch/x86/kernel/e820_32.c | |||
@@ -207,69 +207,6 @@ void __init init_iomem_resources(struct resource *code_resource, | |||
207 | } | 207 | } |
208 | } | 208 | } |
209 | 209 | ||
210 | /* | ||
211 | * Find the highest page frame number we have available | ||
212 | */ | ||
213 | void __init find_max_pfn(void) | ||
214 | { | ||
215 | int i; | ||
216 | |||
217 | max_pfn = 0; | ||
218 | |||
219 | for (i = 0; i < e820.nr_map; i++) { | ||
220 | unsigned long start, end; | ||
221 | /* RAM? */ | ||
222 | if (e820.map[i].type != E820_RAM) | ||
223 | continue; | ||
224 | start = PFN_UP(e820.map[i].addr); | ||
225 | end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); | ||
226 | if (start >= end) | ||
227 | continue; | ||
228 | if (end > max_pfn) | ||
229 | max_pfn = end; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Register fully available low RAM pages with the bootmem allocator. | ||
235 | */ | ||
236 | void __init register_bootmem_low_pages(unsigned long max_low_pfn) | ||
237 | { | ||
238 | int i; | ||
239 | |||
240 | for (i = 0; i < e820.nr_map; i++) { | ||
241 | unsigned long curr_pfn, last_pfn, size; | ||
242 | /* | ||
243 | * Reserve usable low memory | ||
244 | */ | ||
245 | if (e820.map[i].type != E820_RAM) | ||
246 | continue; | ||
247 | /* | ||
248 | * We are rounding up the start address of usable memory: | ||
249 | */ | ||
250 | curr_pfn = PFN_UP(e820.map[i].addr); | ||
251 | if (curr_pfn >= max_low_pfn) | ||
252 | continue; | ||
253 | /* | ||
254 | * ... and at the end of the usable range downwards: | ||
255 | */ | ||
256 | last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); | ||
257 | |||
258 | if (last_pfn > max_low_pfn) | ||
259 | last_pfn = max_low_pfn; | ||
260 | |||
261 | /* | ||
262 | * .. finally, did all the rounding and playing | ||
263 | * around just make the area go away? | ||
264 | */ | ||
265 | if (last_pfn <= curr_pfn) | ||
266 | continue; | ||
267 | |||
268 | size = last_pfn - curr_pfn; | ||
269 | free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | void __init limit_regions(unsigned long long size) | 210 | void __init limit_regions(unsigned long long size) |
274 | { | 211 | { |
275 | unsigned long long current_addr; | 212 | unsigned long long current_addr; |
@@ -360,8 +297,9 @@ static int __init parse_memmap(char *arg) | |||
360 | * size before original memory map is | 297 | * size before original memory map is |
361 | * reset. | 298 | * reset. |
362 | */ | 299 | */ |
363 | find_max_pfn(); | 300 | e820_register_active_regions(0, 0, -1UL); |
364 | saved_max_pfn = max_pfn; | 301 | saved_max_pfn = e820_end_of_ram(); |
302 | remove_all_active_ranges(); | ||
365 | #endif | 303 | #endif |
366 | e820.nr_map = 0; | 304 | e820.nr_map = 0; |
367 | user_defined_memmap = 1; | 305 | user_defined_memmap = 1; |
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c index 922be66668b8..27b908254fb0 100644 --- a/arch/x86/kernel/numaq_32.c +++ b/arch/x86/kernel/numaq_32.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/topology.h> | 32 | #include <asm/topology.h> |
33 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
34 | #include <asm/mpspec.h> | 34 | #include <asm/mpspec.h> |
35 | #include <asm/e820.h> | ||
35 | 36 | ||
36 | #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) | 37 | #define MB_TO_PAGES(addr) ((addr) << (20 - PAGE_SHIFT)) |
37 | 38 | ||
@@ -61,6 +62,8 @@ static void __init smp_dump_qct(void) | |||
61 | node_end_pfn[node] = MB_TO_PAGES( | 62 | node_end_pfn[node] = MB_TO_PAGES( |
62 | eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); | 63 | eq->hi_shrd_mem_start + eq->hi_shrd_mem_size); |
63 | 64 | ||
65 | e820_register_active_regions(node, node_start_pfn[node], | ||
66 | node_end_pfn[node]); | ||
64 | memory_present(node, | 67 | memory_present(node, |
65 | node_start_pfn[node], node_end_pfn[node]); | 68 | node_start_pfn[node], node_end_pfn[node]); |
66 | node_remap_size[node] = node_memmap_size_bytes(node, | 69 | node_remap_size[node] = node_memmap_size_bytes(node, |
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index ccf3595202fa..0ec6480aaa27 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -405,11 +405,12 @@ static void __init zone_sizes_init(void) | |||
405 | max_zone_pfns[ZONE_DMA] = | 405 | max_zone_pfns[ZONE_DMA] = |
406 | virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 406 | virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
407 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; | 407 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; |
408 | remove_all_active_ranges(); | ||
408 | #ifdef CONFIG_HIGHMEM | 409 | #ifdef CONFIG_HIGHMEM |
409 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; | 410 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; |
410 | add_active_range(0, 0, highend_pfn); | 411 | e820_register_active_regions(0, 0, highend_pfn); |
411 | #else | 412 | #else |
412 | add_active_range(0, 0, max_low_pfn); | 413 | e820_register_active_regions(0, 0, max_low_pfn); |
413 | #endif | 414 | #endif |
414 | 415 | ||
415 | free_area_init_nodes(max_zone_pfns); | 416 | free_area_init_nodes(max_zone_pfns); |
@@ -582,6 +583,7 @@ static void __init relocate_initrd(void) | |||
582 | 583 | ||
583 | void __init setup_bootmem_allocator(void) | 584 | void __init setup_bootmem_allocator(void) |
584 | { | 585 | { |
586 | int i; | ||
585 | unsigned long bootmap_size, bootmap; | 587 | unsigned long bootmap_size, bootmap; |
586 | /* | 588 | /* |
587 | * Initialize the boot-time allocator (with low memory only): | 589 | * Initialize the boot-time allocator (with low memory only): |
@@ -603,7 +605,8 @@ void __init setup_bootmem_allocator(void) | |||
603 | min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); | 605 | min_low_pfn<<PAGE_SHIFT, max_low_pfn<<PAGE_SHIFT); |
604 | printk(KERN_INFO " bootmap %08lx - %08lx\n", | 606 | printk(KERN_INFO " bootmap %08lx - %08lx\n", |
605 | bootmap, bootmap + bootmap_size); | 607 | bootmap, bootmap + bootmap_size); |
606 | register_bootmem_low_pages(max_low_pfn); | 608 | for_each_online_node(i) |
609 | free_bootmem_with_active_regions(i, max_low_pfn); | ||
607 | early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); | 610 | early_res_to_bootmem(0, max_low_pfn<<PAGE_SHIFT); |
608 | 611 | ||
609 | #ifdef CONFIG_ACPI_SLEEP | 612 | #ifdef CONFIG_ACPI_SLEEP |
@@ -733,11 +736,20 @@ void __init setup_arch(char **cmdline_p) | |||
733 | if (efi_enabled) | 736 | if (efi_enabled) |
734 | efi_init(); | 737 | efi_init(); |
735 | 738 | ||
739 | e820_register_active_regions(0, 0, -1UL); | ||
740 | /* | ||
741 | * partially used pages are not usable - thus | ||
742 | * we are rounding upwards: | ||
743 | */ | ||
744 | max_pfn = e820_end_of_ram(); | ||
745 | |||
736 | /* update e820 for memory not covered by WB MTRRs */ | 746 | /* update e820 for memory not covered by WB MTRRs */ |
737 | find_max_pfn(); | ||
738 | mtrr_bp_init(); | 747 | mtrr_bp_init(); |
739 | if (mtrr_trim_uncached_memory(max_pfn)) | 748 | if (mtrr_trim_uncached_memory(max_pfn)) { |
740 | find_max_pfn(); | 749 | remove_all_active_ranges(); |
750 | e820_register_active_regions(0, 0, -1UL); | ||
751 | max_pfn = e820_end_of_ram(); | ||
752 | } | ||
741 | 753 | ||
742 | max_low_pfn = setup_memory(); | 754 | max_low_pfn = setup_memory(); |
743 | 755 | ||
diff --git a/arch/x86/kernel/srat_32.c b/arch/x86/kernel/srat_32.c index 88971ee166d4..32d8b1142938 100644 --- a/arch/x86/kernel/srat_32.c +++ b/arch/x86/kernel/srat_32.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/srat.h> | 31 | #include <asm/srat.h> |
32 | #include <asm/topology.h> | 32 | #include <asm/topology.h> |
33 | #include <asm/smp.h> | 33 | #include <asm/smp.h> |
34 | #include <asm/e820.h> | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * proximity macros and definitions | 37 | * proximity macros and definitions |
@@ -244,7 +245,8 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) | |||
244 | printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", | 245 | printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", |
245 | j, chunk->nid, chunk->start_pfn, chunk->end_pfn); | 246 | j, chunk->nid, chunk->start_pfn, chunk->end_pfn); |
246 | node_read_chunk(chunk->nid, chunk); | 247 | node_read_chunk(chunk->nid, chunk); |
247 | add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn); | 248 | e820_register_active_regions(chunk->nid, chunk->start_pfn, |
249 | min(chunk->end_pfn, max_pfn)); | ||
248 | } | 250 | } |
249 | 251 | ||
250 | for_each_online_node(nid) { | 252 | for_each_online_node(nid) { |
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c index 7ced26ab9aec..a89ccf3d4c14 100644 --- a/arch/x86/mm/discontig_32.c +++ b/arch/x86/mm/discontig_32.c | |||
@@ -120,10 +120,9 @@ int __init get_memcfg_numa_flat(void) | |||
120 | { | 120 | { |
121 | printk("NUMA - single node, flat memory mode\n"); | 121 | printk("NUMA - single node, flat memory mode\n"); |
122 | 122 | ||
123 | /* Run the memory configuration and find the top of memory. */ | ||
124 | find_max_pfn(); | ||
125 | node_start_pfn[0] = 0; | 123 | node_start_pfn[0] = 0; |
126 | node_end_pfn[0] = max_pfn; | 124 | node_end_pfn[0] = max_pfn; |
125 | e820_register_active_regions(0, 0, max_pfn); | ||
127 | memory_present(0, 0, max_pfn); | 126 | memory_present(0, 0, max_pfn); |
128 | node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn); | 127 | node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn); |
129 | 128 | ||
@@ -337,6 +336,11 @@ unsigned long __init setup_memory(void) | |||
337 | * this space and use it to adjust the boundary between ZONE_NORMAL | 336 | * this space and use it to adjust the boundary between ZONE_NORMAL |
338 | * and ZONE_HIGHMEM. | 337 | * and ZONE_HIGHMEM. |
339 | */ | 338 | */ |
339 | |||
340 | /* call find_max_low_pfn at first, it could update max_pfn */ | ||
341 | system_max_low_pfn = max_low_pfn = find_max_low_pfn(); | ||
342 | |||
343 | remove_all_active_ranges(); | ||
340 | get_memcfg_numa(); | 344 | get_memcfg_numa(); |
341 | 345 | ||
342 | kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE); | 346 | kva_pages = round_up(calculate_numa_remap_pages(), PTRS_PER_PTE); |
@@ -344,7 +348,6 @@ unsigned long __init setup_memory(void) | |||
344 | /* partially used pages are not usable - thus round upwards */ | 348 | /* partially used pages are not usable - thus round upwards */ |
345 | system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); | 349 | system_start_pfn = min_low_pfn = PFN_UP(init_pg_tables_end); |
346 | 350 | ||
347 | system_max_low_pfn = max_low_pfn = find_max_low_pfn(); | ||
348 | kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE); | 351 | kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE); |
349 | do { | 352 | do { |
350 | kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT, | 353 | kva_start_pfn = find_e820_area(kva_target_pfn<<PAGE_SHIFT, |
@@ -402,7 +405,6 @@ unsigned long __init setup_memory(void) | |||
402 | 405 | ||
403 | void __init zone_sizes_init(void) | 406 | void __init zone_sizes_init(void) |
404 | { | 407 | { |
405 | int nid; | ||
406 | unsigned long max_zone_pfns[MAX_NR_ZONES]; | 408 | unsigned long max_zone_pfns[MAX_NR_ZONES]; |
407 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); | 409 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
408 | max_zone_pfns[ZONE_DMA] = | 410 | max_zone_pfns[ZONE_DMA] = |
@@ -412,15 +414,6 @@ void __init zone_sizes_init(void) | |||
412 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; | 414 | max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; |
413 | #endif | 415 | #endif |
414 | 416 | ||
415 | /* If SRAT has not registered memory, register it now */ | ||
416 | if (find_max_pfn_with_active_regions() == 0) { | ||
417 | for_each_online_node(nid) { | ||
418 | if (node_has_online_mem(nid)) | ||
419 | add_active_range(nid, node_start_pfn[nid], | ||
420 | node_end_pfn[nid]); | ||
421 | } | ||
422 | } | ||
423 | |||
424 | free_area_init_nodes(max_zone_pfns); | 417 | free_area_init_nodes(max_zone_pfns); |
425 | return; | 418 | return; |
426 | } | 419 | } |
diff --git a/include/asm-x86/e820_32.h b/include/asm-x86/e820_32.h index 00fbc60b9d30..212b74c10efc 100644 --- a/include/asm-x86/e820_32.h +++ b/include/asm-x86/e820_32.h | |||
@@ -21,8 +21,6 @@ | |||
21 | extern void setup_memory_map(void); | 21 | extern void setup_memory_map(void); |
22 | extern void finish_e820_parsing(void); | 22 | extern void finish_e820_parsing(void); |
23 | 23 | ||
24 | extern void find_max_pfn(void); | ||
25 | extern void register_bootmem_low_pages(unsigned long max_low_pfn); | ||
26 | extern void limit_regions(unsigned long long size); | 24 | extern void limit_regions(unsigned long long size); |
27 | extern void init_iomem_resources(struct resource *code_resource, | 25 | extern void init_iomem_resources(struct resource *code_resource, |
28 | struct resource *data_resource, | 26 | struct resource *data_resource, |