diff options
author | Andy Whitcroft <apw@shadowen.org> | 2005-06-23 03:07:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-23 12:45:05 -0400 |
commit | 05b79bdcb48c18cd9b580c39e3efb9a1ab078151 (patch) | |
tree | 1767aaa7a4621ff4cf1a85c2078229de54272f30 /arch/i386 | |
parent | d41dee369bff3b9dcb6328d4d822926c28cc2594 (diff) |
[PATCH] sparsemem memory model for i386
Provide the architecture specific implementation for SPARSEMEM for i386 SMP
and NUMA systems.
Signed-off-by: Andy Whitcroft <apw@shadowen.org>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Martin Bligh <mbligh@aracnet.com>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/Kconfig | 24 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 8 | ||||
-rw-r--r-- | arch/i386/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/i386/mm/discontig.c | 36 | ||||
-rw-r--r-- | arch/i386/mm/init.c | 18 |
5 files changed, 52 insertions, 36 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f0064b5e3702..bfdcedef06e1 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -68,7 +68,6 @@ config X86_VOYAGER | |||
68 | 68 | ||
69 | config X86_NUMAQ | 69 | config X86_NUMAQ |
70 | bool "NUMAQ (IBM/Sequent)" | 70 | bool "NUMAQ (IBM/Sequent)" |
71 | select DISCONTIGMEM | ||
72 | select NUMA | 71 | select NUMA |
73 | help | 72 | help |
74 | This option is used for getting Linux to run on a (IBM/Sequent) NUMA | 73 | This option is used for getting Linux to run on a (IBM/Sequent) NUMA |
@@ -783,11 +782,6 @@ comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" | |||
783 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" | 782 | comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" |
784 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) | 783 | depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) |
785 | 784 | ||
786 | config ARCH_DISCONTIGMEM_ENABLE | ||
787 | bool | ||
788 | depends on NUMA | ||
789 | default y | ||
790 | |||
791 | config HAVE_ARCH_BOOTMEM_NODE | 785 | config HAVE_ARCH_BOOTMEM_NODE |
792 | bool | 786 | bool |
793 | depends on NUMA | 787 | depends on NUMA |
@@ -800,7 +794,7 @@ config ARCH_HAVE_MEMORY_PRESENT | |||
800 | 794 | ||
801 | config NEED_NODE_MEMMAP_SIZE | 795 | config NEED_NODE_MEMMAP_SIZE |
802 | bool | 796 | bool |
803 | depends on DISCONTIGMEM | 797 | depends on DISCONTIGMEM || SPARSEMEM |
804 | default y | 798 | default y |
805 | 799 | ||
806 | config HAVE_ARCH_ALLOC_REMAP | 800 | config HAVE_ARCH_ALLOC_REMAP |
@@ -808,6 +802,22 @@ config HAVE_ARCH_ALLOC_REMAP | |||
808 | depends on NUMA | 802 | depends on NUMA |
809 | default y | 803 | default y |
810 | 804 | ||
805 | config ARCH_DISCONTIGMEM_ENABLE | ||
806 | def_bool y | ||
807 | depends on NUMA | ||
808 | |||
809 | config ARCH_DISCONTIGMEM_DEFAULT | ||
810 | def_bool y | ||
811 | depends on NUMA | ||
812 | |||
813 | config ARCH_SPARSEMEM_ENABLE | ||
814 | def_bool y | ||
815 | depends on NUMA | ||
816 | |||
817 | config ARCH_SELECT_MEMORY_MODEL | ||
818 | def_bool y | ||
819 | depends on ARCH_SPARSEMEM_ENABLE | ||
820 | |||
811 | source "mm/Kconfig" | 821 | source "mm/Kconfig" |
812 | 822 | ||
813 | config HAVE_ARCH_EARLY_PFN_TO_NID | 823 | config HAVE_ARCH_EARLY_PFN_TO_NID |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 2bfbddebdbf8..0d689335c8d6 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/mmzone.h> | ||
28 | #include <linux/tty.h> | 29 | #include <linux/tty.h> |
29 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
30 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
@@ -1022,7 +1023,7 @@ static void __init reserve_ebda_region(void) | |||
1022 | reserve_bootmem(addr, PAGE_SIZE); | 1023 | reserve_bootmem(addr, PAGE_SIZE); |
1023 | } | 1024 | } |
1024 | 1025 | ||
1025 | #ifndef CONFIG_DISCONTIGMEM | 1026 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
1026 | void __init setup_bootmem_allocator(void); | 1027 | void __init setup_bootmem_allocator(void); |
1027 | static unsigned long __init setup_memory(void) | 1028 | static unsigned long __init setup_memory(void) |
1028 | { | 1029 | { |
@@ -1072,9 +1073,9 @@ void __init zone_sizes_init(void) | |||
1072 | free_area_init(zones_size); | 1073 | free_area_init(zones_size); |
1073 | } | 1074 | } |
1074 | #else | 1075 | #else |
1075 | extern unsigned long setup_memory(void); | 1076 | extern unsigned long __init setup_memory(void); |
1076 | extern void zone_sizes_init(void); | 1077 | extern void zone_sizes_init(void); |
1077 | #endif /* !CONFIG_DISCONTIGMEM */ | 1078 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
1078 | 1079 | ||
1079 | void __init setup_bootmem_allocator(void) | 1080 | void __init setup_bootmem_allocator(void) |
1080 | { | 1081 | { |
@@ -1475,6 +1476,7 @@ void __init setup_arch(char **cmdline_p) | |||
1475 | #endif | 1476 | #endif |
1476 | paging_init(); | 1477 | paging_init(); |
1477 | remapped_pgdat_init(); | 1478 | remapped_pgdat_init(); |
1479 | sparse_init(); | ||
1478 | zone_sizes_init(); | 1480 | zone_sizes_init(); |
1479 | 1481 | ||
1480 | /* | 1482 | /* |
diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile index fc3272506846..80908b5aa60f 100644 --- a/arch/i386/mm/Makefile +++ b/arch/i386/mm/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o | 5 | obj-y := init.o pgtable.o fault.o ioremap.o extable.o pageattr.o mmap.o |
6 | 6 | ||
7 | obj-$(CONFIG_DISCONTIGMEM) += discontig.o | 7 | obj-$(CONFIG_NUMA) += discontig.o |
8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
9 | obj-$(CONFIG_HIGHMEM) += highmem.o | 9 | obj-$(CONFIG_HIGHMEM) += highmem.o |
10 | obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o | 10 | obj-$(CONFIG_BOOT_IOREMAP) += boot_ioremap.o |
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index 088ca4722183..0efeb96ba5d4 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c | |||
@@ -42,12 +42,16 @@ bootmem_data_t node0_bdata; | |||
42 | * populated the following initialisation. | 42 | * populated the following initialisation. |
43 | * | 43 | * |
44 | * 1) node_online_map - the map of all nodes configured (online) in the system | 44 | * 1) node_online_map - the map of all nodes configured (online) in the system |
45 | * 2) physnode_map - the mapping between a pfn and owning node | 45 | * 2) node_start_pfn - the starting page frame number for a node |
46 | * 3) node_start_pfn - the starting page frame number for a node | ||
47 | * 3) node_end_pfn - the ending page fram number for a node | 46 | * 3) node_end_pfn - the ending page fram number for a node |
48 | */ | 47 | */ |
48 | unsigned long node_start_pfn[MAX_NUMNODES]; | ||
49 | unsigned long node_end_pfn[MAX_NUMNODES]; | ||
50 | |||
49 | 51 | ||
52 | #ifdef CONFIG_DISCONTIGMEM | ||
50 | /* | 53 | /* |
54 | * 4) physnode_map - the mapping between a pfn and owning node | ||
51 | * physnode_map keeps track of the physical memory layout of a generic | 55 | * physnode_map keeps track of the physical memory layout of a generic |
52 | * numa node on a 256Mb break (each element of the array will | 56 | * numa node on a 256Mb break (each element of the array will |
53 | * represent 256Mb of memory and will be marked by the node id. so, | 57 | * represent 256Mb of memory and will be marked by the node id. so, |
@@ -85,9 +89,7 @@ unsigned long node_memmap_size_bytes(int nid, unsigned long start_pfn, | |||
85 | 89 | ||
86 | return (nr_pages + 1) * sizeof(struct page); | 90 | return (nr_pages + 1) * sizeof(struct page); |
87 | } | 91 | } |
88 | 92 | #endif | |
89 | unsigned long node_start_pfn[MAX_NUMNODES]; | ||
90 | unsigned long node_end_pfn[MAX_NUMNODES]; | ||
91 | 93 | ||
92 | extern unsigned long find_max_low_pfn(void); | 94 | extern unsigned long find_max_low_pfn(void); |
93 | extern void find_max_pfn(void); | 95 | extern void find_max_pfn(void); |
@@ -390,24 +392,26 @@ void __init set_highmem_pages_init(int bad_ppro) | |||
390 | { | 392 | { |
391 | #ifdef CONFIG_HIGHMEM | 393 | #ifdef CONFIG_HIGHMEM |
392 | struct zone *zone; | 394 | struct zone *zone; |
395 | struct page *page; | ||
393 | 396 | ||
394 | for_each_zone(zone) { | 397 | for_each_zone(zone) { |
395 | unsigned long node_pfn, node_high_size, zone_start_pfn; | 398 | unsigned long node_pfn, zone_start_pfn, zone_end_pfn; |
396 | struct page * zone_mem_map; | 399 | |
397 | |||
398 | if (!is_highmem(zone)) | 400 | if (!is_highmem(zone)) |
399 | continue; | 401 | continue; |
400 | 402 | ||
401 | printk("Initializing %s for node %d\n", zone->name, | ||
402 | zone->zone_pgdat->node_id); | ||
403 | |||
404 | node_high_size = zone->spanned_pages; | ||
405 | zone_mem_map = zone->zone_mem_map; | ||
406 | zone_start_pfn = zone->zone_start_pfn; | 403 | zone_start_pfn = zone->zone_start_pfn; |
404 | zone_end_pfn = zone_start_pfn + zone->spanned_pages; | ||
405 | |||
406 | printk("Initializing %s for node %d (%08lx:%08lx)\n", | ||
407 | zone->name, zone->zone_pgdat->node_id, | ||
408 | zone_start_pfn, zone_end_pfn); | ||
407 | 409 | ||
408 | for (node_pfn = 0; node_pfn < node_high_size; node_pfn++) { | 410 | for (node_pfn = zone_start_pfn; node_pfn < zone_end_pfn; node_pfn++) { |
409 | one_highpage_init((struct page *)(zone_mem_map + node_pfn), | 411 | if (!pfn_valid(node_pfn)) |
410 | zone_start_pfn + node_pfn, bad_ppro); | 412 | continue; |
413 | page = pfn_to_page(node_pfn); | ||
414 | one_highpage_init(page, node_pfn, bad_ppro); | ||
411 | } | 415 | } |
412 | } | 416 | } |
413 | totalram_pages += totalhigh_pages; | 417 | totalram_pages += totalhigh_pages; |
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 666ca79fb50a..48ebfab77a3c 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c | |||
@@ -276,7 +276,9 @@ void __init one_highpage_init(struct page *page, int pfn, int bad_ppro) | |||
276 | SetPageReserved(page); | 276 | SetPageReserved(page); |
277 | } | 277 | } |
278 | 278 | ||
279 | #ifndef CONFIG_DISCONTIGMEM | 279 | #ifdef CONFIG_NUMA |
280 | extern void set_highmem_pages_init(int); | ||
281 | #else | ||
280 | static void __init set_highmem_pages_init(int bad_ppro) | 282 | static void __init set_highmem_pages_init(int bad_ppro) |
281 | { | 283 | { |
282 | int pfn; | 284 | int pfn; |
@@ -284,9 +286,7 @@ static void __init set_highmem_pages_init(int bad_ppro) | |||
284 | one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); | 286 | one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro); |
285 | totalram_pages += totalhigh_pages; | 287 | totalram_pages += totalhigh_pages; |
286 | } | 288 | } |
287 | #else | 289 | #endif /* CONFIG_FLATMEM */ |
288 | extern void set_highmem_pages_init(int); | ||
289 | #endif /* !CONFIG_DISCONTIGMEM */ | ||
290 | 290 | ||
291 | #else | 291 | #else |
292 | #define kmap_init() do { } while (0) | 292 | #define kmap_init() do { } while (0) |
@@ -297,10 +297,10 @@ extern void set_highmem_pages_init(int); | |||
297 | unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; | 297 | unsigned long long __PAGE_KERNEL = _PAGE_KERNEL; |
298 | unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; | 298 | unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC; |
299 | 299 | ||
300 | #ifndef CONFIG_DISCONTIGMEM | 300 | #ifdef CONFIG_NUMA |
301 | #define remap_numa_kva() do {} while (0) | ||
302 | #else | ||
303 | extern void __init remap_numa_kva(void); | 301 | extern void __init remap_numa_kva(void); |
302 | #else | ||
303 | #define remap_numa_kva() do {} while (0) | ||
304 | #endif | 304 | #endif |
305 | 305 | ||
306 | static void __init pagetable_init (void) | 306 | static void __init pagetable_init (void) |
@@ -525,7 +525,7 @@ static void __init set_max_mapnr_init(void) | |||
525 | #else | 525 | #else |
526 | num_physpages = max_low_pfn; | 526 | num_physpages = max_low_pfn; |
527 | #endif | 527 | #endif |
528 | #ifndef CONFIG_DISCONTIGMEM | 528 | #ifdef CONFIG_FLATMEM |
529 | max_mapnr = num_physpages; | 529 | max_mapnr = num_physpages; |
530 | #endif | 530 | #endif |
531 | } | 531 | } |
@@ -539,7 +539,7 @@ void __init mem_init(void) | |||
539 | int tmp; | 539 | int tmp; |
540 | int bad_ppro; | 540 | int bad_ppro; |
541 | 541 | ||
542 | #ifndef CONFIG_DISCONTIGMEM | 542 | #ifdef CONFIG_FLATMEM |
543 | if (!mem_map) | 543 | if (!mem_map) |
544 | BUG(); | 544 | BUG(); |
545 | #endif | 545 | #endif |