--- zzzz-none-000/linux-3.10.107/drivers/acpi/numa.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/acpi/numa.c 2021-02-04 17:41:59.000000000 +0000 @@ -15,10 +15,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * */ @@ -29,7 +25,8 @@ #include #include #include -#include +#include +#include #define PREFIX "ACPI: " @@ -61,7 +58,7 @@ return node_to_pxm_map[node]; } -void __acpi_map_pxm_to_node(int pxm, int node) +static void __acpi_map_pxm_to_node(int pxm, int node) { if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm]) pxm_to_node_map[pxm] = node; @@ -71,9 +68,14 @@ int acpi_map_pxm_to_node(int pxm) { - int node = pxm_to_node_map[pxm]; + int node; + + if (pxm < 0 || pxm >= MAX_PXM_DOMAINS) + return NUMA_NO_NODE; - if (node < 0) { + node = pxm_to_node_map[pxm]; + + if (node == NUMA_NO_NODE) { if (nodes_weight(nodes_found_map) >= MAX_NUMNODES) return NUMA_NO_NODE; node = first_unset_node(nodes_found_map); @@ -84,6 +86,45 @@ return 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, n, dist, min_dist; + + node = acpi_map_pxm_to_node(pxm); + + if (node == NUMA_NO_NODE) + node = 0; + + if (!node_online(node)) { + min_dist = INT_MAX; + for_each_online_node(n) { + dist = node_distance(node, n); + if (dist < min_dist) { + min_dist = dist; + node = n; + } + } + } + + return node; +} +EXPORT_SYMBOL(acpi_map_pxm_to_online_node); + static void __init acpi_table_print_srat_entry(struct acpi_subtable_header *header) { @@ -159,7 +200,7 @@ * distance than the others. * Do some quick checks here and only use the SLIT if it passes. */ -static __init int slit_valid(struct acpi_table_slit *slit) +static int __init slit_valid(struct acpi_table_slit *slit) { int i, j; int d = slit->locality_count; @@ -178,12 +219,7 @@ static int __init acpi_parse_slit(struct acpi_table_header *table) { - struct acpi_table_slit *slit; - - if (!table) - return -EINVAL; - - slit = (struct acpi_table_slit *)table; + struct acpi_table_slit *slit = (struct acpi_table_slit *)table; if (!slit_valid(slit)) { printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); @@ -194,7 +230,7 @@ return 0; } -void __init __attribute__ ((weak)) +void __init __weak acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) { printk(KERN_WARNING PREFIX @@ -261,11 +297,8 @@ static int __init acpi_parse_srat(struct acpi_table_header *table) { - struct acpi_table_srat *srat; - if (!table) - return -EINVAL; + struct acpi_table_srat *srat = (struct acpi_table_srat *)table; - srat = (struct acpi_table_srat *)table; acpi_srat_revision = srat->header.revision; /* Real work done in acpi_table_parse_srat below. */ @@ -294,10 +327,18 @@ /* SRAT: Static Resource Affinity Table */ if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) { - acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, - acpi_parse_x2apic_affinity, 0); - acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, - acpi_parse_processor_affinity, 0); + struct acpi_subtable_proc srat_proc[2]; + + memset(srat_proc, 0, sizeof(srat_proc)); + srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY; + srat_proc[0].handler = acpi_parse_processor_affinity; + srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY; + srat_proc[1].handler = acpi_parse_x2apic_affinity; + + acpi_table_parse_entries_array(ACPI_SIG_SRAT, + sizeof(struct acpi_table_srat), + srat_proc, ARRAY_SIZE(srat_proc), 0); + cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY, acpi_parse_memory_affinity, NR_NODE_MEMBLKS); @@ -315,7 +356,7 @@ return 0; } -int acpi_get_pxm(acpi_handle h) +static int acpi_get_pxm(acpi_handle h) { unsigned long long pxm; acpi_status status; @@ -332,14 +373,12 @@ return -1; } -int acpi_get_node(acpi_handle *handle) +int acpi_get_node(acpi_handle handle) { - int pxm, node = -1; + int pxm; pxm = acpi_get_pxm(handle); - if (pxm >= 0 && pxm < MAX_PXM_DOMAINS) - node = acpi_map_pxm_to_node(pxm); - return node; + return acpi_map_pxm_to_node(pxm); } EXPORT_SYMBOL(acpi_get_node);