aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/srat_64.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-02-16 11:11:09 -0500
committerTejun Heo <tj@kernel.org>2011-02-16 11:11:09 -0500
commitac7136b611ee8f8bd6231ce2e1dbdd31ae3d39bc (patch)
tree41f6809ba694a723b521573c2e8d34c652c31281 /arch/x86/mm/srat_64.c
parent4697bdcc945c094d2c8a4876a24faeaf31a283e0 (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.c27
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 */
51void __init acpi_numa_slit_init(struct acpi_table_slit *slit) 51void __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
316static int null_slit_node_compare(int a, int b) 323int acpi_emu_node_distance(int a, int b)
317{
318 return node_to_pxm(a) == node_to_pxm(b);
319}
320#else
321static int null_slit_node_compare(int a, int b)
322{
323 return a == b;
324}
325#endif /* CONFIG_NUMA_EMU */
326
327int __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 */
338EXPORT_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)
341int memory_add_physaddr_to_nid(u64 start) 336int memory_add_physaddr_to_nid(u64 start)