diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-07-03 18:34:51 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-07-04 11:32:11 -0400 |
commit | 5084f61a4d6c9c7bfd3be07fbb5253c1a08cd568 (patch) | |
tree | ac18e1e7686c6296db2ceb85463f49497ab3f442 /arch/sh/mm/numa.c | |
parent | c601a51af10f714292f42eab45fa8c9154dc1414 (diff) |
sh: Use bootmem ontop of lmb for NUMA
Like the UP case, use lmb as the foundation of memory resource
management on NUMA.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/numa.c')
-rw-r--r-- | arch/sh/mm/numa.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c index 095d93bec7cd..9b784fdb947c 100644 --- a/arch/sh/mm/numa.c +++ b/arch/sh/mm/numa.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/bootmem.h> | 11 | #include <linux/bootmem.h> |
12 | #include <linux/lmb.h> | ||
12 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
13 | #include <linux/numa.h> | 14 | #include <linux/numa.h> |
14 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
@@ -26,6 +27,15 @@ EXPORT_SYMBOL_GPL(node_data); | |||
26 | void __init setup_memory(void) | 27 | void __init setup_memory(void) |
27 | { | 28 | { |
28 | unsigned long free_pfn = PFN_UP(__pa(_end)); | 29 | unsigned long free_pfn = PFN_UP(__pa(_end)); |
30 | u64 base = min_low_pfn << PAGE_SHIFT; | ||
31 | u64 size = (max_low_pfn << PAGE_SHIFT) - min_low_pfn; | ||
32 | |||
33 | lmb_add(base, size); | ||
34 | |||
35 | /* Reserve the LMB regions used by the kernel, initrd, etc.. */ | ||
36 | lmb_reserve(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET, | ||
37 | (PFN_PHYS(free_pfn) + PAGE_SIZE - 1) - | ||
38 | (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET)); | ||
29 | 39 | ||
30 | /* | 40 | /* |
31 | * Node 0 sets up its pgdat at the first available pfn, | 41 | * Node 0 sets up its pgdat at the first available pfn, |
@@ -45,24 +55,23 @@ void __init setup_memory(void) | |||
45 | 55 | ||
46 | void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) | 56 | void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) |
47 | { | 57 | { |
48 | unsigned long bootmap_pages, bootmap_start, bootmap_size; | 58 | unsigned long bootmap_pages; |
49 | unsigned long start_pfn, free_pfn, end_pfn; | 59 | unsigned long start_pfn, end_pfn; |
60 | unsigned long bootmem_paddr; | ||
50 | 61 | ||
51 | /* Don't allow bogus node assignment */ | 62 | /* Don't allow bogus node assignment */ |
52 | BUG_ON(nid > MAX_NUMNODES || nid == 0); | 63 | BUG_ON(nid > MAX_NUMNODES || nid == 0); |
53 | 64 | ||
54 | /* | 65 | start_pfn = start >> PAGE_SHIFT; |
55 | * The free pfn starts at the beginning of the range, and is | ||
56 | * advanced as necessary for pgdat and node map allocations. | ||
57 | */ | ||
58 | free_pfn = start_pfn = start >> PAGE_SHIFT; | ||
59 | end_pfn = end >> PAGE_SHIFT; | 66 | end_pfn = end >> PAGE_SHIFT; |
60 | 67 | ||
68 | lmb_add(start, end - start); | ||
69 | |||
61 | __add_active_range(nid, start_pfn, end_pfn); | 70 | __add_active_range(nid, start_pfn, end_pfn); |
62 | 71 | ||
63 | /* Node-local pgdat */ | 72 | /* Node-local pgdat */ |
64 | NODE_DATA(nid) = pfn_to_kaddr(free_pfn); | 73 | NODE_DATA(nid) = __va(lmb_alloc_base(sizeof(struct pglist_data), |
65 | free_pfn += PFN_UP(sizeof(struct pglist_data)); | 74 | SMP_CACHE_BYTES, end_pfn)); |
66 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); | 75 | memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); |
67 | 76 | ||
68 | NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; | 77 | NODE_DATA(nid)->bdata = &bootmem_node_data[nid]; |
@@ -71,16 +80,17 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end) | |||
71 | 80 | ||
72 | /* Node-local bootmap */ | 81 | /* Node-local bootmap */ |
73 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); | 82 | bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); |
74 | bootmap_start = (unsigned long)pfn_to_kaddr(free_pfn); | 83 | bootmem_paddr = lmb_alloc_base(bootmap_pages << PAGE_SHIFT, |
75 | bootmap_size = init_bootmem_node(NODE_DATA(nid), free_pfn, start_pfn, | 84 | PAGE_SIZE, end_pfn); |
76 | end_pfn); | 85 | init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, |
86 | start_pfn, end_pfn); | ||
77 | 87 | ||
78 | free_bootmem_with_active_regions(nid, end_pfn); | 88 | free_bootmem_with_active_regions(nid, end_pfn); |
79 | 89 | ||
80 | /* Reserve the pgdat and bootmap space with the bootmem allocator */ | 90 | /* Reserve the pgdat and bootmap space with the bootmem allocator */ |
81 | reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT, | 91 | reserve_bootmem_node(NODE_DATA(nid), start_pfn << PAGE_SHIFT, |
82 | sizeof(struct pglist_data), BOOTMEM_DEFAULT); | 92 | sizeof(struct pglist_data), BOOTMEM_DEFAULT); |
83 | reserve_bootmem_node(NODE_DATA(nid), free_pfn << PAGE_SHIFT, | 93 | reserve_bootmem_node(NODE_DATA(nid), bootmem_paddr, |
84 | bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); | 94 | bootmap_pages << PAGE_SHIFT, BOOTMEM_DEFAULT); |
85 | 95 | ||
86 | /* It's up */ | 96 | /* It's up */ |