diff options
author | Tejun Heo <tj@kernel.org> | 2011-02-16 11:11:09 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2011-02-16 11:11:09 -0500 |
commit | ac7136b611ee8f8bd6231ce2e1dbdd31ae3d39bc (patch) | |
tree | 41f6809ba694a723b521573c2e8d34c652c31281 /arch/x86/mm/srat_64.c | |
parent | 4697bdcc945c094d2c8a4876a24faeaf31a283e0 (diff) |
x86-64, NUMA: Implement generic node distance handling
Node distance either used direct node comparison, ACPI PXM comparison
or ACPI SLIT table lookup. This patch implements generic node
distance handling. NUMA init methods can call numa_set_distance() to
set distance between nodes and the common __node_distance()
implementation will report the set distance.
Due to the way NUMA emulation is implemented, the generic node
distance handling is used only when emulation is not used. Later
patches will update NUMA emulation to use the generic distance
mechanism.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Shaohui Zheng <shaohui.zheng@intel.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/mm/srat_64.c')
-rw-r--r-- | arch/x86/mm/srat_64.c | 27 |
1 files changed, 11 insertions, 16 deletions
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 4f8e6cde9bf6..d2f53f35d86a 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c | |||
@@ -50,9 +50,16 @@ static __init inline int srat_disabled(void) | |||
50 | /* Callback for SLIT parsing */ | 50 | /* Callback for SLIT parsing */ |
51 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) | 51 | void __init acpi_numa_slit_init(struct acpi_table_slit *slit) |
52 | { | 52 | { |
53 | int i, j; | ||
53 | unsigned length; | 54 | unsigned length; |
54 | unsigned long phys; | 55 | unsigned long phys; |
55 | 56 | ||
57 | for (i = 0; i < slit->locality_count; i++) | ||
58 | for (j = 0; j < slit->locality_count; j++) | ||
59 | numa_set_distance(pxm_to_node(i), pxm_to_node(j), | ||
60 | slit->entry[slit->locality_count * i + j]); | ||
61 | |||
62 | /* acpi_slit is used only by emulation */ | ||
56 | length = slit->header.length; | 63 | length = slit->header.length; |
57 | phys = memblock_find_in_range(0, max_pfn_mapped<<PAGE_SHIFT, length, | 64 | phys = memblock_find_in_range(0, max_pfn_mapped<<PAGE_SHIFT, length, |
58 | PAGE_SIZE); | 65 | PAGE_SIZE); |
@@ -313,29 +320,17 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) | |||
313 | node_set(i, numa_nodes_parsed); | 320 | node_set(i, numa_nodes_parsed); |
314 | } | 321 | } |
315 | 322 | ||
316 | static int null_slit_node_compare(int a, int b) | 323 | int acpi_emu_node_distance(int a, int b) |
317 | { | ||
318 | return node_to_pxm(a) == node_to_pxm(b); | ||
319 | } | ||
320 | #else | ||
321 | static int null_slit_node_compare(int a, int b) | ||
322 | { | ||
323 | return a == b; | ||
324 | } | ||
325 | #endif /* CONFIG_NUMA_EMU */ | ||
326 | |||
327 | int __node_distance(int a, int b) | ||
328 | { | 324 | { |
329 | int index; | 325 | int index; |
330 | 326 | ||
331 | if (!acpi_slit) | 327 | if (!acpi_slit) |
332 | return null_slit_node_compare(a, b) ? LOCAL_DISTANCE : | 328 | return node_to_pxm(a) == node_to_pxm(b) ? |
333 | REMOTE_DISTANCE; | 329 | LOCAL_DISTANCE : REMOTE_DISTANCE; |
334 | index = acpi_slit->locality_count * node_to_pxm(a); | 330 | index = acpi_slit->locality_count * node_to_pxm(a); |
335 | return acpi_slit->entry[index + node_to_pxm(b)]; | 331 | return acpi_slit->entry[index + node_to_pxm(b)]; |
336 | } | 332 | } |
337 | 333 | #endif /* CONFIG_NUMA_EMU */ | |
338 | EXPORT_SYMBOL(__node_distance); | ||
339 | 334 | ||
340 | #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) | 335 | #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) |
341 | int memory_add_physaddr_to_nid(u64 start) | 336 | int memory_add_physaddr_to_nid(u64 start) |