# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1242831770 -3600
# Node ID 89e50c449307631bbbe3366e3cd804ce4c2efd68
# Parent b0966b6f5180507d5e1b5c32be08cac4ea58c569
ACPI/NUMA: Improve SRAT parsing
This is to properly handle SRAT rev 2 extended proximity domain
values.
Also a first step to eliminate the redundant definitions of
ACPI provided table structures (Linux eliminated all of the duplicates
from include/linux/acpi.h in 2.6.21).
Portions based on a Linux patch from Kurt Garloff <garloff@xxxxxxx>
and Alexey Starikovskiy <astarikovskiy@xxxxxxx>.
IA64 build tested only.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
xen/arch/ia64/linux-xen/acpi.c | 36 ++++++------------
xen/arch/x86/srat.c | 42 ++++++++++++---------
xen/drivers/acpi/numa.c | 58 +++++++++++++++++++-----------
xen/include/asm-ia64/linux-xen/asm/numa.h | 2 +
xen/include/asm-x86/numa.h | 2 +
xen/include/xen/acpi.h | 33 +----------------
6 files changed, 81 insertions(+), 92 deletions(-)
diff -r b0966b6f5180 -r 89e50c449307 xen/arch/ia64/linux-xen/acpi.c
--- a/xen/arch/ia64/linux-xen/acpi.c Wed May 20 15:38:34 2009 +0100
+++ b/xen/arch/ia64/linux-xen/acpi.c Wed May 20 16:02:50 2009 +0100
@@ -55,6 +55,7 @@
#include <asm/xen/hypervisor.h>
#ifdef XEN
#include <asm/hw_irq.h>
+#include <asm/numa.h>
extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
#endif
@@ -484,22 +485,28 @@ static struct acpi_table_slit __initdata
static struct acpi_table_slit __initdata *slit_table;
cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
-static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
+static int __init
+get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
{
int pxm;
pxm = pa->proximity_domain_lo;
- if (ia64_platform_is("sn2"))
+ if (srat_rev >= 2) {
+ pxm += pa->proximity_domain_hi[0] << 8;
+ pxm += pa->proximity_domain_hi[1] << 16;
+ pxm += pa->proximity_domain_hi[2] << 24;
+ } else if (ia64_platform_is("sn2"))
pxm += pa->proximity_domain_hi[0] << 8;
return pxm;
}
-static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
+static int __init
+get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
{
int pxm;
pxm = ma->proximity_domain;
- if (!ia64_platform_is("sn2"))
+ if (!ia64_platform_is("sn2") && srat_rev < 2)
pxm &= 0xff;
return pxm;
@@ -525,17 +532,9 @@ void __init acpi_numa_slit_init(struct a
slit_table = slit;
}
-#ifndef XEN
void __init
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
-#else
-void __init
-acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa__)
-#endif
-{
-#ifdef XEN
- struct acpi_srat_cpu_affinity *pa = (struct acpi_srat_cpu_affinity
*)pa__;
-#endif
+{
int pxm;
if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
@@ -554,18 +553,9 @@ acpi_numa_processor_affinity_init (struc
srat_num_cpus++;
}
-#ifndef XEN
void __init
acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
-#else
-void __init
-acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma__)
-#endif
-{
-#ifdef XEN
- struct acpi_srat_mem_affinity *ma =
- (struct acpi_srat_mem_affinity *)ma__;
-#endif
+{
unsigned long paddr, size;
int pxm;
struct node_memblk_s *p, *q, *pend;
diff -r b0966b6f5180 -r 89e50c449307 xen/arch/x86/srat.c
--- a/xen/arch/x86/srat.c Wed May 20 15:38:34 2009 +0100
+++ b/xen/arch/x86/srat.c Wed May 20 16:02:50 2009 +0100
@@ -132,17 +132,23 @@ void __init acpi_numa_slit_init(struct a
/* Callback for Proximity Domain -> LAPIC mapping */
void __init
-acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
+acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
{
int pxm, node;
if (srat_disabled())
return;
- if (pa->header.length != sizeof(struct acpi_table_processor_affinity))
{ bad_srat();
- return;
- }
- if (pa->flags.enabled == 0)
- return;
- pxm = pa->proximity_domain;
+ if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
+ bad_srat();
+ return;
+ }
+ if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
+ return;
+ pxm = pa->proximity_domain_lo;
+ if (srat_rev >= 2) {
+ pxm |= pa->proximity_domain_hi[0] << 8;
+ pxm |= pa->proximity_domain_hi[1] << 16;
+ pxm |= pa->proximity_domain_hi[2] << 24;
+ }
node = setup_node(pxm);
if (node < 0) {
printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
@@ -157,7 +163,7 @@ acpi_numa_processor_affinity_init(struct
/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
void __init
-acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
+acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
struct node *nd;
u64 start, end;
@@ -166,15 +172,17 @@ acpi_numa_memory_affinity_init(struct ac
if (srat_disabled())
return;
- if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) {
- bad_srat();
- return;
- }
- if (ma->flags.enabled == 0)
- return;
- start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
- end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
+ if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
+ bad_srat();
+ return;
+ }
+ if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
+ return;
+ start = ma->base_address;
+ end = start + ma->length;
pxm = ma->proximity_domain;
+ if (srat_rev < 2)
+ pxm &= 0xff;
node = setup_node(pxm);
if (node < 0) {
printk(KERN_ERR "SRAT: Too many proximity domains.\n");
@@ -182,7 +190,7 @@ acpi_numa_memory_affinity_init(struct ac
return;
}
/* It is fine to add this area to the nodes data it will be used later*/
- if (ma->flags.hot_pluggable == 1)
+ if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
printk(KERN_INFO "SRAT: hot plug zone found %"PRIx64" -
%"PRIx64" \n",
start, end);
i = conflicting_nodes(start, end);
diff -r b0966b6f5180 -r 89e50c449307 xen/drivers/acpi/numa.c
--- a/xen/drivers/acpi/numa.c Wed May 20 15:38:34 2009 +0100
+++ b/xen/drivers/acpi/numa.c Wed May 20 16:02:50 2009 +0100
@@ -35,6 +35,8 @@
#define _COMPONENT ACPI_NUMA
ACPI_MODULE_NAME("numa")
+int __initdata srat_rev;
+
void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
{
@@ -48,14 +50,21 @@ void __init acpi_table_print_srat_entry(
case ACPI_SRAT_PROCESSOR_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
{
- struct acpi_table_processor_affinity *p =
- (struct acpi_table_processor_affinity *)header;
+ struct acpi_srat_cpu_affinity *p =
+ container_of(header, struct acpi_srat_cpu_affinity,
header);
+ u32 proximity_domain = p->proximity_domain_lo;
+
+ if (srat_rev >= 2) {
+ proximity_domain |= p->proximity_domain_hi[0]
<< 8;
+ proximity_domain |= p->proximity_domain_hi[1]
<< 16;
+ proximity_domain |= p->proximity_domain_hi[2]
<< 24;
+ }
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"SRAT Processor (id[0x%02x]
eid[0x%02x]) in proximity domain %d %s\n",
- p->apic_id, p->lsapic_eid,
- p->proximity_domain,
- p->flags.
- enabled ? "enabled" : "disabled"));
+ p->apic_id, p->local_sapic_eid,
+ proximity_domain,
+ p->flags & ACPI_SRAT_CPU_ENABLED
+ ? "enabled" : "disabled"));
}
#endif /* ACPI_DEBUG_OUTPUT */
break;
@@ -63,18 +72,20 @@ void __init acpi_table_print_srat_entry(
case ACPI_SRAT_MEMORY_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
{
- struct acpi_table_memory_affinity *p =
- (struct acpi_table_memory_affinity *)header;
+ struct acpi_srat_mem_affinity *p =
+ container_of(header, struct acpi_srat_mem_affinity,
header);
+ u32 proximity_domain = p->proximity_domain;
+
+ if (srat_rev < 2)
+ proximity_domain &= 0xff;
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "SRAT Memory (0x%08x%08x length
0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
- p->base_addr_hi, p->base_addr_lo,
- p->length_hi, p->length_lo,
- p->memory_type, p->proximity_domain,
- p->flags.
- enabled ? "enabled" : "disabled",
- p->flags.
- hot_pluggable ? " hot-pluggable" :
- ""));
+ "SRAT Memory (0x%016"PRIx64" length
0x%016"PRIx64" type 0x%x) in proximity domain %d %s%s\n",
+ p->base_address, p->length,
+ p->memory_type, proximity_domain,
+ p->flags & ACPI_SRAT_MEM_ENABLED
+ ? "enabled" : "disabled",
+ p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE
+ ? " hot-pluggable" : ""));
}
#endif /* ACPI_DEBUG_OUTPUT */
break;
@@ -98,9 +109,9 @@ acpi_parse_processor_affinity(struct acp
acpi_parse_processor_affinity(struct acpi_subtable_header * header,
const unsigned long end)
{
- struct acpi_table_processor_affinity *processor_affinity;
+ struct acpi_srat_cpu_affinity *processor_affinity
+ = container_of(header, struct acpi_srat_cpu_affinity, header);
- processor_affinity = (struct acpi_table_processor_affinity *)header;
if (!processor_affinity)
return -EINVAL;
@@ -116,9 +127,9 @@ acpi_parse_memory_affinity(struct acpi_s
acpi_parse_memory_affinity(struct acpi_subtable_header * header,
const unsigned long end)
{
- struct acpi_table_memory_affinity *memory_affinity;
+ struct acpi_srat_mem_affinity *memory_affinity
+ = container_of(header, struct acpi_srat_mem_affinity, header);
- memory_affinity = (struct acpi_table_memory_affinity *)header;
if (!memory_affinity)
return -EINVAL;
@@ -132,6 +143,11 @@ acpi_parse_memory_affinity(struct acpi_s
static int __init acpi_parse_srat(struct acpi_table_header *table)
{
+ if (!table)
+ return -EINVAL;
+
+ srat_rev = table->revision;
+
return 0;
}
diff -r b0966b6f5180 -r 89e50c449307 xen/include/asm-ia64/linux-xen/asm/numa.h
--- a/xen/include/asm-ia64/linux-xen/asm/numa.h Wed May 20 15:38:34 2009 +0100
+++ b/xen/include/asm-ia64/linux-xen/asm/numa.h Wed May 20 16:02:50 2009 +0100
@@ -24,6 +24,8 @@
#include <linux/threads.h>
#include <asm/mmzone.h>
+
+extern int srat_rev;
extern u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
#ifndef XEN
diff -r b0966b6f5180 -r 89e50c449307 xen/include/asm-x86/numa.h
--- a/xen/include/asm-x86/numa.h Wed May 20 15:38:34 2009 +0100
+++ b/xen/include/asm-x86/numa.h Wed May 20 16:02:50 2009 +0100
@@ -4,6 +4,8 @@
#include <xen/cpumask.h>
#define NODES_SHIFT 6
+
+extern int srat_rev;
extern unsigned char cpu_to_node[];
extern cpumask_t node_to_cpumask[];
diff -r b0966b6f5180 -r 89e50c449307 xen/include/xen/acpi.h
--- a/xen/include/xen/acpi.h Wed May 20 15:38:34 2009 +0100
+++ b/xen/include/xen/acpi.h Wed May 20 16:02:50 2009 +0100
@@ -176,35 +176,6 @@ enum acpi_srat_entry_id {
ACPI_SRAT_ENTRY_COUNT
};
-struct acpi_table_processor_affinity {
- struct acpi_subtable_header header;
- u8 proximity_domain;
- u8 apic_id;
- struct {
- u32 enabled:1;
- u32 reserved:31;
- } flags;
- u8 lsapic_eid;
- u8 reserved[7];
-} __attribute__ ((packed));
-
-struct acpi_table_memory_affinity {
- struct acpi_subtable_header header;
- u8 proximity_domain;
- u8 reserved1[5];
- u32 base_addr_lo;
- u32 base_addr_hi;
- u32 length_lo;
- u32 length_hi;
- u32 memory_type; /* See acpi_address_range_id */
- struct {
- u32 enabled:1;
- u32 hot_pluggable:1;
- u32 reserved:30;
- } flags;
- u64 reserved2;
-} __attribute__ ((packed));
-
enum acpi_address_range_id {
ACPI_ADDRESS_RANGE_MEMORY = 1,
ACPI_ADDRESS_RANGE_RESERVED = 2,
@@ -297,8 +268,8 @@ void acpi_table_print_srat_entry (struct
/* the following four functions are architecture-dependent */
void acpi_numa_slit_init (struct acpi_table_slit *slit);
-void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity
*pa);
-void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma);
+void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
+void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
void acpi_numa_arch_fixup(void);
#ifdef CONFIG_ACPI_HOTPLUG_CPU
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|