All of lore.kernel.org
 help / color / mirror / Atom feed
* SRAT v1 support
@ 2009-05-15 14:51 xb
  2009-05-15 18:38   ` Yinghai Lu
  0 siblings, 1 reply; 5+ messages in thread
From: xb @ 2009-05-15 14:51 UTC (permalink / raw)
  To: linux-acpi; +Cc: Zoltan

Recent linux kernels suppose that the  SRAT table is in rev 2 format 
(ACPI 3.0), but some BIOSes still provide SRAT table in rev 1.
The rev 2 of the SRAT extension mainly provides an extension of the 
"proximity_domain" item from 8 bits to 32 bits, using a "reserved" field 
of the structure.
When the "reserved" field is not null, linux finds a wrong proximity 
domain, and numa initialization is wrong.
Following patch tests the SRAT revision to allow a correct initialization:

This patch tests the version of SRAT ACPI table to allow supporting SRAT 
rev 1 and SRAT rev 2.

diff -Nru linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c 
linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c
--- linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c    2009-03-12 
14:41:38.000000000 +0100
+++ linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c    2009-03-16 
14:52:07.000000000 +0100
@@ -260,7 +260,8 @@
 }
 
 static int __init
-acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned 
long end)
+acpi_parse_lapic(const struct acpi_subtable_header * const header,
+                const unsigned long end, const int rev)
 {
     struct acpi_madt_local_apic *processor = NULL;
 
@@ -285,7 +286,8 @@
 }
 
 static int __init
-acpi_parse_sapic(struct acpi_subtable_header *header, const unsigned 
long end)
+acpi_parse_sapic(const struct acpi_subtable_header * const header,
+                const unsigned long end, const int rev)
 {
     struct acpi_madt_local_sapic *processor = NULL;
 
@@ -303,8 +305,8 @@
 }
 
 static int __init
-acpi_parse_lapic_addr_ovr(struct acpi_subtable_header * header,
-              const unsigned long end)
+acpi_parse_lapic_addr_ovr(const struct acpi_subtable_header * const header,
+                  const unsigned long end, const int rev)
 {
     struct acpi_madt_local_apic_override *lapic_addr_ovr = NULL;
 
@@ -319,7 +321,8 @@
 }
 
 static int __init
-acpi_parse_lapic_nmi(struct acpi_subtable_header * header, const 
unsigned long end)
+acpi_parse_lapic_nmi(const struct acpi_subtable_header * const header,
+                const unsigned long end, const int rev)
 {
     struct acpi_madt_local_apic_nmi *lapic_nmi = NULL;
 
@@ -341,7 +344,8 @@
 #ifdef CONFIG_X86_IO_APIC
 
 static int __init
-acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned 
long end)
+acpi_parse_ioapic(const struct acpi_subtable_header * const header,
+                const unsigned long end, const int rev)
 {
     struct acpi_madt_io_apic *ioapic = NULL;
 
@@ -392,8 +396,8 @@
 }
 
 static int __init
-acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
-               const unsigned long end)
+acpi_parse_int_src_ovr(const struct acpi_subtable_header * const header,
+               const unsigned long end, const int rev)
 {
     struct acpi_madt_interrupt_override *intsrc = NULL;
 
@@ -426,7 +430,8 @@
 }
 
 static int __init
-acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned 
long end)
+acpi_parse_nmi_src(const struct acpi_subtable_header * const header,
+                const unsigned long end, const int rev)
 {
     struct acpi_madt_nmi_source *nmi_src = NULL;
 
diff -Nru linux-2.6.29-rc7-orig/arch/x86/mm/srat_64.c 
linux-2.6.29-rc7-tmp/arch/x86/mm/srat_64.c
--- linux-2.6.29-rc7-orig/arch/x86/mm/srat_64.c    2009-03-12 
14:41:38.000000000 +0100
+++ linux-2.6.29-rc7-tmp/arch/x86/mm/srat_64.c    2009-03-16 
15:25:18.000000000 +0100
@@ -220,7 +220,7 @@
 
 /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
 void __init
-acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
+acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity * 
const ma, const int rev)
 {
     struct bootnode *nd, oldnode;
     unsigned long start, end;
@@ -240,7 +240,18 @@
         return;
     start = ma->base_address;
     end = start + ma->length;
-    pxm = ma->proximity_domain;
+    switch (rev){
+    case ACPI_SRAT_MEM_AFF_ACPI2:
+        pxm = ma->_2.proximity_domain;
+        break;
+    case ACPI_SRAT_MEM_AFF_ACPI3:
+        pxm = ma->_3.proximity_domain;
+        break;
+    default:
+        printk(KERN_ERR "SRAT: unknown memory affinity revision 
%d+1\n", rev);
+        bad_srat();
+        return;
+    }
     node = setup_node(pxm);
     if (node < 0) {
         printk(KERN_ERR "SRAT: Too many proximity domains.\n");
diff -Nru linux-2.6.29-rc7-orig/drivers/acpi/numa.c 
linux-2.6.29-rc7-tmp/drivers/acpi/numa.c
--- linux-2.6.29-rc7-orig/drivers/acpi/numa.c    2009-03-12 
14:41:43.000000000 +0100
+++ linux-2.6.29-rc7-tmp/drivers/acpi/numa.c    2009-03-16 
15:25:59.000000000 +0100
@@ -88,7 +88,8 @@
 #endif  /*  0  */
 
 static void __init
-acpi_table_print_srat_entry(struct acpi_subtable_header *header)
+acpi_table_print_srat_entry(const struct acpi_subtable_header * const 
header,
+                                const int rev)
 {
 
     ACPI_FUNCTION_NAME("acpi_table_print_srat_entry");
@@ -116,13 +117,25 @@
     case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
 #ifdef ACPI_DEBUG_OUTPUT
         {
-            struct acpi_srat_mem_affinity *p =
-                (struct acpi_srat_mem_affinity *)header;
+            struct acpi_srat_mem_affinity *p = (struct 
acpi_srat_mem_affinity *)header;
+            int pxm;
+
+            switch (rev){
+            case ACPI_SRAT_MEM_AFF_ACPI2:
+                pxm = p->_2.proximity_domain;
+                break;
+            case ACPI_SRAT_MEM_AFF_ACPI3:
+                pxm = p->_3.proximity_domain;
+                break;
+            default:
+                printk(KERN_ERR "SRAT: unknown memory affinity revision 
%d+1\n", rev);
+                pxm = 0;
+            }
             ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                       "SRAT Memory (0x%lx length 0x%lx) in proximity 
domain %d %s%s\n",
                       (unsigned long)p->base_address,
                       (unsigned long)p->length,
-                      p->proximity_domain,
+                      pxm,
                       (p->flags & ACPI_SRAT_MEM_ENABLED)?
                       "enabled" : "disabled",
                       (p->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)?
@@ -181,8 +194,8 @@
 }
 
 static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
-                  const unsigned long end)
+acpi_parse_processor_affinity(const struct acpi_subtable_header * const 
header,
+                  const unsigned long end, const int rev)
 {
     struct acpi_srat_cpu_affinity *processor_affinity;
 
@@ -190,7 +203,7 @@
     if (!processor_affinity)
         return -EINVAL;
 
-    acpi_table_print_srat_entry(header);
+    acpi_table_print_srat_entry(header, rev);
 
     /* let architecture-dependent part to do it */
     acpi_numa_processor_affinity_init(processor_affinity);
@@ -199,8 +212,8 @@
 }
 
 static int __init
-acpi_parse_memory_affinity(struct acpi_subtable_header * header,
-               const unsigned long end)
+acpi_parse_memory_affinity(const struct acpi_subtable_header * const 
header,
+                   const unsigned long end, const int rev)
 {
     struct acpi_srat_mem_affinity *memory_affinity;
 
@@ -208,10 +221,10 @@
     if (!memory_affinity)
         return -EINVAL;
 
-    acpi_table_print_srat_entry(header);
+    acpi_table_print_srat_entry(header, rev);
 
     /* let architecture-dependent part to do it */
-    acpi_numa_memory_affinity_init(memory_affinity);
+    acpi_numa_memory_affinity_init(memory_affinity, rev);
 
     return 0;
 }
@@ -239,7 +252,7 @@
 
 int __init acpi_numa_init(void)
 {
-    /* SRAT: Static Resource Affinity Table */
+    /* SRAT: Static/System Resource Affinity Table */
     if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
         acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
                       acpi_parse_processor_affinity, NR_CPUS);
diff -Nru linux-2.6.29-rc7-orig/drivers/acpi/tables.c 
linux-2.6.29-rc7-tmp/drivers/acpi/tables.c
--- linux-2.6.29-rc7-orig/drivers/acpi/tables.c    2009-03-12 
14:41:43.000000000 +0100
+++ linux-2.6.29-rc7-tmp/drivers/acpi/tables.c    2009-03-16 
15:01:05.000000000 +0100
@@ -44,7 +44,7 @@
 
 static int acpi_apic_instance __initdata;
 
-void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
+void acpi_table_print_madt_entry(const struct acpi_subtable_header * 
const header)
 {
     if (!header)
         return;
@@ -206,7 +206,7 @@
            table_end) {
         if (entry->type == entry_id
             && (!max_entries || count++ < max_entries))
-            if (handler(entry, table_end))
+            if (handler(entry, table_end, table_header->revision))
                 return -EINVAL;
 
         entry = (struct acpi_subtable_header *)
diff -Nru linux-2.6.29-rc7-orig/include/acpi/actbl1.h 
linux-2.6.29-rc7-tmp/include/acpi/actbl1.h
--- linux-2.6.29-rc7-orig/include/acpi/actbl1.h    2009-03-12 
14:41:40.000000000 +0100
+++ linux-2.6.29-rc7-tmp/include/acpi/actbl1.h    2009-03-16 
14:53:14.000000000 +0100
@@ -1193,16 +1193,26 @@
 };
 
 /* 1: Memory Affinity */
+#define    ACPI_SRAT_MEM_AFF_ACPI2    1
+#define    ACPI_SRAT_MEM_AFF_ACPI3    2
 
 struct acpi_srat_mem_affinity {
     struct acpi_subtable_header header;
-    u32 proximity_domain;
-    u16 reserved;        /* Reserved, must be zero */
+    union {
+        struct {        /* ACPI 2 */
+            u8 proximity_domain;
+            u8 reserved[5];    /* Reserved, must be zero */
+        } _2;
+        struct {        /* ACPI 3 */
+            u32 proximity_domain;
+            u16 reserved;    /* Reserved, must be zero */
+        } _3;
+    };
     u64 base_address;
     u64 length;
-       u32 reserved1;
+    u32 reserved1;
     u32 flags;
-       u64 reserved2;           /* Reserved, must be zero */
+    u64 reserved2;            /* Reserved, must be zero */
 };
 
 /* Flags */
diff -Nru linux-2.6.29-rc7-orig/include/linux/acpi.h 
linux-2.6.29-rc7-tmp/include/linux/acpi.h
--- linux-2.6.29-rc7-orig/include/linux/acpi.h    2009-03-12 
14:41:40.000000000 +0100
+++ linux-2.6.29-rc7-tmp/include/linux/acpi.h    2009-03-16 
15:19:07.000000000 +0100
@@ -76,7 +76,8 @@
 
 typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 
-typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header 
*header, const unsigned long end);
+typedef int (*acpi_table_entry_handler) (const struct 
acpi_subtable_header * const header,
+                    const unsigned long end, const int revision);
 
 char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
 int early_acpi_boot_init(void);
@@ -91,12 +92,12 @@
     int entry_id, acpi_table_entry_handler handler, unsigned int 
max_entries);
 int acpi_table_parse_madt (enum acpi_madt_type id, 
acpi_table_entry_handler handler, unsigned int max_entries);
 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 (const struct acpi_subtable_header * 
const madt);
 
 /* 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_srat_cpu_affinity *pa);
-void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma);
+void acpi_numa_memory_affinity_init (const struct 
acpi_srat_mem_affinity * const ma, const int rev);
 void acpi_numa_arch_fixup(void);
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: SRAT v1 support
  2009-05-15 14:51 SRAT v1 support xb
@ 2009-05-15 18:38   ` Yinghai Lu
  0 siblings, 0 replies; 5+ messages in thread
From: Yinghai Lu @ 2009-05-15 18:38 UTC (permalink / raw)
  To: xb, Ingo Molnar, H. Peter Anvin, Suresh Siddha, Andrew Morton,
	Len
  Cc: linux-acpi, Zoltan, Linux Kernel Mailing List

On Fri, May 15, 2009 at 7:51 AM, xb <xavier.bru@bull.net> wrote:
> Recent linux kernels suppose that the  SRAT table is in rev 2 format (ACPI
> 3.0), but some BIOSes still provide SRAT table in rev 1.
> The rev 2 of the SRAT extension mainly provides an extension of the
> "proximity_domain" item from 8 bits to 32 bits, using a "reserved" field of
> the structure.
> When the "reserved" field is not null, linux finds a wrong proximity domain,
> and numa initialization is wrong.
> Following patch tests the SRAT revision to allow a correct initialization:
>
> This patch tests the version of SRAT ACPI table to allow supporting SRAT rev
> 1 and SRAT rev 2.
>
> diff -Nru linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c
> linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c
> --- linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c    2009-03-12
> 14:41:38.000000000 +0100
> +++ linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c    2009-03-16
> 14:52:07.000000000 +0100
> @@ -260,7 +260,8 @@
> }
>
> static int __init
> -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long
> end)
> +acpi_parse_lapic(const struct acpi_subtable_header * const header,
> +                const unsigned long end, const int rev)

do we need to pass that rev all over around?

looks like we could use one srat_version or pxm_mask variable to get
the same result.

YH
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: SRAT v1 support
@ 2009-05-15 18:38   ` Yinghai Lu
  0 siblings, 0 replies; 5+ messages in thread
From: Yinghai Lu @ 2009-05-15 18:38 UTC (permalink / raw)
  To: xb, Ingo Molnar, H. Peter Anvin, Suresh Siddha, Andrew Morton,
	Len Brown
  Cc: linux-acpi, Zoltan, Linux Kernel Mailing List

On Fri, May 15, 2009 at 7:51 AM, xb <xavier.bru@bull.net> wrote:
> Recent linux kernels suppose that the  SRAT table is in rev 2 format (ACPI
> 3.0), but some BIOSes still provide SRAT table in rev 1.
> The rev 2 of the SRAT extension mainly provides an extension of the
> "proximity_domain" item from 8 bits to 32 bits, using a "reserved" field of
> the structure.
> When the "reserved" field is not null, linux finds a wrong proximity domain,
> and numa initialization is wrong.
> Following patch tests the SRAT revision to allow a correct initialization:
>
> This patch tests the version of SRAT ACPI table to allow supporting SRAT rev
> 1 and SRAT rev 2.
>
> diff -Nru linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c
> linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c
> --- linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c    2009-03-12
> 14:41:38.000000000 +0100
> +++ linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c    2009-03-16
> 14:52:07.000000000 +0100
> @@ -260,7 +260,8 @@
> }
>
> static int __init
> -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long
> end)
> +acpi_parse_lapic(const struct acpi_subtable_header * const header,
> +                const unsigned long end, const int rev)

do we need to pass that rev all over around?

looks like we could use one srat_version or pxm_mask variable to get
the same result.

YH

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: SRAT v1 support
  2009-05-15 18:38   ` Yinghai Lu
@ 2009-05-18 11:19     ` xb
  -1 siblings, 0 replies; 5+ messages in thread
From: xb @ 2009-05-18 11:19 UTC (permalink / raw)
  Cc: linux-acpi, Linux Kernel Mailing List

yes, could be simpler :-)

    I just saw that Kurt Garloff from Suse has published 3 patches on 
kernel mailing list that fixes the SRAT v1 issue:
    [PATCH 0/3]: Discard reserved PXM bits for SRAT v1
    [PATCH 1/3]: Store SRAT revision
    [PATCH 2/3]: x86-64: Handle SRAT v1 and v2 consistently

    It looks OK for us.

Thanks.
Xavier


Yinghai Lu wrote:
> On Fri, May 15, 2009 at 7:51 AM, xb <xavier.bru@bull.net> wrote:
>   
>> Recent linux kernels suppose that the  SRAT table is in rev 2 format (ACPI
>> 3.0), but some BIOSes still provide SRAT table in rev 1.
>> The rev 2 of the SRAT extension mainly provides an extension of the
>> "proximity_domain" item from 8 bits to 32 bits, using a "reserved" field of
>> the structure.
>> When the "reserved" field is not null, linux finds a wrong proximity domain,
>> and numa initialization is wrong.
>> Following patch tests the SRAT revision to allow a correct initialization:
>>
>> This patch tests the version of SRAT ACPI table to allow supporting SRAT rev
>> 1 and SRAT rev 2.
>>
>> diff -Nru linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c
>> linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c
>> --- linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c    2009-03-12
>> 14:41:38.000000000 +0100
>> +++ linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c    2009-03-16
>> 14:52:07.000000000 +0100
>> @@ -260,7 +260,8 @@
>> }
>>
>> static int __init
>> -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long
>> end)
>> +acpi_parse_lapic(const struct acpi_subtable_header * const header,
>> +                const unsigned long end, const int rev)
>>     
>
> do we need to pass that rev all over around?
>
> looks like we could use one srat_version or pxm_mask variable to get
> the same result.
>
> YH
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>   

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: SRAT v1 support
@ 2009-05-18 11:19     ` xb
  0 siblings, 0 replies; 5+ messages in thread
From: xb @ 2009-05-18 11:19 UTC (permalink / raw)
  Cc: linux-acpi, Linux Kernel Mailing List

yes, could be simpler :-)

    I just saw that Kurt Garloff from Suse has published 3 patches on 
kernel mailing list that fixes the SRAT v1 issue:
    [PATCH 0/3]: Discard reserved PXM bits for SRAT v1
    [PATCH 1/3]: Store SRAT revision
    [PATCH 2/3]: x86-64: Handle SRAT v1 and v2 consistently

    It looks OK for us.

Thanks.
Xavier


Yinghai Lu wrote:
> On Fri, May 15, 2009 at 7:51 AM, xb <xavier.bru@bull.net> wrote:
>   
>> Recent linux kernels suppose that the  SRAT table is in rev 2 format (ACPI
>> 3.0), but some BIOSes still provide SRAT table in rev 1.
>> The rev 2 of the SRAT extension mainly provides an extension of the
>> "proximity_domain" item from 8 bits to 32 bits, using a "reserved" field of
>> the structure.
>> When the "reserved" field is not null, linux finds a wrong proximity domain,
>> and numa initialization is wrong.
>> Following patch tests the SRAT revision to allow a correct initialization:
>>
>> This patch tests the version of SRAT ACPI table to allow supporting SRAT rev
>> 1 and SRAT rev 2.
>>
>> diff -Nru linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c
>> linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c
>> --- linux-2.6.29-rc7-orig/arch/x86/kernel/acpi/boot.c    2009-03-12
>> 14:41:38.000000000 +0100
>> +++ linux-2.6.29-rc7-tmp/arch/x86/kernel/acpi/boot.c    2009-03-16
>> 14:52:07.000000000 +0100
>> @@ -260,7 +260,8 @@
>> }
>>
>> static int __init
>> -acpi_parse_lapic(struct acpi_subtable_header * header, const unsigned long
>> end)
>> +acpi_parse_lapic(const struct acpi_subtable_header * const header,
>> +                const unsigned long end, const int rev)
>>     
>
> do we need to pass that rev all over around?
>
> looks like we could use one srat_version or pxm_mask variable to get
> the same result.
>
> YH
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
>   

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-05-18 11:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-15 14:51 SRAT v1 support xb
2009-05-15 18:38 ` Yinghai Lu
2009-05-15 18:38   ` Yinghai Lu
2009-05-18 11:19   ` xb
2009-05-18 11:19     ` xb

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.