diff options
author | Matt Tolentino <metolent@snoqualmie.dp.intel.com> | 2005-06-23 03:08:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-23 12:45:07 -0400 |
commit | bbfceef47fb9467424113a004070bf37a806a97c (patch) | |
tree | 3c12cef85abaaa0ca42088fc7600ed687b74fb5e /arch | |
parent | 2b97690f4cd960779fb351b7cd9974390afabb36 (diff) |
[PATCH] add x86-64 specific support for sparsemem
This patch adds in the necessary support for sparsemem such that x86-64
kernels may use sparsemem as an alternative to discontigmem for NUMA
kernels. Note that this does no preclude one from continuing to build NUMA
kernels using discontigmem, but merely allows the option to build NUMA
kernels with sparsemem.
Interestingly, the use of sparsemem in lieu of discontigmem in NUMA kernels
results in reduced text size for otherwise equivalent kernels as shown in
the example builds below:
text data bss dec hex filename
2371036 765884 1237108 4374028 42be0c vmlinux.discontig
2366549 776484 1302772 4445805 43d66d vmlinux.sparse
Signed-off-by: Matt Tolentino <matthew.e.tolentino@intel.com>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/kernel/setup.c | 27 | ||||
-rw-r--r-- | arch/x86_64/mm/numa.c | 8 |
2 files changed, 25 insertions, 10 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index dd8419b37a7e..000015dd5a8b 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
41 | #include <linux/kallsyms.h> | 41 | #include <linux/kallsyms.h> |
42 | #include <linux/edd.h> | 42 | #include <linux/edd.h> |
43 | #include <linux/mmzone.h> | ||
44 | |||
43 | #include <asm/mtrr.h> | 45 | #include <asm/mtrr.h> |
44 | #include <asm/uaccess.h> | 46 | #include <asm/uaccess.h> |
45 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -378,16 +380,19 @@ static __init void parse_cmdline_early (char ** cmdline_p) | |||
378 | } | 380 | } |
379 | 381 | ||
380 | #ifndef CONFIG_NUMA | 382 | #ifndef CONFIG_NUMA |
381 | static void __init contig_initmem_init(void) | 383 | static void __init |
384 | contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) | ||
382 | { | 385 | { |
383 | unsigned long bootmap_size, bootmap; | 386 | unsigned long bootmap_size, bootmap; |
384 | bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; | 387 | |
385 | bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); | 388 | memory_present(0, start_pfn, end_pfn); |
386 | if (bootmap == -1L) | 389 | bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; |
387 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); | 390 | bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); |
388 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); | 391 | if (bootmap == -1L) |
389 | e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); | 392 | panic("Cannot find bootmem map of size %ld\n",bootmap_size); |
390 | reserve_bootmem(bootmap, bootmap_size); | 393 | bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); |
394 | e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); | ||
395 | reserve_bootmem(bootmap, bootmap_size); | ||
391 | } | 396 | } |
392 | #endif | 397 | #endif |
393 | 398 | ||
@@ -557,7 +562,7 @@ void __init setup_arch(char **cmdline_p) | |||
557 | #ifdef CONFIG_NUMA | 562 | #ifdef CONFIG_NUMA |
558 | numa_initmem_init(0, end_pfn); | 563 | numa_initmem_init(0, end_pfn); |
559 | #else | 564 | #else |
560 | contig_initmem_init(); | 565 | contig_initmem_init(0, end_pfn); |
561 | #endif | 566 | #endif |
562 | 567 | ||
563 | /* Reserve direct mapping */ | 568 | /* Reserve direct mapping */ |
@@ -618,6 +623,8 @@ void __init setup_arch(char **cmdline_p) | |||
618 | } | 623 | } |
619 | } | 624 | } |
620 | #endif | 625 | #endif |
626 | |||
627 | sparse_init(); | ||
621 | paging_init(); | 628 | paging_init(); |
622 | 629 | ||
623 | check_ioapic(); | 630 | check_ioapic(); |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index fd9f25d7a6c4..84cde796ecb1 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -66,6 +66,13 @@ int __init compute_hash_shift(struct node *nodes, int numnodes) | |||
66 | return -1; | 66 | return -1; |
67 | } | 67 | } |
68 | 68 | ||
69 | #ifdef CONFIG_SPARSEMEM | ||
70 | int early_pfn_to_nid(unsigned long pfn) | ||
71 | { | ||
72 | return phys_to_nid(pfn << PAGE_SHIFT); | ||
73 | } | ||
74 | #endif | ||
75 | |||
69 | /* Initialize bootmem allocator for a node */ | 76 | /* Initialize bootmem allocator for a node */ |
70 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) | 77 | void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long end) |
71 | { | 78 | { |
@@ -80,6 +87,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en | |||
80 | start_pfn = start >> PAGE_SHIFT; | 87 | start_pfn = start >> PAGE_SHIFT; |
81 | end_pfn = end >> PAGE_SHIFT; | 88 | end_pfn = end >> PAGE_SHIFT; |
82 | 89 | ||
90 | memory_present(nodeid, start_pfn, end_pfn); | ||
83 | nodedata_phys = find_e820_area(start, end, pgdat_size); | 91 | nodedata_phys = find_e820_area(start, end, pgdat_size); |
84 | if (nodedata_phys == -1L) | 92 | if (nodedata_phys == -1L) |
85 | panic("Cannot find memory pgdat in node %d\n", nodeid); | 93 | panic("Cannot find memory pgdat in node %d\n", nodeid); |