LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
@ 2013-01-21 21:39 Yinghai Lu
[not found] ` <CAE9FiQX0bUdWz6bmqLKDHpY5mvjEYdobseroCRnu0-Ju0qmsPw@mail.gmail.com>
0 siblings, 1 reply; 8+ messages in thread
From: Yinghai Lu @ 2013-01-21 21:39 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, linux-acpi, Yinghai Lu, Suresh Siddha,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton,
linux-kernel
One system have mixing xapic and x2apic entries in MADT and SRAT.
BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
the cpus are with x2apic mode pre-enabled, still need to use xapic entries
instead of x2apic entries.
on 8 socket system with x2apic pre-enabled, will get out of order sequence:
CPU0: socket0, core0, thread0.
CPU1 - CPU 40: socket 4 - socket 7, thread 0
CPU41 - CPU 80: socket 4 - socket 7, thread 1
CPU81 - CPU 119: socket 0 - socket 3, thread 0
CPU120 - CPU 159: socket 0 - socket 3, thread 1
so max_cpus=80 will not get all thread0 now.
Need to handle every entry in MADT at same time with xapic and x2apic.
so we can honor sequence in MADT.
We can use max_cpus= command line to use thread0 in every core,
because recent MADT always have all thread0 at first.
Also it could make the cpu to node mapping more sane.
after patch will get
CPU0 - CPU 79: socket 0 - socket 7, thread 0
CPU80 - CPU 159: socket 0 - socket 7, thread 1
-v2: update some comments, and change to pass array pointer.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++-----
drivers/acpi/numa.c | 16 +++++++--
drivers/acpi/tables.c | 75 ++++++++++++++++++++++++++++++++------------
include/linux/acpi.h | 9 +++++
4 files changed, 97 insertions(+), 33 deletions(-)
Index: linux-2.6/drivers/acpi/tables.c
===================================================================
--- linux-2.6.orig/drivers/acpi/tables.c
+++ linux-2.6/drivers/acpi/tables.c
@@ -199,12 +199,10 @@ void acpi_table_print_madt_entry(struct
}
}
-
int __init
-acpi_table_parse_entries(char *id,
+acpi_table_parse_entries_array(char *id,
unsigned long table_size,
- int entry_id,
- acpi_tbl_entry_handler handler,
+ struct acpi_subtable_proc *proc, int proc_num,
unsigned int max_entries)
{
struct acpi_table_header *table_header = NULL;
@@ -212,12 +210,12 @@ acpi_table_parse_entries(char *id,
unsigned int count = 0;
unsigned long table_end;
acpi_size tbl_size;
+ int i;
- if (acpi_disabled)
+ if (acpi_disabled) {
+ proc[0].count = -ENODEV;
return -ENODEV;
-
- if (!handler)
- return -EINVAL;
+ }
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
@@ -226,6 +224,7 @@ acpi_table_parse_entries(char *id,
if (!table_header) {
printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+ proc[0].count = -ENODEV;
return -ENODEV;
}
@@ -238,33 +237,69 @@ acpi_table_parse_entries(char *id,
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) {
- if (entry->type == entry_id
- && (!max_entries || count++ < max_entries))
- if (handler(entry, table_end))
- goto err;
+ for (i = 0; i < proc_num; i++) {
+ if (entry->type != proc[i].id)
+ continue;
+ if (max_entries && count++ >= max_entries)
+ continue;
+ if (proc[i].handler(entry, table_end)) {
+ early_acpi_os_unmap_memory((char *)table_header,
+ tbl_size);
+ proc[i].count = -EINVAL;
+ return -EINVAL;
+ }
+ proc[i].count++;
+ break;
+ }
/*
* If entry->length is 0, break from this loop to avoid
* infinite loop.
*/
if (entry->length == 0) {
- pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
- goto err;
- }
+ pr_err(PREFIX "[%4.4s:0x%02x ", id, proc[0].id);
+ for (i = 1; i < proc_num; i++)
+ printk(KERN_CONT " 0x%02x", proc[i].id);
+ pr_err(KERN_CONT "] Invalid zero length\n");
+ early_acpi_os_unmap_memory((char *)table_header,
+ tbl_size);
+ proc[0].count = -EINVAL;
+ return -EINVAL;
+ }
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
}
if (max_entries && count > max_entries) {
- printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
- "%i found\n", id, entry_id, count - max_entries, count);
+ printk(KERN_WARNING PREFIX "[%4.4s:0x%02x ", id, proc[0].id);
+ for (i = 1; i < proc_num; i++)
+ printk(KERN_CONT " 0x%02x", proc[i].id);
+ printk(KERN_CONT "] ignored %i entries of %i found\n",
+ count-max_entries, count);
}
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
return count;
-err:
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
- return -EINVAL;
+}
+
+int __init
+acpi_table_parse_entries(char *id,
+ unsigned long table_size,
+ int entry_id,
+ acpi_tbl_entry_handler handler,
+ unsigned int max_entries)
+{
+ struct acpi_subtable_proc proc[1];
+
+ if (!handler)
+ return -EINVAL;
+
+ memset(proc, 0, sizeof(proc));
+ proc[0].id = entry_id;
+ proc[0].handler = handler;
+
+ return acpi_table_parse_entries_array(id, table_size, proc, 1,
+ max_entries);
}
int __init
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -887,6 +887,7 @@ static int __init acpi_parse_madt_lapic_
{
int count;
int x2count = 0;
+ struct acpi_subtable_proc madt_proc[2];
if (!cpu_has_apic)
return -ENODEV;
@@ -911,10 +912,16 @@ static int __init acpi_parse_madt_lapic_
acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) {
- x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
- acpi_parse_x2apic, MAX_LOCAL_APIC);
- count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
- acpi_parse_lapic, MAX_LOCAL_APIC);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+ madt_proc[0].handler = acpi_parse_lapic;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+ madt_proc[1].handler = acpi_parse_x2apic;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
}
if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
@@ -926,11 +933,16 @@ static int __init acpi_parse_madt_lapic_
return count;
}
- x2count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
- acpi_parse_x2apic_nmi, 0);
- count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC_NMI;
+ madt_proc[0].handler = acpi_parse_lapic_nmi;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC_NMI;
+ madt_proc[1].handler = acpi_parse_x2apic_nmi;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), 0);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
Index: linux-2.6/drivers/acpi/numa.c
===================================================================
--- linux-2.6.orig/drivers/acpi/numa.c
+++ linux-2.6/drivers/acpi/numa.c
@@ -294,10 +294,18 @@ int __init acpi_numa_init(void)
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
- acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
- acpi_parse_x2apic_affinity, 0);
- acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
- acpi_parse_processor_affinity, 0);
+ struct acpi_subtable_proc srat_proc[2];
+
+ 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;
+
+ acpi_table_parse_entries_array(ACPI_SIG_SRAT,
+ sizeof(struct acpi_table_srat),
+ srat_proc, ARRAY_SIZE(srat_proc), 0);
+
cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
acpi_parse_memory_affinity,
NR_NODE_MEMBLKS);
Index: linux-2.6/include/linux/acpi.h
===================================================================
--- linux-2.6.orig/include/linux/acpi.h
+++ linux-2.6/include/linux/acpi.h
@@ -87,6 +87,12 @@ static inline void acpi_initrd_override(
}
#endif
+struct acpi_subtable_proc {
+ int id;
+ acpi_tbl_entry_handler handler;
+ int count;
+};
+
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
void __acpi_unmap_table(char *map, unsigned long size);
int early_acpi_boot_init(void);
@@ -97,6 +103,9 @@ int acpi_numa_init (void);
int acpi_table_init (void);
int acpi_table_parse(char *id, acpi_tbl_table_handler handler);
+int acpi_table_parse_entries_array(char *id, unsigned long table_size,
+ struct acpi_subtable_proc *proc, int proc_num,
+ unsigned int max_entries);
int __init acpi_table_parse_entries(char *id, unsigned long table_size,
int entry_id,
acpi_tbl_entry_handler handler,
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
@ 2012-01-31 8:31 Yinghai Lu
0 siblings, 0 replies; 8+ messages in thread
From: Yinghai Lu @ 2012-01-31 8:31 UTC (permalink / raw)
To: Len Brown
Cc: linux-acpi, Yinghai Lu, Suresh Siddha, Thomas Gleixner,
Ingo Molnar, H. Peter Anvin, Andrew Morton, linux-kernel
One system have mixing xapic and x2apic entries in MADT and SRAT.
BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
the cpus are with x2apic mode pre-enabled, still need to use xapic entries
instead of x2apic entries.
on 8 socket system with x2apic pre-enabled, will get out of order sequence:
CPU0: socket0, core0, thread0.
CPU1 - CPU 40: socket 4 - socket 7, thread 0
CPU41 - CPU 80: socket 4 - socket 7, thread 1
CPU81 - CPU 119: socket 0 - socket 3, thread 0
CPU120 - CPU 159: socket 0 - socket 3, thread 1
so max_cpus=80 will not get all thread0 now.
Need to handle every entry in MADT at same time with xapic and x2apic.
so we can honor sequence in MADT.
We can use max_cpus= command line to use thread0 in every core,
because recent MADT always have all thread0 at first.
Also it could make the cpu to node mapping more sane.
after patch will get
CPU0 - CPU 79: socket 0 - socket 7, thread 0
CPU80 - CPU 159: socket 0 - socket 7, thread 1
-v2: update some comments, and change to pass array pointer.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++-------
drivers/acpi/numa.c | 16 +++++++++---
drivers/acpi/tables.c | 57 +++++++++++++++++++++++++++++++++-----------
include/linux/acpi.h | 9 ++++++
4 files changed, 86 insertions(+), 26 deletions(-)
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -889,6 +889,7 @@ static int __init acpi_parse_madt_lapic_
{
int count;
int x2count = 0;
+ struct acpi_subtable_proc madt_proc[2];
if (!cpu_has_apic)
return -ENODEV;
@@ -913,10 +914,16 @@ static int __init acpi_parse_madt_lapic_
acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) {
- x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
- acpi_parse_x2apic, MAX_LOCAL_APIC);
- count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
- acpi_parse_lapic, MAX_LOCAL_APIC);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+ madt_proc[0].handler = acpi_parse_lapic;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+ madt_proc[1].handler = acpi_parse_x2apic;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
}
if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
@@ -928,11 +935,16 @@ static int __init acpi_parse_madt_lapic_
return count;
}
- x2count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
- acpi_parse_x2apic_nmi, 0);
- count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC_NMI;
+ madt_proc[0].handler = acpi_parse_lapic_nmi;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC_NMI;
+ madt_proc[1].handler = acpi_parse_x2apic_nmi;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, ARRAY_SIZE(madt_proc), 0);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
Index: linux-2.6/drivers/acpi/numa.c
===================================================================
--- linux-2.6.orig/drivers/acpi/numa.c
+++ linux-2.6/drivers/acpi/numa.c
@@ -290,10 +290,18 @@ int __init acpi_numa_init(void)
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
- acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
- acpi_parse_x2apic_affinity, 0);
- acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
- acpi_parse_processor_affinity, 0);
+ struct acpi_subtable_proc srat_proc[2];
+
+ 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;
+
+ acpi_table_parse_entries_array(ACPI_SIG_SRAT,
+ sizeof(struct acpi_table_srat),
+ srat_proc, ARRAY_SIZE(srat_proc), 0);
+
ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
acpi_parse_memory_affinity,
NR_NODE_MEMBLKS);
Index: linux-2.6/drivers/acpi/tables.c
===================================================================
--- linux-2.6.orig/drivers/acpi/tables.c
+++ linux-2.6/drivers/acpi/tables.c
@@ -201,10 +201,9 @@ void acpi_table_print_madt_entry(struct
int __init
-acpi_table_parse_entries(char *id,
+acpi_table_parse_entries_array(char *id,
unsigned long table_size,
- int entry_id,
- acpi_table_entry_handler handler,
+ struct acpi_subtable_proc *proc, int proc_num,
unsigned int max_entries)
{
struct acpi_table_header *table_header = NULL;
@@ -212,12 +211,12 @@ acpi_table_parse_entries(char *id,
unsigned int count = 0;
unsigned long table_end;
acpi_size tbl_size;
+ int i;
- if (acpi_disabled)
+ if (acpi_disabled) {
+ proc[0].count = -ENODEV;
return -ENODEV;
-
- if (!handler)
- return -EINVAL;
+ }
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
@@ -226,6 +225,7 @@ acpi_table_parse_entries(char *id,
if (!table_header) {
printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+ proc[0].count = -ENODEV;
return -ENODEV;
}
@@ -238,19 +238,30 @@ acpi_table_parse_entries(char *id,
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) {
- if (entry->type == entry_id
- && (!max_entries || count++ < max_entries))
- if (handler(entry, table_end)) {
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+ for (i = 0; i < proc_num; i++) {
+ if (entry->type != proc[i].id)
+ continue;
+ if (max_entries && count++ >= max_entries)
+ continue;
+ if (proc[i].handler(entry, table_end)) {
+ early_acpi_os_unmap_memory((char *)table_header,
+ tbl_size);
+ proc[i].count = -EINVAL;
return -EINVAL;
}
+ proc[i].count++;
+ break;
+ }
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
}
if (max_entries && count > max_entries) {
- printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
- "%i found\n", id, entry_id, count - max_entries, count);
+ printk(KERN_WARNING PREFIX "[%4.4s:0x%02x ", id, proc[0].id);
+ for (i = 1; i < proc_num; i++)
+ printk(KERN_CONT " 0x%02x", proc[i].id);
+ printk(KERN_CONT "] ignored %i entries of %i found\n",
+ count-max_entries, count);
}
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
@@ -258,6 +269,26 @@ acpi_table_parse_entries(char *id,
}
int __init
+acpi_table_parse_entries(char *id,
+ unsigned long table_size,
+ int entry_id,
+ acpi_table_entry_handler handler,
+ unsigned int max_entries)
+{
+ struct acpi_subtable_proc proc[1];
+
+ if (!handler)
+ return -EINVAL;
+
+ memset(proc, 0, sizeof(proc));
+ proc[0].id = entry_id;
+ proc[0].handler = handler;
+
+ return acpi_table_parse_entries_array(id, table_size, proc, 1,
+ max_entries);
+}
+
+int __init
acpi_table_parse_madt(enum acpi_madt_type id,
acpi_table_entry_handler handler, unsigned int max_entries)
{
Index: linux-2.6/include/linux/acpi.h
===================================================================
--- linux-2.6.orig/include/linux/acpi.h
+++ linux-2.6/include/linux/acpi.h
@@ -76,6 +76,12 @@ typedef int (*acpi_table_handler) (struc
typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+struct acpi_subtable_proc {
+ int id;
+ acpi_table_entry_handler handler;
+ int count;
+};
+
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
void __acpi_unmap_table(char *map, unsigned long size);
int early_acpi_boot_init(void);
@@ -86,6 +92,9 @@ int acpi_numa_init (void);
int acpi_table_init (void);
int acpi_table_parse (char *id, acpi_table_handler handler);
+int acpi_table_parse_entries_array(char *id, unsigned long table_size,
+ struct acpi_subtable_proc *proc, int proc_num,
+ unsigned int max_entries);
int __init acpi_table_parse_entries(char *id, unsigned long table_size,
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);
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
@ 2011-01-28 3:09 Yinghai Lu
2011-01-29 2:01 ` Suresh Siddha
2011-01-31 12:24 ` Ingo Molnar
0 siblings, 2 replies; 8+ messages in thread
From: Yinghai Lu @ 2011-01-28 3:09 UTC (permalink / raw)
To: Len Brown, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Suresh Siddha
Cc: Pavel Machek, Rafael J. Wysocki, linux-kernel, ACPI Devel Maling List
One system have mixing xapic and x2apic entries in MADT and SRAT.
BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
the cpus are with x2apic mode pre-enabled, still need to use xapic entries
instead of x2apic entries.
on 8 socket system with x2apic pre-enabled, will get out of order sequence:
CPU0: socket0, core0, thread0.
CPU1 - CPU 40: socket 4 - socket 7, thread 0
CPU41 - CPU 80: socket 4 - socket 7, thread 1
CPU81 - CPU 119: socket 0 - socket 3, thread 0
CPU120 - CPU 159: socket 0 - socket 3, thread 1
so max_cpus=80 will not get all thread0 now.
Need to handle every entry in MADT at same time with xapic and x2apic.
so we can honor sequence in MADT.
We can use max_cpus= command line to use thread0 in every core,
because recent MADT always have all thread0 at first.
Also it could make the cpu to node mapping more sane.
after patch will get
CPU0 - CPU 79: socket 0 - socket 7, thread 0
CPU80 - CPU 159: socket 0 - socket 7, thread 1
-v2: update some comments, and change to pass array pointer.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++-------
drivers/acpi/numa.c | 16 +++++++++---
drivers/acpi/tables.c | 57 +++++++++++++++++++++++++++++++++-----------
include/linux/acpi.h | 9 ++++++
4 files changed, 86 insertions(+), 26 deletions(-)
Index: linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/boot.c
+++ linux-2.6/arch/x86/kernel/acpi/boot.c
@@ -883,6 +883,7 @@ static int __init acpi_parse_madt_lapic_
{
int count;
int x2count = 0;
+ struct acpi_subtable_proc madt_proc[2];
if (!cpu_has_apic)
return -ENODEV;
@@ -907,10 +908,16 @@ static int __init acpi_parse_madt_lapic_
acpi_parse_sapic, MAX_LOCAL_APIC);
if (!count) {
- x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
- acpi_parse_x2apic, MAX_LOCAL_APIC);
- count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
- acpi_parse_lapic, MAX_LOCAL_APIC);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+ madt_proc[0].handler = acpi_parse_lapic;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+ madt_proc[1].handler = acpi_parse_x2apic;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, 2, MAX_LOCAL_APIC);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
}
if (!count && !x2count) {
printk(KERN_ERR PREFIX "No LAPIC entries present\n");
@@ -922,11 +929,16 @@ static int __init acpi_parse_madt_lapic_
return count;
}
- x2count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC_NMI,
- acpi_parse_x2apic_nmi, 0);
- count =
- acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC_NMI, acpi_parse_lapic_nmi, 0);
+ memset(madt_proc, 0, sizeof(madt_proc));
+ madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC_NMI;
+ madt_proc[0].handler = acpi_parse_lapic_nmi;
+ madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC_NMI;
+ madt_proc[1].handler = acpi_parse_x2apic_nmi;
+ acpi_table_parse_entries_array(ACPI_SIG_MADT,
+ sizeof(struct acpi_table_madt),
+ madt_proc, 2, 0);
+ count = madt_proc[0].count;
+ x2count = madt_proc[1].count;
if (count < 0 || x2count < 0) {
printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
/* TBD: Cleanup to allow fallback to MPS */
Index: linux-2.6/drivers/acpi/numa.c
===================================================================
--- linux-2.6.orig/drivers/acpi/numa.c
+++ linux-2.6/drivers/acpi/numa.c
@@ -284,10 +284,18 @@ int __init acpi_numa_init(void)
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
- acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
- acpi_parse_x2apic_affinity, 0);
- acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
- acpi_parse_processor_affinity, 0);
+ struct acpi_subtable_proc srat_proc[2];
+
+ 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;
+
+ acpi_table_parse_entries_array(ACPI_SIG_SRAT,
+ sizeof(struct acpi_table_srat),
+ srat_proc, 2, 0);
+
ret = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
acpi_parse_memory_affinity,
NR_NODE_MEMBLKS);
Index: linux-2.6/drivers/acpi/tables.c
===================================================================
--- linux-2.6.orig/drivers/acpi/tables.c
+++ linux-2.6/drivers/acpi/tables.c
@@ -201,10 +201,9 @@ void acpi_table_print_madt_entry(struct
int __init
-acpi_table_parse_entries(char *id,
+acpi_table_parse_entries_array(char *id,
unsigned long table_size,
- int entry_id,
- acpi_table_entry_handler handler,
+ struct acpi_subtable_proc *proc, int proc_num,
unsigned int max_entries)
{
struct acpi_table_header *table_header = NULL;
@@ -212,12 +211,12 @@ acpi_table_parse_entries(char *id,
unsigned int count = 0;
unsigned long table_end;
acpi_size tbl_size;
+ int i;
- if (acpi_disabled)
+ if (acpi_disabled) {
+ proc[0].count = -ENODEV;
return -ENODEV;
-
- if (!handler)
- return -EINVAL;
+ }
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
acpi_get_table_with_size(id, acpi_apic_instance, &table_header, &tbl_size);
@@ -226,6 +225,7 @@ acpi_table_parse_entries(char *id,
if (!table_header) {
printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
+ proc[0].count = -ENODEV;
return -ENODEV;
}
@@ -238,19 +238,30 @@ acpi_table_parse_entries(char *id,
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) {
- if (entry->type == entry_id
- && (!max_entries || count++ < max_entries))
- if (handler(entry, table_end)) {
- early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+ for (i = 0; i < proc_num; i++) {
+ if (entry->type != proc[i].id)
+ continue;
+ if (max_entries && count++ >= max_entries)
+ continue;
+ if (proc[i].handler(entry, table_end)) {
+ early_acpi_os_unmap_memory((char *)table_header,
+ tbl_size);
+ proc[i].count = -EINVAL;
return -EINVAL;
}
+ proc[i].count++;
+ break;
+ }
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
}
if (max_entries && count > max_entries) {
- printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
- "%i found\n", id, entry_id, count - max_entries, count);
+ printk(KERN_WARNING PREFIX "[%4.4s:0x%02x ", id, proc[0].id);
+ for (i = 1; i < proc_num; i++)
+ printk(KERN_CONT " 0x%02x", proc[i].id);
+ printk(KERN_CONT "] ignored %i entries of %i found\n",
+ count-max_entries, count);
}
early_acpi_os_unmap_memory((char *)table_header, tbl_size);
@@ -258,6 +269,26 @@ acpi_table_parse_entries(char *id,
}
int __init
+acpi_table_parse_entries(char *id,
+ unsigned long table_size,
+ int entry_id,
+ acpi_table_entry_handler handler,
+ unsigned int max_entries)
+{
+ struct acpi_subtable_proc proc[1];
+
+ if (!handler)
+ return -EINVAL;
+
+ memset(proc, 0, sizeof(proc));
+ proc[0].id = entry_id;
+ proc[0].handler = handler;
+
+ return acpi_table_parse_entries_array(id, table_size, proc, 1,
+ max_entries);
+}
+
+int __init
acpi_table_parse_madt(enum acpi_madt_type id,
acpi_table_entry_handler handler, unsigned int max_entries)
{
Index: linux-2.6/include/linux/acpi.h
===================================================================
--- linux-2.6.orig/include/linux/acpi.h
+++ linux-2.6/include/linux/acpi.h
@@ -76,6 +76,12 @@ typedef int (*acpi_table_handler) (struc
typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
+struct acpi_subtable_proc {
+ int id;
+ acpi_table_entry_handler handler;
+ int count;
+};
+
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
void __acpi_unmap_table(char *map, unsigned long size);
int early_acpi_boot_init(void);
@@ -86,6 +92,9 @@ int acpi_numa_init (void);
int acpi_table_init (void);
int acpi_table_parse (char *id, acpi_table_handler handler);
+int acpi_table_parse_entries_array(char *id, unsigned long table_size,
+ struct acpi_subtable_proc *proc, int proc_num,
+ unsigned int max_entries);
int __init acpi_table_parse_entries(char *id, unsigned long table_size,
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);
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
2011-01-28 3:09 Yinghai Lu
@ 2011-01-29 2:01 ` Suresh Siddha
2011-01-29 2:17 ` Yinghai Lu
2011-01-31 12:24 ` Ingo Molnar
1 sibling, 1 reply; 8+ messages in thread
From: Suresh Siddha @ 2011-01-29 2:01 UTC (permalink / raw)
To: Yinghai Lu
Cc: Brown, Len, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Pavel Machek, Rafael J. Wysocki, linux-kernel,
ACPI Devel Maling List
On Thu, 2011-01-27 at 19:09 -0800, Yinghai Lu wrote:
> One system have mixing xapic and x2apic entries in MADT and SRAT.
> BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
> the cpus are with x2apic mode pre-enabled, still need to use xapic entries
> instead of x2apic entries.
true. thats what the spec says.
> on 8 socket system with x2apic pre-enabled, will get out of order sequence:
> CPU0: socket0, core0, thread0.
> CPU1 - CPU 40: socket 4 - socket 7, thread 0
> CPU41 - CPU 80: socket 4 - socket 7, thread 1
> CPU81 - CPU 119: socket 0 - socket 3, thread 0
> CPU120 - CPU 159: socket 0 - socket 3, thread 1
>
> so max_cpus=80 will not get all thread0 now.
>
> Need to handle every entry in MADT at same time with xapic and x2apic.
> so we can honor sequence in MADT.
hmm few things.
So is your bios listing like this:
xapic entries for all thread-0
x2apic entries for all thread-0
xapic entries for all thread-1
x2apic entries for all thread-1
What happens if some other bios lists like:
all xapic entries
followed by all x2apic entries
or
all x2apic entries
followed by all x2apic entries
I am not sure if there is a strict recommendation by Intel bios writers
guide to list all thread-0 first followed by thread-1. Even if there is
a strict recommendation like that, I am sure there will be some bios's
that don't follow the rules.
Anyways two things.
a) I don't want to complicate the code too much and still doesn't get
the desired behavior when some bios has a different silly ordering.
b) Also perhaps we need to make it more explicit. Like instead of
relying on the "maxcpus=n/2" to boot all thread-0's, we should say it
more explicitly like perhaps nosmt or noht (we used to have this kind of
option before). Or is it even worth to bother about this, given that we
can boot all the cpu's and offline the SMT siblings.
> We can use max_cpus= command line to use thread0 in every core,
> because recent MADT always have all thread0 at first.
> Also it could make the cpu to node mapping more sane.
>
> after patch will get
> CPU0 - CPU 79: socket 0 - socket 7, thread 0
> CPU80 - CPU 159: socket 0 - socket 7, thread 1
>
> -v2: update some comments, and change to pass array pointer.
>
thanks,
suresh
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
2011-01-29 2:01 ` Suresh Siddha
@ 2011-01-29 2:17 ` Yinghai Lu
0 siblings, 0 replies; 8+ messages in thread
From: Yinghai Lu @ 2011-01-29 2:17 UTC (permalink / raw)
To: Suresh Siddha
Cc: Brown, Len, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Pavel Machek, Rafael J. Wysocki, linux-kernel,
ACPI Devel Maling List
On Fri, Jan 28, 2011 at 6:01 PM, Suresh Siddha
<suresh.b.siddha@intel.com> wrote:
> On Thu, 2011-01-27 at 19:09 -0800, Yinghai Lu wrote:
>> One system have mixing xapic and x2apic entries in MADT and SRAT.
>> BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
>> the cpus are with x2apic mode pre-enabled, still need to use xapic entries
>> instead of x2apic entries.
>
> true. thats what the spec says.
I was thinking if cpus are with x2apic pre-enabled, we should have
x2apic entries for them.
>
>> on 8 socket system with x2apic pre-enabled, will get out of order sequence:
>> CPU0: socket0, core0, thread0.
>> CPU1 - CPU 40: socket 4 - socket 7, thread 0
>> CPU41 - CPU 80: socket 4 - socket 7, thread 1
>> CPU81 - CPU 119: socket 0 - socket 3, thread 0
>> CPU120 - CPU 159: socket 0 - socket 3, thread 1
>>
>> so max_cpus=80 will not get all thread0 now.
>>
>> Need to handle every entry in MADT at same time with xapic and x2apic.
>> so we can honor sequence in MADT.
>
> hmm few things.
>
> So is your bios listing like this:
>
> xapic entries for all thread-0
> x2apic entries for all thread-0
> xapic entries for all thread-1
> x2apic entries for all thread-1
Yes. that is required by BIOS write guide, it says all thread 0 should
come first.
>
> What happens if some other bios lists like:
>
> all xapic entries
> followed by all x2apic entries
assume should get
CPU0: socket0, core0, thread0.
CPU1 - CPU 80: socket 4 - socket 7, thread 0 and thread 1
CPU81 - CPU 159: socket 0 - socket 3, thread 0 and thread 1
>
> or
>
> all x2apic entries
> followed by all x2apic entries
all x2apic ?
>
> I am not sure if there is a strict recommendation by Intel bios writers
> guide to list all thread-0 first followed by thread-1. Even if there is
> a strict recommendation like that, I am sure there will be some bios's
> that don't follow the rules.
our bios follow the BWG guide.
>
> Anyways two things.
>
> a) I don't want to complicate the code too much and still doesn't get
> the desired behavior when some bios has a different silly ordering.
we have right ordering according to ACPI 4.0 spec and BWG
also i think that code is not that complicated.
>
> b) Also perhaps we need to make it more explicit. Like instead of
> relying on the "maxcpus=n/2" to boot all thread-0's, we should say it
> more explicitly like perhaps nosmt or noht (we used to have this kind of
> option before). Or is it even worth to bother about this, given that we
> can boot all the cpu's and offline the SMT siblings.
interesting, if we have nosmt or noht, we still need to boot that cpu
to use cpuid to
find out thread idx?
Thanks
Yinghai Lu
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time
2011-01-28 3:09 Yinghai Lu
2011-01-29 2:01 ` Suresh Siddha
@ 2011-01-31 12:24 ` Ingo Molnar
1 sibling, 0 replies; 8+ messages in thread
From: Ingo Molnar @ 2011-01-31 12:24 UTC (permalink / raw)
To: Yinghai Lu, Len Brown
Cc: Len Brown, Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
Suresh Siddha, Pavel Machek, Rafael J. Wysocki, linux-kernel,
ACPI Devel Maling List, Andrew Morton
* Yinghai Lu <yinghai@kernel.org> wrote:
>
> One system have mixing xapic and x2apic entries in MADT and SRAT.
> BIOS guys insist that ACPI 4.0 SPEC said so, if apic id < 255, even
> the cpus are with x2apic mode pre-enabled, still need to use xapic entries
> instead of x2apic entries.
>
> on 8 socket system with x2apic pre-enabled, will get out of order sequence:
> CPU0: socket0, core0, thread0.
> CPU1 - CPU 40: socket 4 - socket 7, thread 0
> CPU41 - CPU 80: socket 4 - socket 7, thread 1
> CPU81 - CPU 119: socket 0 - socket 3, thread 0
> CPU120 - CPU 159: socket 0 - socket 3, thread 1
>
> so max_cpus=80 will not get all thread0 now.
>
> Need to handle every entry in MADT at same time with xapic and x2apic.
> so we can honor sequence in MADT.
>
> We can use max_cpus= command line to use thread0 in every core,
> because recent MADT always have all thread0 at first.
> Also it could make the cpu to node mapping more sane.
>
> after patch will get
> CPU0 - CPU 79: socket 0 - socket 7, thread 0
> CPU80 - CPU 159: socket 0 - socket 7, thread 1
>
> -v2: update some comments, and change to pass array pointer.
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>
> ---
> arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++-------
> drivers/acpi/numa.c | 16 +++++++++---
> drivers/acpi/tables.c | 57 +++++++++++++++++++++++++++++++++-----------
> include/linux/acpi.h | 9 ++++++
> 4 files changed, 86 insertions(+), 26 deletions(-)
Seems useful - we can queue it up and can get it tested in the x86 tree if Len acks
the principle and the ACPI approach.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2014-08-21 23:27 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-21 21:39 [PATCH -v2] x86, acpi: Handle xapic/x2apic entries in MADT at same time Yinghai Lu
[not found] ` <CAE9FiQX0bUdWz6bmqLKDHpY5mvjEYdobseroCRnu0-Ju0qmsPw@mail.gmail.com>
[not found] ` <1f7d783e-5b26-495d-83d5-5d522eb3941e@email.android.com>
[not found] ` <CAE9FiQWPiVb_hySAADQypuZtcTN+iEQb4hoO=-+iurdsmKqKrg@mail.gmail.com>
[not found] ` <CAE9FiQUcq05K1mR5E7K-MT3+Z4xxckxO+o9RJ6QDwiGG1T_3aQ@mail.gmail.com>
[not found] ` <CAE9FiQVHcPH3aOU3uD=PsWay1w+csSDzZk62tpMXVgsFVMW1wg@mail.gmail.com>
[not found] ` <CAE9FiQVGZf_cRMK0spp9=YhG8SsrK+FY6fi00pCxZcEL1Ne-kg@mail.gmail.com>
[not found] ` <CAE9FiQW6q860P4+qQWTwt0k0vjOJ-S6FdyZHv06=0qv1Z97C=g@mail.gmail.com>
2014-08-21 7:00 ` Ingo Molnar
2014-08-21 23:27 ` Yinghai Lu
-- strict thread matches above, loose matches on Subject: below --
2012-01-31 8:31 Yinghai Lu
2011-01-28 3:09 Yinghai Lu
2011-01-29 2:01 ` Suresh Siddha
2011-01-29 2:17 ` Yinghai Lu
2011-01-31 12:24 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).