Skip to content

Commit

Permalink
ACPI: NUMA: Up-level "map to online node" functionality
Browse files Browse the repository at this point in the history
The acpi_map_pxm_to_online_node() helper is used to find the closest
online node to a given proximity domain. This is used to map devices in
a proximity domain with no online memory or cpus to the closest online
node and populate a device's 'numa_node' property. The numa_node
property allows applications to be migrated "close" to a resource.

In preparation for providing a generic facility to optionally map an
address range to its closest online node, or the node the range would
represent were it to be onlined (target_node), up-level the core of
acpi_map_pxm_to_online_node() to a generic mm/numa helper.

Cc: Michal Hocko <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Reviewed-by: Ingo Molnar <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
Link: https://lore.kernel.org/r/158188324802.894464.13128795207831894206.stgit@dwillia2-desk3.amr.corp.intel.com
  • Loading branch information
djbw committed Feb 17, 2020
1 parent bb6d3fb commit b2ca916
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 42 deletions.
41 changes: 0 additions & 41 deletions drivers/acpi/numa/srat.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,47 +72,6 @@ int acpi_map_pxm_to_node(int pxm)
}
EXPORT_SYMBOL(acpi_map_pxm_to_node);

/**
* acpi_map_pxm_to_online_node - Map proximity ID to online node
* @pxm: ACPI proximity ID
*
* This is similar to acpi_map_pxm_to_node(), but always returns an online
* node. When the mapped node from a given proximity ID is offline, it
* looks up the node distance table and returns the nearest online node.
*
* ACPI device drivers, which are called after the NUMA initialization has
* completed in the kernel, can call this interface to obtain their device
* NUMA topology from ACPI tables. Such drivers do not have to deal with
* offline nodes. A node may be offline when a device proximity ID is
* unique, SRAT memory entry does not exist, or NUMA is disabled, ex.
* "numa=off" on x86.
*/
int acpi_map_pxm_to_online_node(int pxm)
{
int node, min_node;

node = acpi_map_pxm_to_node(pxm);

if (node == NUMA_NO_NODE)
node = 0;

min_node = node;
if (!node_online(node)) {
int min_dist = INT_MAX, dist, n;

for_each_online_node(n) {
dist = node_distance(node, n);
if (dist < min_dist) {
min_dist = dist;
min_node = n;
}
}
}

return min_node;
}
EXPORT_SYMBOL(acpi_map_pxm_to_online_node);

static void __init
acpi_table_print_srat_entry(struct acpi_subtable_header *header)
{
Expand Down
23 changes: 22 additions & 1 deletion include/linux/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,9 +416,30 @@ extern void acpi_osi_setup(char *str);
extern bool acpi_osi_is_win8(void);

#ifdef CONFIG_ACPI_NUMA
int acpi_map_pxm_to_online_node(int pxm);
int acpi_map_pxm_to_node(int pxm);
int acpi_get_node(acpi_handle handle);

/**
* acpi_map_pxm_to_online_node - Map proximity ID to online node
* @pxm: ACPI proximity ID
*
* This is similar to acpi_map_pxm_to_node(), but always returns an online
* node. When the mapped node from a given proximity ID is offline, it
* looks up the node distance table and returns the nearest online node.
*
* ACPI device drivers, which are called after the NUMA initialization has
* completed in the kernel, can call this interface to obtain their device
* NUMA topology from ACPI tables. Such drivers do not have to deal with
* offline nodes. A node may be offline when a device proximity ID is
* unique, SRAT memory entry does not exist, or NUMA is disabled, ex.
* "numa=off" on x86.
*/
static inline int acpi_map_pxm_to_online_node(int pxm)
{
int node = acpi_map_pxm_to_node(pxm);

return numa_map_to_online_node(node);
}
#else
static inline int acpi_map_pxm_to_online_node(int pxm)
{
Expand Down
9 changes: 9 additions & 0 deletions include/linux/numa.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@

#define NUMA_NO_NODE (-1)

#ifdef CONFIG_NUMA
int numa_map_to_online_node(int node);
#else
static inline int numa_map_to_online_node(int node)
{
return NUMA_NO_NODE;
}
#endif

#endif /* _LINUX_NUMA_H */
30 changes: 30 additions & 0 deletions mm/mempolicy.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,36 @@ static struct mempolicy default_policy = {

static struct mempolicy preferred_node_policy[MAX_NUMNODES];

/**
* numa_map_to_online_node - Find closest online node
* @nid: Node id to start the search
*
* Lookup the next closest node by distance if @nid is not online.
*/
int numa_map_to_online_node(int node)
{
int min_node;

if (node == NUMA_NO_NODE)
node = 0;

min_node = node;
if (!node_online(node)) {
int min_dist = INT_MAX, dist, n;

for_each_online_node(n) {
dist = node_distance(node, n);
if (dist < min_dist) {
min_dist = dist;
min_node = n;
}
}
}

return min_node;
}
EXPORT_SYMBOL_GPL(numa_map_to_online_node);

struct mempolicy *get_task_policy(struct task_struct *p)
{
struct mempolicy *pol = p->mempolicy;
Expand Down

0 comments on commit b2ca916

Please sign in to comment.