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 printksteinar/wifi_calib_4_9_kernel
commit
d85f4eb699
|
@ -113,4 +113,12 @@ static inline const char *acpi_get_enable_method(int cpu)
|
||||||
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
|
pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
|
int arm64_acpi_numa_init(void);
|
||||||
|
int acpi_numa_get_nid(unsigned int cpu, u64 hwid);
|
||||||
|
#else
|
||||||
|
static inline int arm64_acpi_numa_init(void) { return -ENOSYS; }
|
||||||
|
static inline int acpi_numa_get_nid(unsigned int cpu, u64 hwid) { return NUMA_NO_NODE; }
|
||||||
|
#endif /* CONFIG_ACPI_NUMA */
|
||||||
|
|
||||||
#endif /*_ASM_ACPI_H*/
|
#endif /*_ASM_ACPI_H*/
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
|
|
||||||
|
#define NR_NODE_MEMBLKS (MAX_NUMNODES * 2)
|
||||||
|
|
||||||
/* currently, arm64 implements flat NUMA topology */
|
/* currently, arm64 implements flat NUMA topology */
|
||||||
#define parent_node(node) (node)
|
#define parent_node(node) (node)
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
|
||||||
arm64-obj-$(CONFIG_PCI) += pci.o
|
arm64-obj-$(CONFIG_PCI) += pci.o
|
||||||
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
|
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
|
||||||
arm64-obj-$(CONFIG_ACPI) += acpi.o
|
arm64-obj-$(CONFIG_ACPI) += acpi.o
|
||||||
|
arm64-obj-$(CONFIG_ACPI_NUMA) += acpi_numa.o
|
||||||
arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
|
arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL) += acpi_parking_protocol.o
|
||||||
arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
|
arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
|
||||||
arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* ACPI 5.1 based NUMA setup for ARM64
|
||||||
|
* Lots of code was borrowed from arch/x86/mm/srat.c
|
||||||
|
*
|
||||||
|
* Copyright 2004 Andi Kleen, SuSE Labs.
|
||||||
|
* Copyright (C) 2013-2016, Linaro Ltd.
|
||||||
|
* Author: Hanjun Guo <hanjun.guo@linaro.org>
|
||||||
|
*
|
||||||
|
* Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
|
||||||
|
*
|
||||||
|
* Called from acpi_numa_init while reading the SRAT and SLIT tables.
|
||||||
|
* Assumes all memory regions belonging to a single proximity domain
|
||||||
|
* are in one chunk. Holes between them will be included in the node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ACPI: NUMA: " fmt
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/bitmap.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/memblock.h>
|
||||||
|
#include <linux/mmzone.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/topology.h>
|
||||||
|
|
||||||
|
#include <acpi/processor.h>
|
||||||
|
#include <asm/numa.h>
|
||||||
|
|
||||||
|
static int cpus_in_srat;
|
||||||
|
|
||||||
|
struct __node_cpu_hwid {
|
||||||
|
u32 node_id; /* logical node containing this CPU */
|
||||||
|
u64 cpu_hwid; /* MPIDR for this CPU */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct __node_cpu_hwid early_node_cpu_hwid[NR_CPUS] = {
|
||||||
|
[0 ... NR_CPUS - 1] = {NUMA_NO_NODE, PHYS_CPUID_INVALID} };
|
||||||
|
|
||||||
|
int acpi_numa_get_nid(unsigned int cpu, u64 hwid)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cpus_in_srat; i++) {
|
||||||
|
if (hwid == early_node_cpu_hwid[i].cpu_hwid)
|
||||||
|
return early_node_cpu_hwid[i].node_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NUMA_NO_NODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for Proximity Domain -> ACPI processor UID mapping */
|
||||||
|
void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
|
||||||
|
{
|
||||||
|
int pxm, node;
|
||||||
|
phys_cpuid_t mpidr;
|
||||||
|
|
||||||
|
if (srat_disabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pa->header.length < sizeof(struct acpi_srat_gicc_affinity)) {
|
||||||
|
pr_err("SRAT: Invalid SRAT header length: %d\n",
|
||||||
|
pa->header.length);
|
||||||
|
bad_srat();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(pa->flags & ACPI_SRAT_GICC_ENABLED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cpus_in_srat >= NR_CPUS) {
|
||||||
|
pr_warn_once("SRAT: cpu_to_node_map[%d] is too small, may not be able to use all cpus\n",
|
||||||
|
NR_CPUS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pxm = pa->proximity_domain;
|
||||||
|
node = acpi_map_pxm_to_node(pxm);
|
||||||
|
|
||||||
|
if (node == NUMA_NO_NODE || node >= MAX_NUMNODES) {
|
||||||
|
pr_err("SRAT: Too many proximity domains %d\n", pxm);
|
||||||
|
bad_srat();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpidr = acpi_map_madt_entry(pa->acpi_processor_uid);
|
||||||
|
if (mpidr == PHYS_CPUID_INVALID) {
|
||||||
|
pr_err("SRAT: PXM %d with ACPI ID %d has no valid MPIDR in MADT\n",
|
||||||
|
pxm, pa->acpi_processor_uid);
|
||||||
|
bad_srat();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
early_node_cpu_hwid[cpus_in_srat].node_id = node;
|
||||||
|
early_node_cpu_hwid[cpus_in_srat].cpu_hwid = mpidr;
|
||||||
|
node_set(node, numa_nodes_parsed);
|
||||||
|
cpus_in_srat++;
|
||||||
|
pr_info("SRAT: PXM %d -> MPIDR 0x%Lx -> Node %d\n",
|
||||||
|
pxm, mpidr, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init arm64_acpi_numa_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = acpi_numa_init();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return srat_disabled() ? -EINVAL : 0;
|
||||||
|
}
|
|
@ -560,6 +560,8 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
|
||||||
*/
|
*/
|
||||||
acpi_set_mailbox_entry(cpu_count, processor);
|
acpi_set_mailbox_entry(cpu_count, processor);
|
||||||
|
|
||||||
|
early_map_cpu_to_node(cpu_count, acpi_numa_get_nid(cpu_count, hwid));
|
||||||
|
|
||||||
cpu_count++;
|
cpu_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/memblock.h>
|
#include <linux/memblock.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -29,7 +30,7 @@ static int cpu_to_node_map[NR_CPUS] = { [0 ... NR_CPUS-1] = NUMA_NO_NODE };
|
||||||
|
|
||||||
static int numa_distance_cnt;
|
static int numa_distance_cnt;
|
||||||
static u8 *numa_distance;
|
static u8 *numa_distance;
|
||||||
static int numa_off;
|
static bool numa_off;
|
||||||
|
|
||||||
static __init int numa_parse_early_param(char *opt)
|
static __init int numa_parse_early_param(char *opt)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +38,7 @@ static __init int numa_parse_early_param(char *opt)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!strncmp(opt, "off", 3)) {
|
if (!strncmp(opt, "off", 3)) {
|
||||||
pr_info("%s\n", "NUMA turned off");
|
pr_info("%s\n", "NUMA turned off");
|
||||||
numa_off = 1;
|
numa_off = true;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -131,25 +132,25 @@ void __init early_map_cpu_to_node(unsigned int cpu, int nid)
|
||||||
* numa_add_memblk - Set node id to memblk
|
* numa_add_memblk - Set node id to memblk
|
||||||
* @nid: NUMA node ID of the new memblk
|
* @nid: NUMA node ID of the new memblk
|
||||||
* @start: Start address of the new memblk
|
* @start: Start address of the new memblk
|
||||||
* @size: Size of the new memblk
|
* @end: End address of the new memblk
|
||||||
*
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 on success, -errno on failure.
|
* 0 on success, -errno on failure.
|
||||||
*/
|
*/
|
||||||
int __init numa_add_memblk(int nid, u64 start, u64 size)
|
int __init numa_add_memblk(int nid, u64 start, u64 end)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = memblock_set_node(start, size, &memblock.memory, nid);
|
ret = memblock_set_node(start, (end - start), &memblock.memory, nid);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
|
pr_err("NUMA: memblock [0x%llx - 0x%llx] failed to add on node %d\n",
|
||||||
start, (start + size - 1), nid);
|
start, (end - 1), nid);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
node_set(nid, numa_nodes_parsed);
|
node_set(nid, numa_nodes_parsed);
|
||||||
pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
|
pr_info("NUMA: Adding memblock [0x%llx - 0x%llx] on node %d\n",
|
||||||
start, (start + size - 1), nid);
|
start, (end - 1), nid);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,12 +363,15 @@ static int __init dummy_numa_init(void)
|
||||||
int ret;
|
int ret;
|
||||||
struct memblock_region *mblk;
|
struct memblock_region *mblk;
|
||||||
|
|
||||||
pr_info("%s\n", "No NUMA configuration found");
|
if (numa_off)
|
||||||
|
pr_info("NUMA disabled\n"); /* Forced off on command line. */
|
||||||
|
else
|
||||||
|
pr_info("No NUMA configuration found\n");
|
||||||
pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
|
pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n",
|
||||||
0LLU, PFN_PHYS(max_pfn) - 1);
|
0LLU, PFN_PHYS(max_pfn) - 1);
|
||||||
|
|
||||||
for_each_memblock(memory, mblk) {
|
for_each_memblock(memory, mblk) {
|
||||||
ret = numa_add_memblk(0, mblk->base, mblk->size);
|
ret = numa_add_memblk(0, mblk->base, mblk->base + mblk->size);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -375,7 +379,7 @@ static int __init dummy_numa_init(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
numa_off = 1;
|
numa_off = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +392,9 @@ static int __init dummy_numa_init(void)
|
||||||
void __init arm64_numa_init(void)
|
void __init arm64_numa_init(void)
|
||||||
{
|
{
|
||||||
if (!numa_off) {
|
if (!numa_off) {
|
||||||
if (!numa_init(of_numa_init))
|
if (!acpi_disabled && !numa_init(arm64_acpi_numa_init))
|
||||||
|
return;
|
||||||
|
if (acpi_disabled && !numa_init(of_numa_init))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,9 @@ static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void acpi_numa_fixup(void);
|
||||||
|
|
||||||
#endif /* CONFIG_ACPI_NUMA */
|
#endif /* CONFIG_ACPI_NUMA */
|
||||||
|
|
||||||
#endif /*__KERNEL__*/
|
#endif /*__KERNEL__*/
|
||||||
|
|
|
@ -524,7 +524,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init acpi_numa_arch_fixup(void)
|
void __init acpi_numa_fixup(void)
|
||||||
{
|
{
|
||||||
int i, j, node_from, node_to;
|
int i, j, node_from, node_to;
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,7 @@ setup_arch (char **cmdline_p)
|
||||||
early_acpi_boot_init();
|
early_acpi_boot_init();
|
||||||
# ifdef CONFIG_ACPI_NUMA
|
# ifdef CONFIG_ACPI_NUMA
|
||||||
acpi_numa_init();
|
acpi_numa_init();
|
||||||
|
acpi_numa_fixup();
|
||||||
# ifdef CONFIG_ACPI_HOTPLUG_CPU
|
# ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||||
prefill_possible_map();
|
prefill_possible_map();
|
||||||
# endif
|
# endif
|
||||||
|
|
|
@ -145,7 +145,6 @@ static inline void disable_acpi(void) { }
|
||||||
#define ARCH_HAS_POWER_INIT 1
|
#define ARCH_HAS_POWER_INIT 1
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI_NUMA
|
#ifdef CONFIG_ACPI_NUMA
|
||||||
extern int acpi_numa;
|
|
||||||
extern int x86_acpi_numa_init(void);
|
extern int x86_acpi_numa_init(void);
|
||||||
#endif /* CONFIG_ACPI_NUMA */
|
#endif /* CONFIG_ACPI_NUMA */
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* Common code for 32 and 64-bit NUMA */
|
/* Common code for 32 and 64-bit NUMA */
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
@ -15,7 +16,6 @@
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/proto.h>
|
#include <asm/proto.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
#include <asm/acpi.h>
|
|
||||||
#include <asm/amd_nb.h>
|
#include <asm/amd_nb.h>
|
||||||
|
|
||||||
#include "numa_internal.h"
|
#include "numa_internal.h"
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/topology.h>
|
#include <linux/topology.h>
|
||||||
#include <linux/bootmem.h>
|
|
||||||
#include <linux/memblock.h>
|
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
#include <asm/proto.h>
|
#include <asm/proto.h>
|
||||||
#include <asm/numa.h>
|
#include <asm/numa.h>
|
||||||
|
@ -24,51 +22,6 @@
|
||||||
#include <asm/apic.h>
|
#include <asm/apic.h>
|
||||||
#include <asm/uv/uv.h>
|
#include <asm/uv/uv.h>
|
||||||
|
|
||||||
int acpi_numa __initdata;
|
|
||||||
|
|
||||||
static __init int setup_node(int pxm)
|
|
||||||
{
|
|
||||||
return acpi_map_pxm_to_node(pxm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init void bad_srat(void)
|
|
||||||
{
|
|
||||||
printk(KERN_ERR "SRAT: SRAT not used.\n");
|
|
||||||
acpi_numa = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init inline int srat_disabled(void)
|
|
||||||
{
|
|
||||||
return acpi_numa < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callback for Proximity Domain -> x2APIC mapping */
|
/* Callback for Proximity Domain -> x2APIC mapping */
|
||||||
void __init
|
void __init
|
||||||
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
||||||
|
@ -91,7 +44,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
||||||
pxm, apic_id);
|
pxm, apic_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node = setup_node(pxm);
|
node = acpi_map_pxm_to_node(pxm);
|
||||||
if (node < 0) {
|
if (node < 0) {
|
||||||
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
|
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
|
||||||
bad_srat();
|
bad_srat();
|
||||||
|
@ -104,7 +57,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
||||||
}
|
}
|
||||||
set_apicid_to_node(apic_id, node);
|
set_apicid_to_node(apic_id, node);
|
||||||
node_set(node, numa_nodes_parsed);
|
node_set(node, numa_nodes_parsed);
|
||||||
acpi_numa = 1;
|
|
||||||
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
|
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
|
||||||
pxm, apic_id, node);
|
pxm, apic_id, node);
|
||||||
}
|
}
|
||||||
|
@ -127,7 +79,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
|
||||||
pxm = pa->proximity_domain_lo;
|
pxm = pa->proximity_domain_lo;
|
||||||
if (acpi_srat_revision >= 2)
|
if (acpi_srat_revision >= 2)
|
||||||
pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
|
pxm |= *((unsigned int*)pa->proximity_domain_hi) << 8;
|
||||||
node = setup_node(pxm);
|
node = acpi_map_pxm_to_node(pxm);
|
||||||
if (node < 0) {
|
if (node < 0) {
|
||||||
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
|
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
|
||||||
bad_srat();
|
bad_srat();
|
||||||
|
@ -146,74 +98,10 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
|
||||||
|
|
||||||
set_apicid_to_node(apic_id, node);
|
set_apicid_to_node(apic_id, node);
|
||||||
node_set(node, numa_nodes_parsed);
|
node_set(node, numa_nodes_parsed);
|
||||||
acpi_numa = 1;
|
|
||||||
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
|
printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
|
||||||
pxm, apic_id, node);
|
pxm, apic_id, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTPLUG
|
|
||||||
static inline int save_add_info(void) {return 1;}
|
|
||||||
#else
|
|
||||||
static inline int save_add_info(void) {return 0;}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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))
|
|
||||||
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 && !save_add_info())
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
start = ma->base_address;
|
|
||||||
end = start + ma->length;
|
|
||||||
pxm = ma->proximity_domain;
|
|
||||||
if (acpi_srat_revision <= 1)
|
|
||||||
pxm &= 0xff;
|
|
||||||
|
|
||||||
node = setup_node(pxm);
|
|
||||||
if (node < 0) {
|
|
||||||
printk(KERN_ERR "SRAT: Too many proximity domains.\n");
|
|
||||||
goto out_err_bad_srat;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numa_add_memblk(node, start, end) < 0)
|
|
||||||
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 -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __init acpi_numa_arch_fixup(void) {}
|
|
||||||
|
|
||||||
int __init x86_acpi_numa_init(void)
|
int __init x86_acpi_numa_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
|
@ -291,8 +291,8 @@ config ACPI_THERMAL
|
||||||
config ACPI_NUMA
|
config ACPI_NUMA
|
||||||
bool "NUMA support"
|
bool "NUMA support"
|
||||||
depends on NUMA
|
depends on NUMA
|
||||||
depends on (X86 || IA64)
|
depends on (X86 || IA64 || ARM64)
|
||||||
default y if IA64_GENERIC || IA64_SGI_SN2
|
default y if IA64_GENERIC || IA64_SGI_SN2 || ARM64
|
||||||
|
|
||||||
config ACPI_CUSTOM_DSDT_FILE
|
config ACPI_CUSTOM_DSDT_FILE
|
||||||
string "Custom DSDT Table file to include"
|
string "Custom DSDT Table file to include"
|
||||||
|
|
|
@ -18,22 +18,21 @@
|
||||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "ACPI: " fmt
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/acpi.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/memblock.h>
|
||||||
#include <linux/numa.h>
|
#include <linux/numa.h>
|
||||||
#include <linux/nodemask.h>
|
#include <linux/nodemask.h>
|
||||||
#include <linux/topology.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;
|
static nodemask_t nodes_found_map = NODE_MASK_NONE;
|
||||||
|
|
||||||
/* maps to convert between proximity domain and logical node ID */
|
/* 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 };
|
= { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
|
||||||
|
|
||||||
unsigned char acpi_srat_revision __initdata;
|
unsigned char acpi_srat_revision __initdata;
|
||||||
|
int acpi_numa __initdata;
|
||||||
|
|
||||||
int pxm_to_node(int pxm)
|
int pxm_to_node(int pxm)
|
||||||
{
|
{
|
||||||
|
@ -128,68 +128,63 @@ 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)
|
||||||
{
|
{
|
||||||
|
|
||||||
ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
|
|
||||||
|
|
||||||
if (!header)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (header->type) {
|
switch (header->type) {
|
||||||
|
|
||||||
case ACPI_SRAT_TYPE_CPU_AFFINITY:
|
case ACPI_SRAT_TYPE_CPU_AFFINITY:
|
||||||
#ifdef ACPI_DEBUG_OUTPUT
|
|
||||||
{
|
{
|
||||||
struct acpi_srat_cpu_affinity *p =
|
struct acpi_srat_cpu_affinity *p =
|
||||||
(struct acpi_srat_cpu_affinity *)header;
|
(struct acpi_srat_cpu_affinity *)header;
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
pr_debug("SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
|
||||||
"SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
|
p->apic_id, p->local_sapic_eid,
|
||||||
p->apic_id, p->local_sapic_eid,
|
p->proximity_domain_lo,
|
||||||
p->proximity_domain_lo,
|
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
||||||
(p->flags & ACPI_SRAT_CPU_ENABLED)?
|
"enabled" : "disabled");
|
||||||
"enabled" : "disabled"));
|
|
||||||
}
|
}
|
||||||
#endif /* ACPI_DEBUG_OUTPUT */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
|
case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
|
||||||
#ifdef ACPI_DEBUG_OUTPUT
|
|
||||||
{
|
{
|
||||||
struct acpi_srat_mem_affinity *p =
|
struct acpi_srat_mem_affinity *p =
|
||||||
(struct acpi_srat_mem_affinity *)header;
|
(struct acpi_srat_mem_affinity *)header;
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
pr_debug("SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
|
||||||
"SRAT Memory (0x%lx length 0x%lx) in proximity domain %d %s%s%s\n",
|
(unsigned long)p->base_address,
|
||||||
(unsigned long)p->base_address,
|
(unsigned long)p->length,
|
||||||
(unsigned long)p->length,
|
p->proximity_domain,
|
||||||
p->proximity_domain,
|
(p->flags & ACPI_SRAT_MEM_ENABLED) ?
|
||||||
(p->flags & ACPI_SRAT_MEM_ENABLED)?
|
"enabled" : "disabled",
|
||||||
"enabled" : "disabled",
|
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
|
||||||
(p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
|
" hot-pluggable" : "",
|
||||||
" hot-pluggable" : "",
|
(p->flags & ACPI_SRAT_MEM_NON_VOLATILE) ?
|
||||||
(p->flags & ACPI_SRAT_MEM_NON_VOLATILE)?
|
" non-volatile" : "");
|
||||||
" non-volatile" : ""));
|
|
||||||
}
|
}
|
||||||
#endif /* ACPI_DEBUG_OUTPUT */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
|
case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
|
||||||
#ifdef ACPI_DEBUG_OUTPUT
|
|
||||||
{
|
{
|
||||||
struct acpi_srat_x2apic_cpu_affinity *p =
|
struct acpi_srat_x2apic_cpu_affinity *p =
|
||||||
(struct acpi_srat_x2apic_cpu_affinity *)header;
|
(struct acpi_srat_x2apic_cpu_affinity *)header;
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
pr_debug("SRAT Processor (x2apicid[0x%08x]) in proximity domain %d %s\n",
|
||||||
"SRAT Processor (x2apicid[0x%08x]) in"
|
p->apic_id,
|
||||||
" proximity domain %d %s\n",
|
p->proximity_domain,
|
||||||
p->apic_id,
|
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
||||||
p->proximity_domain,
|
"enabled" : "disabled");
|
||||||
(p->flags & ACPI_SRAT_CPU_ENABLED) ?
|
|
||||||
"enabled" : "disabled"));
|
|
||||||
}
|
}
|
||||||
#endif /* ACPI_DEBUG_OUTPUT */
|
|
||||||
break;
|
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:
|
default:
|
||||||
printk(KERN_WARNING PREFIX
|
pr_warn("Found unsupported SRAT entry (type = 0x%x)\n",
|
||||||
"Found unsupported SRAT entry (type = 0x%x)\n",
|
header->type);
|
||||||
header->type);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,12 +212,117 @@ static int __init slit_valid(struct acpi_table_slit *slit)
|
||||||
return 1;
|
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)
|
static int __init acpi_parse_slit(struct acpi_table_header *table)
|
||||||
{
|
{
|
||||||
struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
|
struct acpi_table_slit *slit = (struct acpi_table_slit *)table;
|
||||||
|
|
||||||
if (!slit_valid(slit)) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
acpi_numa_slit_init(slit);
|
acpi_numa_slit_init(slit);
|
||||||
|
@ -233,12 +333,9 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
|
||||||
void __init __weak
|
void __init __weak
|
||||||
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
|
||||||
{
|
{
|
||||||
printk(KERN_WARNING PREFIX
|
pr_warn("Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
|
||||||
"Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
|
acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
|
||||||
const unsigned long end)
|
const unsigned long end)
|
||||||
|
@ -275,6 +372,24 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header,
|
||||||
return 0;
|
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 __initdata parsed_numa_memblks;
|
||||||
|
|
||||||
static int __init
|
static int __init
|
||||||
|
@ -319,6 +434,9 @@ int __init acpi_numa_init(void)
|
||||||
{
|
{
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
|
if (acpi_disabled)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Should not limit number with cpu num that is from NR_CPUS or nr_cpus=
|
* 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.
|
* 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 */
|
/* SRAT: Static Resource Affinity Table */
|
||||||
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
|
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));
|
memset(srat_proc, 0, sizeof(srat_proc));
|
||||||
srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
|
srat_proc[0].id = ACPI_SRAT_TYPE_CPU_AFFINITY;
|
||||||
srat_proc[0].handler = acpi_parse_processor_affinity;
|
srat_proc[0].handler = acpi_parse_processor_affinity;
|
||||||
srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY;
|
srat_proc[1].id = ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY;
|
||||||
srat_proc[1].handler = acpi_parse_x2apic_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,
|
acpi_table_parse_entries_array(ACPI_SIG_SRAT,
|
||||||
sizeof(struct acpi_table_srat),
|
sizeof(struct acpi_table_srat),
|
||||||
|
@ -347,8 +467,6 @@ int __init acpi_numa_init(void)
|
||||||
/* SLIT: System Locality Information Table */
|
/* SLIT: System Locality Information Table */
|
||||||
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
|
acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
|
||||||
|
|
||||||
acpi_numa_arch_fixup();
|
|
||||||
|
|
||||||
if (cnt < 0)
|
if (cnt < 0)
|
||||||
return cnt;
|
return cnt;
|
||||||
else if (!parsed_numa_memblks)
|
else if (!parsed_numa_memblks)
|
||||||
|
|
|
@ -108,13 +108,12 @@ static int map_gicc_mpidr(struct acpi_subtable_header *entry,
|
||||||
return -EINVAL;
|
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;
|
unsigned long madt_end, entry;
|
||||||
phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
|
phys_cpuid_t phys_id = PHYS_CPUID_INVALID; /* CPU hardware ID */
|
||||||
struct acpi_table_madt *madt;
|
|
||||||
|
|
||||||
madt = get_madt_table();
|
|
||||||
if (!madt)
|
if (!madt)
|
||||||
return phys_id;
|
return phys_id;
|
||||||
|
|
||||||
|
@ -145,6 +144,25 @@ static phys_cpuid_t map_madt_entry(int type, u32 acpi_id)
|
||||||
return phys_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)
|
static phys_cpuid_t map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
|
||||||
{
|
{
|
||||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
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);
|
phys_id = map_mat_entry(handle, type, acpi_id);
|
||||||
if (invalid_phys_cpuid(phys_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;
|
return phys_id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,8 +91,8 @@ static int __init of_numa_parse_memory_nodes(void)
|
||||||
pr_debug("NUMA: base = %llx len = %llx, node = %u\n",
|
pr_debug("NUMA: base = %llx len = %llx, node = %u\n",
|
||||||
rsrc.start, rsrc.end - rsrc.start + 1, nid);
|
rsrc.start, rsrc.end - rsrc.start + 1, nid);
|
||||||
|
|
||||||
r = numa_add_memblk(nid, rsrc.start,
|
|
||||||
rsrc.end - rsrc.start + 1);
|
r = numa_add_memblk(nid, rsrc.start, rsrc.end + 1);
|
||||||
if (r)
|
if (r)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@ extern int pxm_to_node(int);
|
||||||
extern int node_to_pxm(int);
|
extern int node_to_pxm(int);
|
||||||
extern int acpi_map_pxm_to_node(int);
|
extern int acpi_map_pxm_to_node(int);
|
||||||
extern unsigned char acpi_srat_revision;
|
extern unsigned char acpi_srat_revision;
|
||||||
|
extern int acpi_numa __initdata;
|
||||||
|
|
||||||
|
extern void bad_srat(void);
|
||||||
|
extern int srat_disabled(void);
|
||||||
|
|
||||||
#endif /* CONFIG_ACPI_NUMA */
|
#endif /* CONFIG_ACPI_NUMA */
|
||||||
#endif /* __ACP_NUMA_H */
|
#endif /* __ACP_NUMA_H */
|
||||||
|
|
|
@ -309,6 +309,7 @@ static inline int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
|
||||||
|
|
||||||
/* in processor_core.c */
|
/* in processor_core.c */
|
||||||
phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id);
|
phys_cpuid_t acpi_get_phys_id(acpi_handle, int type, u32 acpi_id);
|
||||||
|
phys_cpuid_t acpi_map_madt_entry(u32 acpi_id);
|
||||||
int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
|
int acpi_map_cpuid(phys_cpuid_t phys_id, u32 acpi_id);
|
||||||
int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
|
int acpi_get_cpuid(acpi_handle, int type, u32 acpi_id);
|
||||||
|
|
||||||
|
|
|
@ -232,12 +232,26 @@ int acpi_table_parse_madt(enum acpi_madt_type id,
|
||||||
int acpi_parse_mcfg (struct acpi_table_header *header);
|
int acpi_parse_mcfg (struct acpi_table_header *header);
|
||||||
void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
|
void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
|
||||||
|
|
||||||
/* the following four functions are architecture-dependent */
|
/* the following numa functions are architecture-dependent */
|
||||||
void acpi_numa_slit_init (struct acpi_table_slit *slit);
|
void acpi_numa_slit_init (struct acpi_table_slit *slit);
|
||||||
|
|
||||||
|
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
|
||||||
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
|
void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
|
||||||
|
#else
|
||||||
|
static inline void
|
||||||
|
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
|
void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARM64
|
||||||
|
void acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa);
|
||||||
|
#else
|
||||||
|
static inline void
|
||||||
|
acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
|
int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
|
||||||
void acpi_numa_arch_fixup(void);
|
|
||||||
|
|
||||||
#ifndef PHYS_CPUID_INVALID
|
#ifndef PHYS_CPUID_INVALID
|
||||||
typedef u32 phys_cpuid_t;
|
typedef u32 phys_cpuid_t;
|
||||||
|
|
Loading…
Reference in New Issue