diff options
author | Tejun Heo <tj@kernel.org> | 2011-05-02 08:18:51 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-05-02 08:18:51 -0400 |
commit | acd26d611e60c1a7c2a14269ab99760f779121f4 (patch) | |
tree | 1ba64ef16bbf1f50226c9b48003743f0e8f141d0 /arch | |
parent | ebe685f24eeb85fbdb0f33792f1dabdbf35eff38 (diff) |
x86-64, NUMA: simplify nodedata allocation
With top-down memblock allocation, the allocation range limits in
ealry_node_mem() can be simplified - try node-local first, then any
node but in any case don't allocate below DMA limit.
Remove early_node_mem() and implement simplified allocation directly
in setup_node_bootmem().
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/mm/numa_64.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 8043d5e7f0d3..b4fd25e753cb 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c | |||
@@ -37,38 +37,6 @@ __initdata | |||
37 | static int numa_distance_cnt; | 37 | static int numa_distance_cnt; |
38 | static u8 *numa_distance; | 38 | static u8 *numa_distance; |
39 | 39 | ||
40 | static void * __init early_node_mem(int nodeid, unsigned long start, | ||
41 | unsigned long end, unsigned long size, | ||
42 | unsigned long align) | ||
43 | { | ||
44 | unsigned long mem; | ||
45 | |||
46 | /* | ||
47 | * put it on high as possible | ||
48 | * something will go with NODE_DATA | ||
49 | */ | ||
50 | if (start < (MAX_DMA_PFN<<PAGE_SHIFT)) | ||
51 | start = MAX_DMA_PFN<<PAGE_SHIFT; | ||
52 | if (start < (MAX_DMA32_PFN<<PAGE_SHIFT) && | ||
53 | end > (MAX_DMA32_PFN<<PAGE_SHIFT)) | ||
54 | start = MAX_DMA32_PFN<<PAGE_SHIFT; | ||
55 | mem = memblock_x86_find_in_range_node(nodeid, start, end, size, align); | ||
56 | if (mem != MEMBLOCK_ERROR) | ||
57 | return __va(mem); | ||
58 | |||
59 | /* extend the search scope */ | ||
60 | end = max_pfn_mapped << PAGE_SHIFT; | ||
61 | start = MAX_DMA_PFN << PAGE_SHIFT; | ||
62 | mem = memblock_find_in_range(start, end, size, align); | ||
63 | if (mem != MEMBLOCK_ERROR) | ||
64 | return __va(mem); | ||
65 | |||
66 | printk(KERN_ERR "Cannot find %lu bytes in node %d\n", | ||
67 | size, nodeid); | ||
68 | |||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | static int __init numa_add_memblk_to(int nid, u64 start, u64 end, | 40 | static int __init numa_add_memblk_to(int nid, u64 start, u64 end, |
73 | struct numa_meminfo *mi) | 41 | struct numa_meminfo *mi) |
74 | { | 42 | { |
@@ -130,6 +98,8 @@ int __init numa_add_memblk(int nid, u64 start, u64 end) | |||
130 | void __init | 98 | void __init |
131 | setup_node_bootmem(int nid, unsigned long start, unsigned long end) | 99 | setup_node_bootmem(int nid, unsigned long start, unsigned long end) |
132 | { | 100 | { |
101 | const u64 nd_low = (u64)MAX_DMA_PFN << PAGE_SHIFT; | ||
102 | const u64 nd_high = (u64)max_pfn_mapped << PAGE_SHIFT; | ||
133 | const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); | 103 | const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE); |
134 | unsigned long nd_pa; | 104 | unsigned long nd_pa; |
135 | int tnid; | 105 | int tnid; |
@@ -146,18 +116,29 @@ setup_node_bootmem(int nid, unsigned long start, unsigned long end) | |||
146 | printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n", | 116 | printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n", |
147 | nid, start, end); | 117 | nid, start, end); |
148 | 118 | ||
149 | node_data[nid] = early_node_mem(nid, start, end, nd_size, | 119 | /* |
150 | SMP_CACHE_BYTES); | 120 | * Try to allocate node data on local node and then fall back to |
151 | if (node_data[nid] == NULL) | 121 | * all nodes. Never allocate in DMA zone. |
122 | */ | ||
123 | nd_pa = memblock_x86_find_in_range_node(nid, nd_low, nd_high, | ||
124 | nd_size, SMP_CACHE_BYTES); | ||
125 | if (nd_pa == MEMBLOCK_ERROR) | ||
126 | nd_pa = memblock_find_in_range(nd_low, nd_high, | ||
127 | nd_size, SMP_CACHE_BYTES); | ||
128 | if (nd_pa == MEMBLOCK_ERROR) { | ||
129 | pr_err("Cannot find %lu bytes in node %d\n", nd_size, nid); | ||
152 | return; | 130 | return; |
153 | nd_pa = __pa(node_data[nid]); | 131 | } |
154 | memblock_x86_reserve_range(nd_pa, nd_pa + nd_size, "NODE_DATA"); | 132 | memblock_x86_reserve_range(nd_pa, nd_pa + nd_size, "NODE_DATA"); |
133 | |||
134 | /* report and initialize */ | ||
155 | printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n", | 135 | printk(KERN_INFO " NODE_DATA [%016lx - %016lx]\n", |
156 | nd_pa, nd_pa + nd_size - 1); | 136 | nd_pa, nd_pa + nd_size - 1); |
157 | tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); | 137 | tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); |
158 | if (tnid != nid) | 138 | if (tnid != nid) |
159 | printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid); | 139 | printk(KERN_INFO " NODE_DATA(%d) on node %d\n", nid, tnid); |
160 | 140 | ||
141 | node_data[nid] = __va(nd_pa); | ||
161 | memset(NODE_DATA(nid), 0, sizeof(pg_data_t)); | 142 | memset(NODE_DATA(nid), 0, sizeof(pg_data_t)); |
162 | NODE_DATA(nid)->node_id = nid; | 143 | NODE_DATA(nid)->node_id = nid; |
163 | NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT; | 144 | NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT; |