ACPI: NUMA: Up-level "map to online node" functionality
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 <mhocko@suse.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Link: https://lore.kernel.org/r/158188324802.894464.13128795207831894206.stgit@dwillia2-desk3.amr.corp.intel.com
This commit is contained in:
parent
bb6d3fb354
commit
b2ca916ce3
|
@ -72,47 +72,6 @@ int acpi_map_pxm_to_node(int pxm)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(acpi_map_pxm_to_node);
|
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
|
static void __init
|
||||||
acpi_table_print_srat_entry(struct acpi_subtable_header *header)
|
acpi_table_print_srat_entry(struct acpi_subtable_header *header)
|
||||||
{
|
{
|
||||||
|
|
|
@ -416,9 +416,30 @@ extern void acpi_osi_setup(char *str);
|
||||||
extern bool acpi_osi_is_win8(void);
|
extern bool acpi_osi_is_win8(void);
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
int acpi_map_pxm_to_online_node(int pxm);
|
|
||||||
int acpi_map_pxm_to_node(int pxm);
|
int acpi_map_pxm_to_node(int pxm);
|
||||||
int acpi_get_node(acpi_handle handle);
|
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
|
#else
|
||||||
static inline int acpi_map_pxm_to_online_node(int pxm)
|
static inline int acpi_map_pxm_to_online_node(int pxm)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,4 +13,13 @@
|
||||||
|
|
||||||
#define NUMA_NO_NODE (-1)
|
#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 */
|
#endif /* _LINUX_NUMA_H */
|
||||||
|
|
|
@ -127,6 +127,36 @@ static struct mempolicy default_policy = {
|
||||||
|
|
||||||
static struct mempolicy preferred_node_policy[MAX_NUMNODES];
|
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 *get_task_policy(struct task_struct *p)
|
||||||
{
|
{
|
||||||
struct mempolicy *pol = p->mempolicy;
|
struct mempolicy *pol = p->mempolicy;
|
||||||
|
|
Loading…
Reference in New Issue