ia64/xen-unstable

changeset 19633:89e50c449307

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@suse.de>
and Alexey Starikovskiy <astarikovskiy@suse.de>.

IA64 build tested only.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed May 20 16:02:50 2009 +0100 (2009-05-20)
parents b0966b6f5180
children 61404d971c92
files xen/arch/ia64/linux-xen/acpi.c xen/arch/x86/srat.c xen/drivers/acpi/numa.c xen/include/asm-ia64/linux-xen/asm/numa.h xen/include/asm-x86/numa.h xen/include/xen/acpi.h
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/acpi.c	Wed May 20 15:38:34 2009 +0100
     1.2 +++ b/xen/arch/ia64/linux-xen/acpi.c	Wed May 20 16:02:50 2009 +0100
     1.3 @@ -55,6 +55,7 @@
     1.4  #include <asm/xen/hypervisor.h>
     1.5  #ifdef XEN
     1.6  #include <asm/hw_irq.h>
     1.7 +#include <asm/numa.h>
     1.8  extern u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES];
     1.9  #endif
    1.10  
    1.11 @@ -484,22 +485,28 @@ static u32 __devinitdata pxm_flag[PXM_FL
    1.12  static struct acpi_table_slit __initdata *slit_table;
    1.13  cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
    1.14  
    1.15 -static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
    1.16 +static int __init
    1.17 +get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
    1.18  {
    1.19  	int pxm;
    1.20  
    1.21  	pxm = pa->proximity_domain_lo;
    1.22 -	if (ia64_platform_is("sn2"))
    1.23 +	if (srat_rev >= 2) {
    1.24 +		pxm += pa->proximity_domain_hi[0] << 8;
    1.25 +		pxm += pa->proximity_domain_hi[1] << 16;
    1.26 +		pxm += pa->proximity_domain_hi[2] << 24;
    1.27 +	} else if (ia64_platform_is("sn2"))
    1.28  		pxm += pa->proximity_domain_hi[0] << 8;
    1.29  	return pxm;
    1.30  }
    1.31  
    1.32 -static int get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
    1.33 +static int __init
    1.34 +get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
    1.35  {
    1.36  	int pxm;
    1.37  
    1.38  	pxm = ma->proximity_domain;
    1.39 -	if (!ia64_platform_is("sn2"))
    1.40 +	if (!ia64_platform_is("sn2") && srat_rev < 2)
    1.41  		pxm &= 0xff;
    1.42  
    1.43  	return pxm;
    1.44 @@ -525,17 +532,9 @@ void __init acpi_numa_slit_init(struct a
    1.45  	slit_table = slit;
    1.46  }
    1.47  
    1.48 -#ifndef XEN
    1.49  void __init
    1.50  acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
    1.51 -#else
    1.52 -void __init
    1.53 -acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa__)
    1.54 -#endif
    1.55  {
    1.56 -#ifdef XEN
    1.57 -	struct acpi_srat_cpu_affinity *pa = (struct acpi_srat_cpu_affinity *)pa__;
    1.58 -#endif
    1.59  	int pxm;
    1.60  
    1.61  	if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
    1.62 @@ -554,18 +553,9 @@ acpi_numa_processor_affinity_init (struc
    1.63  	srat_num_cpus++;
    1.64  }
    1.65  
    1.66 -#ifndef XEN
    1.67  void __init
    1.68  acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
    1.69 -#else
    1.70 -void __init
    1.71 -acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma__)
    1.72 -#endif
    1.73  {
    1.74 -#ifdef XEN
    1.75 -	struct acpi_srat_mem_affinity *ma =
    1.76 -		(struct acpi_srat_mem_affinity *)ma__;
    1.77 -#endif
    1.78  	unsigned long paddr, size;
    1.79  	int pxm;
    1.80  	struct node_memblk_s *p, *q, *pend;
     2.1 --- a/xen/arch/x86/srat.c	Wed May 20 15:38:34 2009 +0100
     2.2 +++ b/xen/arch/x86/srat.c	Wed May 20 16:02:50 2009 +0100
     2.3 @@ -132,17 +132,23 @@ void __init acpi_numa_slit_init(struct a
     2.4  
     2.5  /* Callback for Proximity Domain -> LAPIC mapping */
     2.6  void __init
     2.7 -acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa)
     2.8 +acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
     2.9  {
    2.10  	int pxm, node;
    2.11  	if (srat_disabled())
    2.12  		return;
    2.13 -	if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) {		bad_srat();
    2.14 +	if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
    2.15 +		bad_srat();
    2.16  		return;
    2.17  	}
    2.18 -	if (pa->flags.enabled == 0)
    2.19 +	if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
    2.20  		return;
    2.21 -	pxm = pa->proximity_domain;
    2.22 +	pxm = pa->proximity_domain_lo;
    2.23 +	if (srat_rev >= 2) {
    2.24 +		pxm |= pa->proximity_domain_hi[0] << 8;
    2.25 +		pxm |= pa->proximity_domain_hi[1] << 16;
    2.26 +		pxm |= pa->proximity_domain_hi[2] << 24;
    2.27 +	}
    2.28  	node = setup_node(pxm);
    2.29  	if (node < 0) {
    2.30  		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
    2.31 @@ -157,7 +163,7 @@ acpi_numa_processor_affinity_init(struct
    2.32  
    2.33  /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
    2.34  void __init
    2.35 -acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
    2.36 +acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
    2.37  {
    2.38  	struct node *nd;
    2.39  	u64 start, end;
    2.40 @@ -166,15 +172,17 @@ acpi_numa_memory_affinity_init(struct ac
    2.41  
    2.42  	if (srat_disabled())
    2.43  		return;
    2.44 -	if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) {
    2.45 +	if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
    2.46  		bad_srat();
    2.47  		return;
    2.48  	}
    2.49 -	if (ma->flags.enabled == 0)
    2.50 +	if (!(ma->flags & ACPI_SRAT_MEM_ENABLED))
    2.51  		return;
    2.52 -	start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32);
    2.53 -	end = start + (ma->length_lo | ((u64)ma->length_hi << 32));
    2.54 +	start = ma->base_address;
    2.55 +	end = start + ma->length;
    2.56  	pxm = ma->proximity_domain;
    2.57 +	if (srat_rev < 2)
    2.58 +		pxm &= 0xff;
    2.59  	node = setup_node(pxm);
    2.60  	if (node < 0) {
    2.61  		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
    2.62 @@ -182,7 +190,7 @@ acpi_numa_memory_affinity_init(struct ac
    2.63  		return;
    2.64  	}
    2.65  	/* It is fine to add this area to the nodes data it will be used later*/
    2.66 -	if (ma->flags.hot_pluggable == 1)
    2.67 +	if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
    2.68  		printk(KERN_INFO "SRAT: hot plug zone found %"PRIx64" - %"PRIx64" \n",
    2.69  				start, end);
    2.70  	i = conflicting_nodes(start, end);
     3.1 --- a/xen/drivers/acpi/numa.c	Wed May 20 15:38:34 2009 +0100
     3.2 +++ b/xen/drivers/acpi/numa.c	Wed May 20 16:02:50 2009 +0100
     3.3 @@ -35,6 +35,8 @@
     3.4  #define _COMPONENT	ACPI_NUMA
     3.5  ACPI_MODULE_NAME("numa")
     3.6  
     3.7 +int __initdata srat_rev;
     3.8 +
     3.9  void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
    3.10  {
    3.11  
    3.12 @@ -48,14 +50,21 @@ void __init acpi_table_print_srat_entry(
    3.13  	case ACPI_SRAT_PROCESSOR_AFFINITY:
    3.14  #ifdef ACPI_DEBUG_OUTPUT
    3.15  		{
    3.16 -			struct acpi_table_processor_affinity *p =
    3.17 -			    (struct acpi_table_processor_affinity *)header;
    3.18 +			struct acpi_srat_cpu_affinity *p =
    3.19 +			    container_of(header, struct acpi_srat_cpu_affinity, header);
    3.20 +			u32 proximity_domain = p->proximity_domain_lo;
    3.21 +
    3.22 +			if (srat_rev >= 2) {
    3.23 +				proximity_domain |= p->proximity_domain_hi[0] << 8;
    3.24 +				proximity_domain |= p->proximity_domain_hi[1] << 16;
    3.25 +				proximity_domain |= p->proximity_domain_hi[2] << 24;
    3.26 +			}
    3.27  			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    3.28  					  "SRAT Processor (id[0x%02x] eid[0x%02x]) in proximity domain %d %s\n",
    3.29 -					  p->apic_id, p->lsapic_eid,
    3.30 -					  p->proximity_domain,
    3.31 -					  p->flags.
    3.32 -					  enabled ? "enabled" : "disabled"));
    3.33 +					  p->apic_id, p->local_sapic_eid,
    3.34 +					  proximity_domain,
    3.35 +					  p->flags & ACPI_SRAT_CPU_ENABLED
    3.36 +					  ? "enabled" : "disabled"));
    3.37  		}
    3.38  #endif				/* ACPI_DEBUG_OUTPUT */
    3.39  		break;
    3.40 @@ -63,18 +72,20 @@ void __init acpi_table_print_srat_entry(
    3.41  	case ACPI_SRAT_MEMORY_AFFINITY:
    3.42  #ifdef ACPI_DEBUG_OUTPUT
    3.43  		{
    3.44 -			struct acpi_table_memory_affinity *p =
    3.45 -			    (struct acpi_table_memory_affinity *)header;
    3.46 +			struct acpi_srat_mem_affinity *p =
    3.47 +			    container_of(header, struct acpi_srat_mem_affinity, header);
    3.48 +			u32 proximity_domain = p->proximity_domain;
    3.49 +
    3.50 +			if (srat_rev < 2)
    3.51 +				proximity_domain &= 0xff;
    3.52  			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
    3.53 -					  "SRAT Memory (0x%08x%08x length 0x%08x%08x type 0x%x) in proximity domain %d %s%s\n",
    3.54 -					  p->base_addr_hi, p->base_addr_lo,
    3.55 -					  p->length_hi, p->length_lo,
    3.56 -					  p->memory_type, p->proximity_domain,
    3.57 -					  p->flags.
    3.58 -					  enabled ? "enabled" : "disabled",
    3.59 -					  p->flags.
    3.60 -					  hot_pluggable ? " hot-pluggable" :
    3.61 -					  ""));
    3.62 +					  "SRAT Memory (0x%016"PRIx64" length 0x%016"PRIx64" type 0x%x) in proximity domain %d %s%s\n",
    3.63 +					  p->base_address, p->length,
    3.64 +					  p->memory_type, proximity_domain,
    3.65 +					  p->flags & ACPI_SRAT_MEM_ENABLED
    3.66 +					  ? "enabled" : "disabled",
    3.67 +					  p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE
    3.68 +					  ? " hot-pluggable" : ""));
    3.69  		}
    3.70  #endif				/* ACPI_DEBUG_OUTPUT */
    3.71  		break;
    3.72 @@ -98,9 +109,9 @@ static int __init
    3.73  acpi_parse_processor_affinity(struct acpi_subtable_header * header,
    3.74  			      const unsigned long end)
    3.75  {
    3.76 -	struct acpi_table_processor_affinity *processor_affinity;
    3.77 +	struct acpi_srat_cpu_affinity *processor_affinity
    3.78 +		= container_of(header, struct acpi_srat_cpu_affinity, header);
    3.79  
    3.80 -	processor_affinity = (struct acpi_table_processor_affinity *)header;
    3.81  	if (!processor_affinity)
    3.82  		return -EINVAL;
    3.83  
    3.84 @@ -116,9 +127,9 @@ static int __init
    3.85  acpi_parse_memory_affinity(struct acpi_subtable_header * header,
    3.86  			   const unsigned long end)
    3.87  {
    3.88 -	struct acpi_table_memory_affinity *memory_affinity;
    3.89 +	struct acpi_srat_mem_affinity *memory_affinity
    3.90 +		= container_of(header, struct acpi_srat_mem_affinity, header);
    3.91  
    3.92 -	memory_affinity = (struct acpi_table_memory_affinity *)header;
    3.93  	if (!memory_affinity)
    3.94  		return -EINVAL;
    3.95  
    3.96 @@ -132,6 +143,11 @@ acpi_parse_memory_affinity(struct acpi_s
    3.97  
    3.98  static int __init acpi_parse_srat(struct acpi_table_header *table)
    3.99  {
   3.100 +	if (!table)
   3.101 +		return -EINVAL;
   3.102 +
   3.103 +	srat_rev = table->revision;
   3.104 +
   3.105  	return 0;
   3.106  }
   3.107  
     4.1 --- a/xen/include/asm-ia64/linux-xen/asm/numa.h	Wed May 20 15:38:34 2009 +0100
     4.2 +++ b/xen/include/asm-ia64/linux-xen/asm/numa.h	Wed May 20 16:02:50 2009 +0100
     4.3 @@ -25,6 +25,8 @@
     4.4  
     4.5  #include <asm/mmzone.h>
     4.6  
     4.7 +extern int srat_rev;
     4.8 +
     4.9  extern u8 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
    4.10  #ifndef XEN
    4.11  extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
     5.1 --- a/xen/include/asm-x86/numa.h	Wed May 20 15:38:34 2009 +0100
     5.2 +++ b/xen/include/asm-x86/numa.h	Wed May 20 16:02:50 2009 +0100
     5.3 @@ -5,6 +5,8 @@
     5.4  
     5.5  #define NODES_SHIFT 6
     5.6  
     5.7 +extern int srat_rev;
     5.8 +
     5.9  extern unsigned char cpu_to_node[];
    5.10  extern cpumask_t     node_to_cpumask[];
    5.11  
     6.1 --- a/xen/include/xen/acpi.h	Wed May 20 15:38:34 2009 +0100
     6.2 +++ b/xen/include/xen/acpi.h	Wed May 20 16:02:50 2009 +0100
     6.3 @@ -176,35 +176,6 @@ enum acpi_srat_entry_id {
     6.4  	ACPI_SRAT_ENTRY_COUNT
     6.5  };
     6.6  
     6.7 -struct acpi_table_processor_affinity {
     6.8 -	struct acpi_subtable_header	header;
     6.9 -	u8			proximity_domain;
    6.10 -	u8			apic_id;
    6.11 -	struct {
    6.12 -		u32			enabled:1;
    6.13 -		u32			reserved:31;
    6.14 -	}			flags;
    6.15 -	u8			lsapic_eid;
    6.16 -	u8			reserved[7];
    6.17 -} __attribute__ ((packed));
    6.18 -
    6.19 -struct acpi_table_memory_affinity {
    6.20 -	struct acpi_subtable_header	header;
    6.21 -	u8			proximity_domain;
    6.22 -	u8			reserved1[5];
    6.23 -	u32			base_addr_lo;
    6.24 -	u32			base_addr_hi;
    6.25 -	u32			length_lo;
    6.26 -	u32			length_hi;
    6.27 -	u32			memory_type;	/* See acpi_address_range_id */
    6.28 -	struct {
    6.29 -		u32			enabled:1;
    6.30 -		u32			hot_pluggable:1;
    6.31 -		u32			reserved:30;
    6.32 -	}			flags;
    6.33 -	u64			reserved2;
    6.34 -} __attribute__ ((packed));
    6.35 -
    6.36  enum acpi_address_range_id {
    6.37  	ACPI_ADDRESS_RANGE_MEMORY = 1,
    6.38  	ACPI_ADDRESS_RANGE_RESERVED = 2,
    6.39 @@ -297,8 +268,8 @@ void acpi_table_print_srat_entry (struct
    6.40  
    6.41  /* the following four functions are architecture-dependent */
    6.42  void acpi_numa_slit_init (struct acpi_table_slit *slit);
    6.43 -void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa);
    6.44 -void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma);
    6.45 +void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa);
    6.46 +void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
    6.47  void acpi_numa_arch_fixup(void);
    6.48  
    6.49  #ifdef CONFIG_ACPI_HOTPLUG_CPU