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 | 9688678a6670c7f0ae3872450a8047c0ad401efb (patch) | |
tree | 548c0c327ce26c1d508dce44d7167acf7b6df71a /arch/x86/mm/srat_64.c | |
parent | ba67cf5cf2ce10ad86a212b70f8c7c75d93a5016 (diff) |
x86-64, NUMA: Simplify hotadd memory handling
The only special handling NUMA needs to do for hotadd memory is
determining the node for the hotadd memory given the address of it and
there's nothing specific to specific config method used.
srat_64.c does somewhat elaborate error checking on
ACPI_SRAT_MEM_HOT_PLUGGABLE regions, remembers them and implements
memory_add_physaddr_to_nid() which determines the node for given
hotadd address.
This is almost completely redundant. All the information is already
available to the generic NUMA code which already performs all the
sanity checking and merging. All that's necessary is not using
__initdata from numa_meminfo and providing a function which uses it to
map address to node.
Drop the specific implementation from srat_64.c and add generic
memory_add_physaddr_to_nid() in numa_64.c, which is enabled if
CONFIG_MEMORY_HOTPLUG is set. Other than dropping the code, srat_64.c
doesn't need any change as it already calls numa_add_memblk() for hot
pluggable regions which is enough.
While at it, change CONFIG_MEMORY_HOTPLUG_SPARSE in srat_64.c to
CONFIG_MEMORY_HOTPLUG, for NUMA on x86-64, the two are always the
same.
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/x86/mm/srat_64.c')
-rw-r--r-- | arch/x86/mm/srat_64.c | 78 |
1 files changed, 1 insertions, 77 deletions
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 8e9d3394f6d4..9994d2cacf72 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | int acpi_numa __initdata; | 27 | int acpi_numa __initdata; |
28 | 28 | ||
29 | static struct bootnode nodes_add[MAX_NUMNODES]; | ||
30 | |||
31 | static __init int setup_node(int pxm) | 29 | static __init int setup_node(int pxm) |
32 | { | 30 | { |
33 | return acpi_map_pxm_to_node(pxm); | 31 | return acpi_map_pxm_to_node(pxm); |
@@ -37,7 +35,6 @@ static __init void bad_srat(void) | |||
37 | { | 35 | { |
38 | printk(KERN_ERR "SRAT: SRAT not used.\n"); | 36 | printk(KERN_ERR "SRAT: SRAT not used.\n"); |
39 | acpi_numa = -1; | 37 | acpi_numa = -1; |
40 | memset(nodes_add, 0, sizeof(nodes_add)); | ||
41 | } | 38 | } |
42 | 39 | ||
43 | static __init inline int srat_disabled(void) | 40 | static __init inline int srat_disabled(void) |
@@ -131,67 +128,11 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) | |||
131 | pxm, apic_id, node); | 128 | pxm, apic_id, node); |
132 | } | 129 | } |
133 | 130 | ||
134 | #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE | 131 | #ifdef CONFIG_MEMORY_HOTPLUG |
135 | static inline int save_add_info(void) {return 1;} | 132 | static inline int save_add_info(void) {return 1;} |
136 | #else | 133 | #else |
137 | static inline int save_add_info(void) {return 0;} | 134 | static inline int save_add_info(void) {return 0;} |
138 | #endif | 135 | #endif |
139 | /* | ||
140 | * Update nodes_add[] | ||
141 | * This code supports one contiguous hot add area per node | ||
142 | */ | ||
143 | static void __init | ||
144 | update_nodes_add(int node, unsigned long start, unsigned long end) | ||
145 | { | ||
146 | unsigned long s_pfn = start >> PAGE_SHIFT; | ||
147 | unsigned long e_pfn = end >> PAGE_SHIFT; | ||
148 | int changed = 0; | ||
149 | struct bootnode *nd = &nodes_add[node]; | ||
150 | |||
151 | /* I had some trouble with strange memory hotadd regions breaking | ||
152 | the boot. Be very strict here and reject anything unexpected. | ||
153 | If you want working memory hotadd write correct SRATs. | ||
154 | |||
155 | The node size check is a basic sanity check to guard against | ||
156 | mistakes */ | ||
157 | if ((signed long)(end - start) < NODE_MIN_SIZE) { | ||
158 | printk(KERN_ERR "SRAT: Hotplug area too small\n"); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | /* This check might be a bit too strict, but I'm keeping it for now. */ | ||
163 | if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) { | ||
164 | printk(KERN_ERR | ||
165 | "SRAT: Hotplug area %lu -> %lu has existing memory\n", | ||
166 | s_pfn, e_pfn); | ||
167 | return; | ||
168 | } | ||
169 | |||
170 | /* Looks good */ | ||
171 | |||
172 | if (nd->start == nd->end) { | ||
173 | nd->start = start; | ||
174 | nd->end = end; | ||
175 | changed = 1; | ||
176 | } else { | ||
177 | if (nd->start == end) { | ||
178 | nd->start = start; | ||
179 | changed = 1; | ||
180 | } | ||
181 | if (nd->end == start) { | ||
182 | nd->end = end; | ||
183 | changed = 1; | ||
184 | } | ||
185 | if (!changed) | ||
186 | printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); | ||
187 | } | ||
188 | |||
189 | if (changed) { | ||
190 | node_set(node, numa_nodes_parsed); | ||
191 | printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", | ||
192 | nd->start, nd->end); | ||
193 | } | ||
194 | } | ||
195 | 136 | ||
196 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 137 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
197 | void __init | 138 | void __init |
@@ -228,9 +169,6 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
228 | 169 | ||
229 | printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm, | 170 | printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm, |
230 | start, end); | 171 | start, end); |
231 | |||
232 | if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) | ||
233 | update_nodes_add(node, start, end); | ||
234 | } | 172 | } |
235 | 173 | ||
236 | void __init acpi_numa_arch_fixup(void) {} | 174 | void __init acpi_numa_arch_fixup(void) {} |
@@ -244,17 +182,3 @@ int __init x86_acpi_numa_init(void) | |||
244 | return ret; | 182 | return ret; |
245 | return srat_disabled() ? -EINVAL : 0; | 183 | return srat_disabled() ? -EINVAL : 0; |
246 | } | 184 | } |
247 | |||
248 | #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) | ||
249 | int memory_add_physaddr_to_nid(u64 start) | ||
250 | { | ||
251 | int i, ret = 0; | ||
252 | |||
253 | for_each_node(i) | ||
254 | if (nodes_add[i].start <= start && nodes_add[i].end > start) | ||
255 | ret = i; | ||
256 | |||
257 | return ret; | ||
258 | } | ||
259 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); | ||
260 | #endif | ||