mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-31 04:01:48 -04:00
Merge branch 'acpi-numa'
* acpi-numa: ACPI / NUMA: Enable ACPI based NUMA on ARM64 arm64, ACPI, NUMA: NUMA support based on SRAT and SLIT ACPI / processor: Add acpi_map_madt_entry() ACPI / NUMA: Improve SRAT error detection and add messages ACPI / NUMA: Move acpi_numa_memory_affinity_init() to drivers/acpi/numa.c ACPI / NUMA: remove unneeded acpi_numa=1 ACPI / NUMA: move bad_srat() and srat_disabled() to drivers/acpi/numa.c x86 / ACPI / NUMA: cleanup acpi_numa_processor_affinity_init() arm64, NUMA: Cleanup NUMA disabled messages arm64, NUMA: rework numa_add_memblk() ACPI / NUMA: move acpi_numa_slit_init() to drivers/acpi/numa.c ACPI / NUMA: Move acpi_numa_arch_fixup() to ia64 only ACPI / NUMA: remove duplicate NULL check ACPI / NUMA: Replace ACPI_DEBUG_PRINT() with pr_debug() ACPI / NUMA: Use pr_fmt() instead of printk
This commit is contained in:
commit
d85f4eb699
19 changed files with 369 additions and 192 deletions
|
|
@ -291,8 +291,8 @@ config ACPI_THERMAL
|
|||
config ACPI_NUMA
|
||||
bool "NUMA support"
|
||||
depends on NUMA
|
||||
depends on (X86 || IA64)
|
||||
default y if IA64_GENERIC || IA64_SGI_SN2
|
||||
depends on (X86 || IA64 || ARM64)
|
||||
default y if IA64_GENERIC || IA64_SGI_SN2 || ARM64
|
||||
|
||||
config ACPI_CUSTOM_DSDT_FILE
|
||||
string "Custom DSDT Table file to include"
|
||||
|
|
|
|||
|
|
@ -18,22 +18,21 @@
|
|||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "ACPI: " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/numa.h>
|
||||
#include <linux/nodemask.h>
|
||||
#include <linux/topology.h>
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
#define ACPI_NUMA 0x80000000
|
||||
#define _COMPONENT ACPI_NUMA
|
||||
ACPI_MODULE_NAME("numa");
|
||||
|
||||
static nodemask_t nodes_found_map = NODE_MASK_NONE;
|
||||
|
||||
/* maps to convert between proximity domain and logical node ID */
|
||||
|
|
@ -43,6 +42,7 @@ static int node_to_pxm_map[MAX_NUMNODES]
|
|||
= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
|
||||
|
||||
unsigned char acpi_srat_revision __initdata;
|
||||
int acpi_numa __initdata;
|
||||
|
||||
int pxm_to_node(int pxm)
|
||||
{
|
||||
|
|
@ -128,68 +128,63 @@ EXPORT_SYMBOL(acpi_map_pxm_to_online_node);
|
|||
static void __init
|
||||
acpi_table_print_srat_entry(struct acpi_subtable_header *header)
|
||||
{
|
||||
|
||||
ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
|
||||
|
||||
if (!header)
|
||||
return;
|
||||
|
||||
switch (header->type) {
|
||||
|
||||
case ACPI_SRAT_TYPE_CPU_AFFINITY:
|
||||
#ifdef ACPI_DEBUG_OUTPUT
|
||||
{
|
||||
struct acpi_srat_cpu_affinity *p =
|
||||
(struct acpi_srat_cpu_affinity *)header;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
|
||||
p->apic_id, p->local_sapic_eid,
|
||||
p->proximity_domain_lo,
|
||||
(p->flags & ACPI_SRAT_CPU_ENABLED)?
|
||||
"enabled" : "disabled"));
|
||||
pr_debug("SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
|
||||
p->apic_id, p->local_sapic_eid,
|
||||
p->proximity_domain_lo,
|
||||
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
||||
"enabled" : "disabled");
|
||||
}
|
||||
#endif /* ACPI_DEBUG_OUTPUT */
|
||||
break;
|
||||
|
||||
case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
|
||||
#ifdef ACPI_DEBUG_OUTPUT
|
||||
{
|
||||
struct acpi_srat_mem_affinity *p =
|
||||
(struct acpi_srat_mem_affinity *)header;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
|
||||
(unsigned long)p->base_address,
|
||||
(unsigned long)p->length,
|
||||
p->proximity_domain,
|
||||
(p->flags & ACPI_SRAT_MEM_ENABLED)?
|
||||
"enabled" : "disabled",
|
||||
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
|
||||
" hot-pluggable" : "",
|
||||
(p->flags & ACPI_SRAT_MEM_NON_VOLATILE)?
|
||||
" non-volatile" : ""));
|
||||
pr_debug("SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
|
||||
(unsigned long)p->base_address,
|
||||
(unsigned long)p->length,
|
||||
p->proximity_domain,
|
||||
(p->flags & ACPI_SRAT_MEM_ENABLED) ?
|
||||
"enabled" : "disabled",
|
||||
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
|
||||
" hot-pluggable" : "",
|
||||
(p->flags & ACPI_SRAT_MEM_NON_VOLATILE) ?
|
||||
" non-volatile" : "");
|
||||
}
|
||||
#endif /* ACPI_DEBUG_OUTPUT */
|
||||
break;
|
||||
|
||||
case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
|
||||
#ifdef ACPI_DEBUG_OUTPUT
|
||||
{
|
||||
struct acpi_srat_x2apic_cpu_affinity *p =
|
||||
(struct acpi_srat_x2apic_cpu_affinity *)header;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"SRAT Processor (x2apicid[0x%08x]) in"
|
||||
" proximity domain %d %s\n",
|
||||
p->apic_id,
|
||||
p->proximity_domain,
|
||||
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
||||
"enabled" : "disabled"));
|
||||
pr_debug("SRAT Processor (x2apicid[0x%08x]) in proximity domain %d %s\n",
|
||||
p->apic_id,
|
||||
p->proximity_domain,
|
||||
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
||||
"enabled" : "disabled");
|
||||
}
|
||||
#endif /* ACPI_DEBUG_OUTPUT */
|
||||
break;
|
||||
|
||||
case ACPI_SRAT_TYPE_GICC_AFFINITY:
|
||||
{
|
||||
struct acpi_srat_gicc_affinity *p =
|
||||
(struct acpi_srat_gicc_affinity *)header;
|
||||
pr_debug("SRAT Processor (acpi id[0x%04x]) in proximity domain %d %s\n",
|
||||
p->acpi_processor_uid,
|
||||
p->proximity_domain,
|
||||
(p->flags & ACPI_SRAT_GICC_ENABLED) ?
|
||||
"enabled" : "disabled");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Found unsupported SRAT entry (type = 0x%x)\n",
|
||||
header->type);
|
||||
pr_warn("Found unsupported SRAT entry (type = 0x%x)\n",
|
||||
header->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -217,12 +212,117 @@ static int __init slit_valid(struct acpi_table_slit *slit)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void __init bad_srat(void)
|
||||
{
|
||||
pr_err("SRAT: SRAT not used.\n");
|
||||
acpi_numa = -1;
|
||||
}
|
||||
|
||||
int __init srat_disabled(void)
|
||||
{
|
||||
return acpi_numa < 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_X86) || defined(CONFIG_ARM64)
|
||||
/*
|
||||
* Callback for SLIT parsing. pxm_to_node() returns NUMA_NO_NODE for
|
||||
* I/O localities since SRAT does not list them. I/O localities are
|
||||
* not supported at this point.
|
||||
*/
|
||||
void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < slit->locality_count; i++) {
|
||||
const int from_node = pxm_to_node(i);
|
||||
|
||||
if (from_node == NUMA_NO_NODE)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < slit->locality_count; j++) {
|
||||
const int to_node = pxm_to_node(j);
|
||||
|
||||
if (to_node == NUMA_NO_NODE)
|
||||
continue;
|
||||
|
||||
numa_set_distance(from_node, to_node,
|
||||
slit->entry[slit->locality_count * i + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Default callback for parsing of the Proximity Domain <-> Memory
|
||||
* Area mappings
|
||||
*/
|
||||
int __init
|
||||
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
|
||||
{
|
||||
u64 start, end;
|
||||
u32 hotpluggable;
|
||||
int node, pxm;
|
||||
|
||||
if (srat_disabled())
|
||||
goto out_err;
|
||||
if (ma->header.length < sizeof(struct acpi_srat_mem_affinity)) {
|
||||
pr_err("SRAT: Unexpected header length: %d\n",
|
||||
ma->header.length);
|
||||
goto out_err_bad_srat;
|
||||
}
|
||||
if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
|
||||
goto out_err;
|
||||
hotpluggable = ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE;
|
||||
if (hotpluggable && !IS_ENABLED(CONFIG_MEMORY_HOTPLUG))
|
||||
goto out_err;
|
||||
|
||||
start = ma->base_address;
|
||||
end = start + ma->length;
|
||||
pxm = ma->proximity_domain;
|
||||
if (acpi_srat_revision <= 1)
|
||||
pxm &= 0xff;
|
||||
|
||||
node = acpi_map_pxm_to_node(pxm);
|
||||
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
|
||||
pr_err("SRAT: Too many proximity domains.\n");
|
||||
goto out_err_bad_srat;
|
||||
}
|
||||
|
||||
if (numa_add_memblk(node, start, end) < 0) {
|
||||
pr_err("SRAT: Failed to add memblk to node %u [mem %#010Lx-%#010Lx]\n",
|
||||
node, (unsigned long long) start,
|
||||
(unsigned long long) end - 1);
|
||||
goto out_err_bad_srat;
|
||||
}
|
||||
|
||||
node_set(node, numa_nodes_parsed);
|
||||
|
||||
pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]%s%s\n",
|
||||
node, pxm,
|
||||
(unsigned long long) start, (unsigned long long) end - 1,
|
||||
hotpluggable ? " hotplug" : "",
|
||||
ma->flags & ACPI_SRAT_MEM_NON_VOLATILE ? " non-volatile" : "");
|
||||
|
||||
/* Mark hotplug range in memblock. */
|
||||
if (hotpluggable && memblock_mark_hotplug(start, ma->length))
|
||||
pr_warn("SRAT: Failed to mark hotplug range [mem %#010Lx-%#010Lx] in memblock\n",
|
||||
(unsigned long long)start, (unsigned long long)end - 1);
|
||||
|
||||
max_possible_pfn = max(max_possible_pfn, PFN_UP(end - 1));
|
||||
|
||||
return 0;
|
||||
out_err_bad_srat:
|
||||
bad_srat();
|
||||
out_err:
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif /* defined(CONFIG_X86) || defined (CONFIG_ARM64) */
|
||||
|
||||
static int __init acpi_parse_slit(struct acpi_table_header *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");
|
||||
pr_info("SLIT table looks invalid. Not used.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
acpi_numa_slit_init(slit);
|
||||
|
|
@ -233,12 +333,9 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
|
|||
void __init __weak
|
||||
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
||||
{
|
||||
printk(KERN_WARNING PREFIX
|
||||
"Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
|
||||
return;
|
||||
pr_warn("Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
|
||||
}
|
||||
|
||||
|
||||
static int __init
|
||||
acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
|
||||
const unsigned long end)
|
||||
|
|
@ -275,6 +372,24 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __init
|
||||
acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
|
||||
const unsigned long end)
|
||||
{
|
||||
struct acpi_srat_gicc_affinity *processor_affinity;
|
||||
|
||||
processor_affinity = (struct acpi_srat_gicc_affinity *)header;
|
||||
if (!processor_affinity)
|
||||
return -EINVAL;
|
||||
|
||||
acpi_table_print_srat_entry(header);
|
||||
|
||||
/* let architecture-dependent part to do it */
|
||||
acpi_numa_gicc_affinity_init(processor_affinity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __initdata parsed_numa_memblks;
|
||||
|
||||
static int __init
|
||||
|
|
@ -319,6 +434,9 @@ int __init acpi_numa_init(void)
|
|||
{
|
||||
int cnt = 0;
|
||||
|
||||
if (acpi_disabled)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
|
||||
* SRAT cpu entries could have different order with that in MADT.
|
||||
|
|
@ -327,13 +445,15 @@ int __init acpi_numa_init(void)
|
|||
|
||||
/* SRAT: Static Resource Affinity Table */
|
||||
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
|
||||
struct acpi_subtable_proc srat_proc[2];
|
||||
struct acpi_subtable_proc srat_proc[3];
|
||||
|
||||
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;
|
||||
srat_proc[2].id = ACPI_SRAT_TYPE_GICC_AFFINITY;
|
||||
srat_proc[2].handler = acpi_parse_gicc_affinity;
|
||||
|
||||
acpi_table_parse_entries_array(ACPI_SIG_SRAT,
|
||||
sizeof(struct acpi_table_srat),
|
||||
|
|
@ -347,8 +467,6 @@ int __init acpi_numa_init(void)
|
|||
/* SLIT: System Locality Information Table */
|
||||
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
|
||||
|
||||
acpi_numa_arch_fixup();
|
||||
|
||||
if (cnt < 0)
|
||||
return cnt;
|
||||
else if (!parsed_numa_memblks)
|
||||
|
|
|
|||
|
|
@ -108,13 +108,12 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
|
||||
static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
|
||||
int type, u32 acpi_id)
|
||||
{
|
||||
unsigned long madt_end, entry;
|
||||
phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
|
||||
struct acpi_table_madt *madt;
|
||||
|
||||
madt = get_madt_table();
|
||||
if (!madt)
|
||||
return phys_id;
|
||||
|
||||
|
|
@ -145,6 +144,25 @@ static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
|
|||
return phys_id;
|
||||
}
|
||||
|
||||
phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
|
||||
{
|
||||
struct acpi_table_madt *madt = NULL;
|
||||
acpi_size tbl_size;
|
||||
phys_cpuid_t rv;
|
||||
|
||||
acpi_get_table_with_size(ACPI_SIG_MADT, 0,
|
||||
(struct acpi_table_header **)&madt,
|
||||
&tbl_size);
|
||||
if (!madt)
|
||||
return PHYS_CPUID_INVALID;
|
||||
|
||||
rv = map_madt_entry(madt, 1, acpi_id);
|
||||
|
||||
early_acpi_os_unmap_memory(madt, tbl_size);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
|
|
@ -185,7 +203,7 @@ phys_cpuid_t acpi_get_phys_id(acpi_handle handle, int type, u32 acpi_id)
|
|||
|
||||
phys_id = map_mat_entry(handle, type, acpi_id);
|
||||
if (invalid_phys_cpuid(phys_id))
|
||||
phys_id = map_madt_entry(type, acpi_id);
|
||||
phys_id = map_madt_entry(get_madt_table(), type, acpi_id);
|
||||
|
||||
return phys_id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue