summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/numa.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/numa.c')
-rw-r--r--drivers/acpi/numa.c50
1 files changed, 47 insertions, 3 deletions
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 1333cbdc3ea2..acaa3b4ea504 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -29,6 +29,8 @@
29#include <linux/errno.h> 29#include <linux/errno.h>
30#include <linux/acpi.h> 30#include <linux/acpi.h>
31#include <linux/numa.h> 31#include <linux/numa.h>
32#include <linux/nodemask.h>
33#include <linux/topology.h>
32 34
33#define PREFIX "ACPI: " 35#define PREFIX "ACPI: "
34 36
@@ -70,7 +72,12 @@ static void __acpi_map_pxm_to_node(int pxm, int node)
70 72
71int acpi_map_pxm_to_node(int pxm) 73int acpi_map_pxm_to_node(int pxm)
72{ 74{
73 int node = pxm_to_node_map[pxm]; 75 int node;
76
77 if (pxm < 0 || pxm >= MAX_PXM_DOMAINS)
78 return NUMA_NO_NODE;
79
80 node = pxm_to_node_map[pxm];
74 81
75 if (node == NUMA_NO_NODE) { 82 if (node == NUMA_NO_NODE) {
76 if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) 83 if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
@@ -83,6 +90,45 @@ int acpi_map_pxm_to_node(int pxm)
83 return node; 90 return node;
84} 91}
85 92
93/**
94 * acpi_map_pxm_to_online_node - Map proximity ID to online node
95 * @pxm: ACPI proximity ID
96 *
97 * This is similar to acpi_map_pxm_to_node(), but always returns an online
98 * node. When the mapped node from a given proximity ID is offline, it
99 * looks up the node distance table and returns the nearest online node.
100 *
101 * ACPI device drivers, which are called after the NUMA initialization has
102 * completed in the kernel, can call this interface to obtain their device
103 * NUMA topology from ACPI tables. Such drivers do not have to deal with
104 * offline nodes. A node may be offline when a device proximity ID is
105 * unique, SRAT memory entry does not exist, or NUMA is disabled, ex.
106 * "numa=off" on x86.
107 */
108int acpi_map_pxm_to_online_node(int pxm)
109{
110 int node, n, dist, min_dist;
111
112 node = acpi_map_pxm_to_node(pxm);
113
114 if (node == NUMA_NO_NODE)
115 node = 0;
116
117 if (!node_online(node)) {
118 min_dist = INT_MAX;
119 for_each_online_node(n) {
120 dist = node_distance(node, n);
121 if (dist < min_dist) {
122 min_dist = dist;
123 node = n;
124 }
125 }
126 }
127
128 return node;
129}
130EXPORT_SYMBOL(acpi_map_pxm_to_online_node);
131
86static void __init 132static void __init
87acpi_table_print_srat_entry(struct acpi_subtable_header *header) 133acpi_table_print_srat_entry(struct acpi_subtable_header *header)
88{ 134{
@@ -328,8 +374,6 @@ int acpi_get_node(acpi_handle handle)
328 int pxm; 374 int pxm;
329 375
330 pxm = acpi_get_pxm(handle); 376 pxm = acpi_get_pxm(handle);
331 if (pxm < 0 || pxm >= MAX_PXM_DOMAINS)
332 return NUMA_NO_NODE;
333 377
334 return acpi_map_pxm_to_node(pxm); 378 return acpi_map_pxm_to_node(pxm);
335} 379}