x2APIC and many-APIC systems...
Ingo, Suresh,
Commit a35fd28256e7736cc84af8931a16224f0bfaaf6c prevents x2APIC structures being used from the ACPI MADT if the cores don't advertise the x2APIC feature. Commit c284b42abadbb22083bfde24d308899c08d44ffa prevents onlining cores with APIC ID >255 in non-x2APIC mode. Since NumaChip/NumaConnect uses x2APIC structures to describe non-x2APIC systems (AMD Opteron) with lots of APICs, we thus now can't boot all the cores.
We are able to set the x2APIC bit in the processor feature flags, so get caught by the second patch. Is there an appropriate approach to use in these circumstances? Otherwise, would a patch that separates the APIC ID handover and future x2APIC MSR access be appropriate?
Many thanks,
Daniel
Signature · 2 lines
Daniel J Blueman Principal Software Engineer, Numascale Asia
Quoted 9 lines · Daniel J Blueman
Ingo, Suresh,
Commit
a35fd28256e7736cc84af8931a16224f0bfaaf6cprevents x2APIC structures being used from the ACPI MADT if the cores don't advertise the x2APIC feature. Commitc284b42abadbb22083bfde24d308899c08d44ffaprevents onlining cores with APIC ID >255 in non-x2APIC mode. Since NumaChip/NumaConnect uses x2APIC structures to describe non-x2APIC systems (AMD Opteron) with lots of APICs, we thus now can't boot all the cores.
Quoted 5 lines
We are able to set the x2APIC bit in the processor feature flags, so get caught by the second patch. Is there an appropriate approach to use in these circumstances? Otherwise, would a patch that separates the APIC ID handover and future x2APIC MSR access be appropriate?
add is_apicid_valid() in struct apic?
Yinghai
Quoted 11 lines · Yinghai Lu
Quoted 9 lines · Daniel J Blueman
Ingo, Suresh,
Commit
a35fd28256e7736cc84af8931a16224f0bfaaf6cprevents x2APIC structures being used from the ACPI MADT if the cores don't advertise the x2APIC feature. Commitc284b42abadbb22083bfde24d308899c08d44ffaprevents onlining cores with APIC ID >255 in non-x2APIC mode. Since NumaChip/NumaConnect uses x2APIC structures to describe non-x2APIC systems (AMD Opteron) with lots of APICs, we thus now can't boot all the cores.
Quoted 7 lines
Quoted 5 lines
We are able to set the x2APIC bit in the processor feature flags, so get caught by the second patch. Is there an appropriate approach to use in these circumstances? Otherwise, would a patch that separates the APIC ID handover and future x2APIC MSR access be appropriate?
add
is_apicid_valid()in struct apic?
Yes, we can generalize that and move into the apicdriver. Daniel, will you be able to prepare such a patch?
thanks,
suresh
PATCH 1/1 Move APIC ID validity check into platform APIC code
Move APIC ID validity check into platform APIC code, so it can be overridden when needed. For NumaChip systems, always trust MADT, as it's constructed with high APIC IDs.
Behaviour verifies on standard x86 systems and on NumaChip systems with this, and compile-tested with allyesconfig.
--- arch/x86/include/asm/apic.h | 6 ++++++ arch/x86/kernel/apic/apic_flat_64.c | 2 ++ arch/x86/kernel/apic/apic_noop.c | 1 + arch/x86/kernel/apic/apic_numachip.c | 10 +++++++++- arch/x86/kernel/apic/bigsmp_32.c | 1 + arch/x86/kernel/apic/es7000_32.c | 2 ++ arch/x86/kernel/apic/numaq_32.c | 1 + arch/x86/kernel/apic/probe_32.c | 1 + arch/x86/kernel/apic/summit_32.c | 1 + arch/x86/kernel/apic/x2apic_cluster.c | 1 + arch/x86/kernel/apic/x2apic_phys.c | 1 + arch/x86/kernel/apic/x2apic_uv_x.c | 1 + arch/x86/kernel/smpboot.c | 2 +- 13 files changed, 28 insertions(+), 2 deletions(-)
arch/x86/include/asm/apic.h +6 -0
@@ -288,6 +288,7 @@ struct apic {int (*probe)(void );int (*acpi_madt_oem_check)(char *oem_id,char *oem_table_id); +int (*apic_id_valid)(int apicid);int (*apic_id_registered)(void );u32 irq_delivery_mode;
@@ -532,6 +533,11 @@ static inline unsigned int read_apic_id(void)return apic->get_apic_id (reg); } +static inline int default_apic_id_valid (int apicid) +{ +return x2apic_mode || (apicid <255 ); +} +extern void default_setup_apic_routing (void );extern struct apic apic_noop;
arch/x86/kernel/apic/apic_flat_64.c +2 -0
@@ -180,6 +180,7 @@ static struct apic apic_flat = { .name = "flat", .probe = flat_probe, .acpi_madt_oem_check = flat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
@@ -337,6 +338,7 @@ static struct apic apic_physflat = { .name = "physical flat", .probe = physflat_probe, .acpi_madt_oem_check = physflat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/apic_noop.c +1 -0
@@ -124,6 +124,7 @@ struct apic apic_noop = { .probe = noop_probe, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = noop_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/apic_numachip.c +9 -1
@@ -56,6 +56,12 @@ static unsigned int read_xapic_id(void)return get_apic_id (apic_read (APIC_ID )); } +static int numachip_apic_id_valid (int apicid) +{ +/* Trust what bootloader passes in MADT */ +return 1 ; +} +static int numachip_apic_id_registered (void ) {return physid_isset (read_xapic_id (), phys_cpu_present_map);
@@ -223,10 +229,11 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; +setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
@@ -238,6 +245,7 @@ static struct apic apic_numachip __refconst = { .name = "NumaConnect system", .probe = numachip_probe, .acpi_madt_oem_check = numachip_acpi_madt_oem_check, + .apic_id_valid = numachip_apic_id_valid, .apic_id_registered = numachip_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/bigsmp_32.c +1 -0
@@ -198,6 +198,7 @@ static struct apic apic_bigsmp = { .name = "bigsmp", .probe = probe_bigsmp, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = bigsmp_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/es7000_32.c +2 -0
@@ -625,6 +625,7 @@ static struct apic __refdata apic_es7000_cluster = { .name = "es7000", .probe = probe_es7000, .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = es7000_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
@@ -690,6 +691,7 @@ static struct apic __refdata apic_es7000 = { .name = "es7000", .probe = probe_es7000, .acpi_madt_oem_check = es7000_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = es7000_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/numaq_32.c +1 -0
@@ -478,6 +478,7 @@ static struct apic __refdata apic_numaq = { .name = "NUMAQ", .probe = probe_numaq, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = numaq_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/probe_32.c +1 -0
@@ -92,6 +92,7 @@ static struct apic apic_default = { .name = "default", .probe = probe_default, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = default_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/summit_32.c +1 -0
@@ -496,6 +496,7 @@ static struct apic apic_summit = { .name = "summit", .probe = probe_summit, .acpi_madt_oem_check = summit_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = summit_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_cluster.c +1 -0
@@ -213,6 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -0
@@ -119,6 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +1 -0
@@ -351,6 +351,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/smpboot.c +1 -1
@@ -847,7 +847,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)if (apicid ==BAD_APICID || apicid == boot_cpu_physical_apicid || !physid_isset (apicid, phys_cpu_present_map) || - (!x2apic_mode && apicid >=255 )) { + !apic->apic_id_valid (apicid)) {printk (KERN_ERR "%s: bad cpu %d\n" , __func__, cpu);return -EINVAL ; }
Signature · 1 line
1.7.5.4
[tip:x86/platform] x86/platform: Move APIC ID validity check into platform APIC code
Commit-ID: fa63030e9c79e37b4d4e63b39ffb09cfb7aa0fe4 Gitweb: http://git.kernel.org/tip/fa63030e9c79e37b4d4e63b39ffb09cfb7aa0fe4 Author: Daniel J Blueman <[email protected]> AuthorDate: Wed, 14 Mar 2012 15:17:34 +0800 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 14 Mar 2012 09:49:48 +0100
x86/platform: Move APIC ID validity check into platform APIC code
Move APIC ID validity check into platform APIC code, so it can be overridden when needed. For NumaChip systems, always trust MADT, as it's constructed with high APIC IDs.
Behaviour verifies on standard x86 systems and on NumaChip systems with this, and compile-tested with allyesconfig.
--- arch/x86/include/asm/apic.h | 6 ++++++ arch/x86/kernel/apic/apic_flat_64.c | 2 ++ arch/x86/kernel/apic/apic_noop.c | 1 + arch/x86/kernel/apic/apic_numachip.c | 10 +++++++++- arch/x86/kernel/apic/bigsmp_32.c | 1 + arch/x86/kernel/apic/es7000_32.c | 2 ++ arch/x86/kernel/apic/numaq_32.c | 1 + arch/x86/kernel/apic/probe_32.c | 1 + arch/x86/kernel/apic/summit_32.c | 1 + arch/x86/kernel/apic/x2apic_cluster.c | 1 + arch/x86/kernel/apic/x2apic_phys.c | 1 + arch/x86/kernel/apic/x2apic_uv_x.c | 1 + arch/x86/kernel/smpboot.c | 2 +- 13 files changed, 28 insertions(+), 2 deletions(-)
arch/x86/include/asm/apic.h +6 -0
@@ -288,6 +288,7 @@ struct apic {int (*probe)(void );int (*acpi_madt_oem_check)(char *oem_id,char *oem_table_id); +int (*apic_id_valid)(int apicid);int (*apic_id_registered)(void );u32 irq_delivery_mode;
@@ -532,6 +533,11 @@ static inline unsigned int read_apic_id(void)return apic->get_apic_id (reg); } +static inline int default_apic_id_valid (int apicid) +{ +return x2apic_mode || (apicid <255 ); +} +extern void default_setup_apic_routing (void );extern struct apic apic_noop;
arch/x86/kernel/apic/apic_flat_64.c +2 -0
@@ -180,6 +180,7 @@ static struct apic apic_flat = { .name = "flat", .probe = flat_probe, .acpi_madt_oem_check = flat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
@@ -337,6 +338,7 @@ static struct apic apic_physflat = { .name = "physical flat", .probe = physflat_probe, .acpi_madt_oem_check = physflat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/apic_noop.c +1 -0
@@ -124,6 +124,7 @@ struct apic apic_noop = { .probe = noop_probe, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = noop_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/apic_numachip.c +9 -1
@@ -56,6 +56,12 @@ static unsigned int read_xapic_id(void)return get_apic_id (apic_read (APIC_ID )); } +static int numachip_apic_id_valid (int apicid) +{ +/* Trust what bootloader passes in MADT */ +return 1 ; +} +static int numachip_apic_id_registered (void ) {return physid_isset (read_xapic_id (), phys_cpu_present_map);
@@ -223,10 +229,11 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; +setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
@@ -238,6 +245,7 @@ static struct apic apic_numachip __refconst = { .name = "NumaConnect system", .probe = numachip_probe, .acpi_madt_oem_check = numachip_acpi_madt_oem_check, + .apic_id_valid = numachip_apic_id_valid, .apic_id_registered = numachip_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/bigsmp_32.c +1 -0
@@ -198,6 +198,7 @@ static struct apic apic_bigsmp = { .name = "bigsmp", .probe = probe_bigsmp, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = bigsmp_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/es7000_32.c +2 -0
@@ -625,6 +625,7 @@ static struct apic __refdata apic_es7000_cluster = { .name = "es7000", .probe = probe_es7000, .acpi_madt_oem_check = es7000_acpi_madt_oem_check_cluster, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = es7000_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
@@ -690,6 +691,7 @@ static struct apic __refdata apic_es7000 = { .name = "es7000", .probe = probe_es7000, .acpi_madt_oem_check = es7000_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = es7000_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/numaq_32.c +1 -0
@@ -478,6 +478,7 @@ static struct apic __refdata apic_numaq = { .name = "NUMAQ", .probe = probe_numaq, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = numaq_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/probe_32.c +1 -0
@@ -92,6 +92,7 @@ static struct apic apic_default = { .name = "default", .probe = probe_default, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = default_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/summit_32.c +1 -0
@@ -496,6 +496,7 @@ static struct apic apic_summit = { .name = "summit", .probe = probe_summit, .acpi_madt_oem_check = summit_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = summit_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_cluster.c +1 -0
@@ -213,6 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -0
@@ -119,6 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +1 -0
@@ -351,6 +351,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/smpboot.c +1 -1
@@ -847,7 +847,7 @@ int __cpuinit native_cpu_up(unsigned int cpu)if (apicid ==BAD_APICID || apicid == boot_cpu_physical_apicid || !physid_isset (apicid, phys_cpu_present_map) || - (!x2apic_mode && apicid >=255 )) { + !apic->apic_id_valid (apicid)) {printk (KERN_ERR "%s: bad cpu %d\n" , __func__, cpu);return -EINVAL ; }
Re: [PATCH] Move APIC ID validity check into platform APIC code
In reply to Daniel J BluemanQuoted 101 lines · Daniel J Blueman
Move APIC ID validity check into platform APIC code, so it can be overridden when needed. For NumaChip systems, always trust MADT, as it's constructed with high APIC IDs.
Behaviour verifies on standard x86 systems and on NumaChip systems with this, and compile-tested with allyesconfig.
Signed-off-by Daniel J Blueman <[email protected]>Reviewed-by Steffen Persvold <[email protected]>---
arch/x86/include/asm/apic.h | 6 ++++++arch/x86/kernel/apic/apic_flat_64.c| 2 ++arch/x86/kernel/apic/apic_noop.c| 1 +arch/x86/kernel/apic/apic_numachip.c| 10 +++++++++-arch/x86/kernel/apic/bigsmp_32.c | 1 + arch/x86/kernel/apic/es7000_32.c | 2 ++ arch/x86/kernel/apic/numaq_32.c | 1 + arch/x86/kernel/apic/probe_32.c | 1 + arch/x86/kernel/apic/summit_32.c | 1 +arch/x86/kernel/apic/x2apic_cluster.c | 1 +
arch/x86/kernel/apic/x2apic_phys.c | 1 +
arch/x86/kernel/apic/x2apic_uv_x.c | 1 +
arch/x86/kernel/smpboot.c | 2 +-13 files changed, 28 insertions(+), 2 deletions(-)arch/x86/include/asm/apic.h +6
-0@@ -288,6 +288,7 @@ struct apic { int (*probe)(void); int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id); + int (*apic_id_valid)(int apicid); int (*apic_id_registered)(void); u32 irq_delivery_mode;@@ -532,6 +533,11 @@ static inline unsigned int read_apic_id(void) return apic->get_apic_id(reg); } +static inline int default_apic_id_valid (int apicid) +{ + return x2apic_mode || (apicid < 255); +} + extern void default_setup_apic_routing(void); extern struct apic apic_noop;arch/x86/kernel/apic/apic_flat_64.c +2
-0@@ -180,6 +180,7 @@ static struct apic apic_flat = { .name = "flat", .probe = flat_probe, .acpi_madt_oem_check = flat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,@@ -337,6 +338,7 @@ static struct apic apic_physflat = { .name = "physical flat", .probe = physflat_probe, .acpi_madt_oem_check = physflat_acpi_madt_oem_check, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = flat_apic_id_registered, .irq_delivery_mode = dest_Fixed,arch/x86/kernel/apic/apic_noop.c +1
-0@@ -124,6 +124,7 @@ struct apic apic_noop = { .probe = noop_probe, .acpi_madt_oem_check = NULL, + .apic_id_valid = default_apic_id_valid, .apic_id_registered = noop_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,arch/x86/kernel/apic/apic_numachip.c +6
-0@@ -56,6 +56,12 @@ static unsigned int read_xapic_id(void) return get_apic_id(apic_read(APIC_ID)); } +static int numachip_apic_id_valid (int apicid) +{ + /* Trust what bootloader passes in MADT */ + return 1; +} + static int numachip_apic_id_registered(void) { return physid_isset(read_xapic_id(), phys_cpu_present_map);@@ -223,10 +229,11 @@ static int __init numachip_system_init(void) }
arch/x86/kernel/apic/apic_numachip.c static int __init numachip_system_init(void) · line 238
Quoted 10 lines
arch/x86/kernel/apic/apic_numachip.c +2
-1early_initcall(numachip_system_init); -static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) { if (!strncmp(oem_id, "NUMASC", 6)) { numachip_system = 1; + setup_force_cpu_cap(X86_FEATURE_X2APIC); return 1; }
can you check if you can update
!cpu_has_x2apic && (apic_id >= 0xff) && enabled
in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic()
to use some kind of apic_id_valid()
so you could avoid setting that feature bit.
the checking in SRAT could be removed.
Yinghai
Re: [PATCH] Move APIC ID validity check into platform APIC code
Quoted 1 line · Yinghai Lu
On Wed, Mar 14, 2012 at 12:17 AM, Daniel J Blueman
[]
Quoted 5 lines
can you check if you can update
!cpu_has_x2apic&& (apic_id>= 0xff)&& enabled
Quoted 8 lines
in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic()
to use some kind of
apic_id_valid()so you could avoid setting that feature bit.
the checking in SRAT could be removed.
Yinghai/Team,
One question (as I don't really know *why* this was added to the acpi/srat parsing code). In arch/x86/kernel/smpboot.c the check was originally :
!x2apic_mode && apicid >= 255
However in arch/x86/kernel/acpi/boot.c and arch/x86/mm/srat.c these tests are used :
!cpu_has_x2apic && (apic_id >= 0xff)
Clearly, "cpu_has_x2apic" and "x2apic_mode" are two different things.
Since we can force "cpu_has_x2apic", when Daniel crafted this patch he made the following "default" function :
static inline int default_apic_id_valid(int apicid)
{
return x2apic_mode || (apicid < 255);
}which, as you can see, checks against "x2apic_mode".
My question is; Is checking for "x2apic_mode" going to do the trick in the arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() ?
If the answer is yes, the patch is going to be very simple. But we can't verify that the code in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() actually triggers for the case you wanted it to trigger for because then it will check against "x2apic_mode" and not "cpu_has_x2apic".
Cheers,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Re: [PATCH] Move APIC ID validity check into platform APIC code
Quoted 4 lines · Steffen Persvold
which, as you can see, checks against "
x2apic_mode".My question is; Is checking for "
x2apic_mode" going to do the trick in the arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() ?
no, it is too early.
at that time, only x2apic pre-enabled system have that x2apic_mode set.
Quoted 5 lines
If the answer is yes, the patch is going to be very simple. But we can't verify that the code in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() actually triggers for the case you wanted it to trigger for because then it will check against "
x2apic_mode" and not "cpu_has_x2apic".
when kernel, found pre-enabled x2apic, can not use x2apic for some reason (like x2apic)
it will clear x2apic in cpu feature bit.
for other case like x2apic capable cpus and not preenabled,
but not have dmar table, that feature is not cleared if the not apic id > 255.
So we have default apic_id_valid only check cpu_has_x2apic instead of x2apic_mode instead.
and use it in boot.c
Yinghai
PATCH 1/1 Use x2apic_supported() in the default_apic_id_valid() function.
Use x2apic_supported() in the default_apic_id_valid() function. If x2apic mode is disabled (via nox2apic for example), x2apic_supported() will return false.
This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 1 - arch/x86/mm/srat.c | 7 +------ 4 files changed, 3 insertions(+), 9 deletions(-)
arch/x86/include/asm/apic.h +1 -1
@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(void)static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return x2apic_supported () || (apicid <255 ); }extern void default_setup_apic_routing (void );
arch/x86/kernel/acpi/boot.c +1 -1
@@ -239,7 +239,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);
arch/x86/kernel/apic/apic_numachip.c +0 -1
@@ -233,7 +233,6 @@ static int __cpuinit numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_ {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
arch/x86/mm/srat.c +1 -6
@@ -69,12 +69,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; - apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { -printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , - pxm, apic_id); -return ; - } node =setup_node (pxm);if (node <0 ) {printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm);
@@ -82,6 +76,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; } + apic_id = pa->apic_id;if (apic_id >=MAX_LOCAL_APIC ) {printk (KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n" , pxm, apic_id, node);return ;
Signature · 1 line
1.7.4.1
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 6 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Signed-off-by Steffen Persvold <[email protected]>Reviewed-by Daniel J Blueman <[email protected]>
I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id > 255.
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 5 lines · Yinghai Lu
Quoted 4 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Quoted 8 lines
Quoted 2 lines
Signed-off-by Steffen Persvold <[email protected]>Reviewed-by Daniel J Blueman <[email protected]>I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id > 255.
Acked-by Yinghai Lu <[email protected]>
This breaks the smpboot check if enabling interrupt-remapping/x2apic fails on a platform. We will be in xapic mode and we don't clear the x2apic cpufeature bit in this case and as such smpboot check will fail.
So this change breaks the commitc284b42abadbb22083bfde24d308899c08d44ffa.
I think the right thing is to have two different apid_id_valid checks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.
thanks,
suresh
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 6 lines · Suresh Siddha
Quoted 5 lines · Yinghai Lu
Quoted 4 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Quoted 9 lines
Quoted 8 lines
Quoted 2 lines
Signed-off-by Steffen Persvold<[email protected]>Reviewed-by Daniel J Blueman<[email protected]>I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id> 255.
Acked-by Yinghai Lu<[email protected]>
Suresh,
Quoted 7 lines
This breaks the smpboot check if enabling interrupt-remapping/x2apic fails on a platform. We will be in xapic mode and we don't clear the x2apic cpufeature bit in this case and as such smpboot check will fail.
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.
I was afraid of that.
Quoted 6 lines
I think the right thing is to have two different
apid_id_validchecks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.
Is my understanding of your suggestion correct that in x2apic_phys/cluster.c we add the following apic_id_valid() function :
static int x2apic_apic_id_valid(int apicid)
{
return x2apic_mode || (apicid < 255);
}
?
Considering that this function (apic->apic_id_valid()) is called already in the acpi/boot.c::acpi_parse_x2apic() function is it sufficient enough to test for x2apic_mode ? Yinghai indicated that x2apic_mode was not set at this point, thus it was testing cpu_has_x2apic instead ?
I must admit that I am not familiar enough with the APIC/ACPI code base to determine the sequence of events here (i.e MADT parsing, enabling of x2apic mode etc. etc.).
Please advice.
Kind regards,
Steffen
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 51 lines · Steffen Persvold
Quoted 11 lines · Suresh Siddha
Quoted 10 lines · Yinghai Lu
Quoted 8 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Quoted 9 lines
Quoted 8 lines
Quoted 2 lines
Signed-off-by Steffen Persvold<[email protected]>Reviewed-by Daniel J Blueman<[email protected]>I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id> 255.
Acked-by Yinghai Lu<[email protected]>Suresh,
Quoted 7 lines
This breaks the smpboot check if enabling interrupt-remapping/x2apic fails on a platform. We will be in xapic mode and we don't clear the x2apic cpufeature bit in this case and as such smpboot check will fail.
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.I was afraid of that.
Quoted 6 lines
I think the right thing is to have two different
apid_id_validchecks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.Is my understanding of your suggestion correct that in
x2apic_phys/cluster.cwe add the followingapic_id_valid()function :static int
x2apic_apic_id_valid(int apicid)
{
returnx2apic_mode|| (apicid < 255);
}?
Quoted 8 lines
Considering that this function (
apic->apic_id_valid()) is called already in the acpi/boot.c::acpi_parse_x2apic() function is it sufficient enough to test forx2apic_mode? Yinghai indicated thatx2apic_modewas not set at this point, thus it was testingcpu_has_x2apicinstead ?I must admit that I am not familiar enough with the APIC/ACPI code base to determine the sequence of events here (i.e MADT parsing, enabling of x2apic mode etc. etc.).
After reading the code a bit more it seems that the sequence is as follows :
kernel/setup.c::setup_arch() calls check_x2apic(). check_x2apic() first checks the cpu feature flag, then checks the MSR_IA32_APICBASE msr to see if bios has enabled x2apic mode. If this is the case, x2apic_preenabled and x2apic_mode is set to 1.
Later on in setup_arch(), the ACPI parsing starts.
My assumption is that the approach suggested in my previous email (based on Suresh' comment) with separate apic_id_valid() functions would be sufficient even for the MADT parsing ?
Kind regards,
Steffen
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
In reply to Steffen PersvoldQuoted 7 lines · Steffen Persvold
Is my understanding of your suggestion correct that in
x2apic_phys/cluster.cwe add the followingapic_id_valid()function :static int
x2apic_apic_id_valid(int apicid)
{
returnx2apic_mode|| (apicid < 255);
}
Steffen, We can have something like:
static int x2apic_apic_id_valid(int apicid)
{
return 1;
}
and
static int xapic_apic_id_valid(int apicid)
{
return apicid < 255;
}
If we have selected x2apic driver, then we know we are already in x2apic mode. And also x2apic_uv_x need to use the x2apic version above.
Quoted 4 lines
Considering that this function (
apic->apic_id_valid()) is called already in the acpi/boot.c::acpi_parse_x2apic() function is it sufficient enough to test forx2apic_mode? Yinghai indicated thatx2apic_modewas not set at this point, thus it was testingcpu_has_x2apicinstead ?
If the bios has handed over to us in x2apic mode (or if it is a numachip platform), then by this point apic driver is already set to the corresponding x2apic/numachip driver etc. so we should be fine.
When we are in xapic mode, typically there should be no x2apic MADT entries. And even if there are any (bios not following x2apic spec), the above xapic_apic_id_valid() check will consider only those x2apic MADT entries whose id's are less than 255. xapic mode can go into x2apic mode later but that flow is not supposed to bring up any cpu with apic id >
255. So parsing only entries with apic id < 255 here should be fine.
Hope this clarifies.
thanks,
suresh
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 35 lines · Suresh Siddha
Quoted 7 lines · Steffen Persvold
Is my understanding of your suggestion correct that in
x2apic_phys/cluster.cwe add the followingapic_id_valid()function :static int
x2apic_apic_id_valid(int apicid){ return x2apic_mode || (apicid< 255); }Steffen, We can have something like:
static int
x2apic_apic_id_valid(int apicid){ return 1; }and
static int
xapic_apic_id_valid(int apicid){ return apicid< 255; }If we have selected x2apic driver, then we know we are already in x2apic mode. And also
x2apic_uv_xneed to use the x2apic version above.Quoted 4 lines
Considering that this function (
apic->apic_id_valid()) is called already in the acpi/boot.c::acpi_parse_x2apic() function is it sufficient enough to test forx2apic_mode? Yinghai indicated thatx2apic_modewas not set at this point, thus it was testingcpu_has_x2apicinstead ?If the bios has handed over to us in x2apic mode (or if it is a numachip platform), then by this point apic driver is already set to the corresponding x2apic/numachip driver etc. so we should be fine.
Quoted 9 lines
When we are in xapic mode, typically there should be no x2apic MADT entries. And even if there are any (bios not following x2apic spec), the above
xapic_apic_id_valid()check will consider only those x2apic MADT entries whose id's are less than 255. xapic mode can go into x2apic mode later but that flow is not supposed to bring up any cpu with apic id>
255. So parsing only entries with apic id< 255 here should be fine.Hope this clarifies.
Yes, this is now my understanding aswell. Thank you.
I will resend a reviced patch shortly.
Kind regards,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
In reply to Suresh SiddhaQuoted 18 lines · Suresh Siddha
Quoted 7 lines · Steffen Persvold
Is my understanding of your suggestion correct that in
x2apic_phys/cluster.cwe add the followingapic_id_valid()function :static int
x2apic_apic_id_valid(int apicid){ return x2apic_mode || (apicid< 255); }Steffen, We can have something like:
static int
x2apic_apic_id_valid(int apicid){ return 1; }and
Quoted 8 lines
static int
xapic_apic_id_valid(int apicid){ return apicid< 255; }If we have selected x2apic driver, then we know we are already in x2apic mode. And also
x2apic_uv_xneed to use the x2apic version above.
If you specify "nox2apic" option, will it choose the xapic driver instead (and early enough) ? Otherwise I think we might break Yinghai's commit (a35fd28256e7736cc84af8931a16224f0bfaaf6c).
Cheers,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 24 lines · Steffen Persvold
Quoted 23 lines · Suresh Siddha
Quoted 7 lines · Steffen Persvold
Is my understanding of your suggestion correct that in
x2apic_phys/cluster.cwe add the followingapic_id_valid()function :static int
x2apic_apic_id_valid(int apicid)
{
returnx2apic_mode|| (apicid< 255);
}Steffen, We can have something like:
static int
x2apic_apic_id_valid(int apicid)
{
return 1;
}and
static int
xapic_apic_id_valid(int apicid)
{
return apicid< 255;
}
Quoted 8 lines
Quoted 3 lines
If we have selected x2apic driver, then we know we are already in x2apic mode. And also
x2apic_uv_xneed to use the x2apic version above.If you specify "nox2apic" option, will it choose the xapic driver instead (and early enough) ? Otherwise I think we might break Yinghai's commit (
a35fd28256e7736cc84af8931a16224f0bfaaf6c).
Answering myself here, my apologies, but yes it looks like both x2apic drivers will be de-activated if the "nox2apic" option is specified (x2apic_enabled() will return false).
Cheers,
Steffen
PATCH 1/1 Added separate apic_id_valid() functions for selected apic drivers
In reply to Suresh SiddhaThis allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate apic_id_valid() functions which will accept x2apic type IDs :
x2apic_physx2apic_clusterx2apic_uv_xapic_numachip
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 7 +------ 8 files changed, 17 insertions(+), 13 deletions(-)
arch/x86/include/asm/apic.h +1 -1
@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(void)static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return (apicid <255 ); }extern void default_setup_apic_routing (void );
arch/x86/include/asm/x2apic.h +5 -0
@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_target_cpus(void)return cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;
arch/x86/kernel/acpi/boot.c +1 -1
@@ -239,7 +239,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);
arch/x86/kernel/apic/apic_numachip.c +1 -2
@@ -229,11 +229,10 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
arch/x86/kernel/apic/x2apic_cluster.c +1 -1
@@ -213,7 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -1
@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +6 -1
@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;
@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/mm/srat.c +1 -6
@@ -69,12 +69,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; - apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { -printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , - pxm, apic_id); -return ; - } node =setup_node (pxm);if (node <0 ) {printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm);
@@ -82,6 +76,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; } + apic_id = pa->apic_id;if (apic_id >=MAX_LOCAL_APIC ) {printk (KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n" , pxm, apic_id, node);return ;
Signature · 1 line
1.7.4.1
Re: [PATCH] Added separate apic_id_valid() functions for selected apic drivers
arch/x86/mm/srat.c acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) · line 73
Quoted 10 lines · Steffen Persvold
arch/x86/mm/srat.c +0
-2@@ -69,12 +69,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)if ((pa->flags &ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; - apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) {
not sure why you removed this. Shouldn't this be replaced with apic->apic_id_valid() check?
thanks.
Quoted 15 lines
arch/x86/mm/srat.c +1
-4-printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , - pxm, apic_id); -return ; - } node =setup_node (pxm);if (node <0 ) {printk (KERN_ERR "SRAT: Too many proximity domains %x\n" , pxm);@@ -82,6 +76,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; } + apic_id = pa->apic_id;if (apic_id >=MAX_LOCAL_APIC ) {printk (KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n" , pxm, apic_id, node);return ;
Re: [PATCH] Added separate apic_id_valid() functions for selected apic drivers
Quoted 15 lines · Suresh Siddha
arch/x86/mm/srat.c acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) · line 73
Quoted 10 lines · Steffen Persvold
arch/x86/mm/srat.c +0
-2@@ -69,12 +69,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0) return; pxm = pa->proximity_domain; - apic_id = pa->apic_id; - if (!cpu_has_x2apic && (apic_id >= 0xff)) {not sure why you removed this. Shouldn't this be replaced with
apic->apic_id_valid()check?
yes, it should change to apic->apic_id_valid().
in arch/x86/kernel/setup.c, early_acpi_boot_init() calling will probe and install right apic.
Yinghai
Re: [PATCH] Added separate apic_id_valid() functions for selected apic drivers
In reply to Suresh SiddhaQuoted 15 lines · Suresh Siddha
arch/x86/mm/srat.c acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) · line 73
Quoted 10 lines · Steffen Persvold
arch/x86/mm/srat.c +0
-2@@ -69,12 +69,6 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)if ((pa->flags&ACPI_SRAT_CPU_ENABLED ) ==0 )return ; pxm = pa->proximity_domain; - apic_id = pa->apic_id; -if (!cpu_has_x2apic&& (apic_id>=0xff )) {not sure why you removed this. Shouldn't this be replaced with
apic->apic_id_valid()check?
Well I removed it in both my patches because Yinghai stated :
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
the checking in SRAT could be removed.
Yinghai
a couple of emails ago. I could of course use apic->apic_id_valid() here too to avoid parsing the PXM.
Cheers,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
In reply to Suresh SiddhaQuoted 13 lines · Suresh Siddha
Quoted 12 lines · Yinghai Lu
Quoted 6 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Signed-off-by Steffen Persvold <[email protected]>Reviewed-by Daniel J Blueman <[email protected]>I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id > 255.
Quoted 5 lines
Quoted 1 line
Acked-by Yinghai Lu <[email protected]>This breaks the smpboot check if enabling interrupt-remapping/x2apic fails on a platform. We will be in xapic mode and we don't clear the x2apic cpufeature bit in this case and as such smpboot check will fail.
two cases:
A: x2apic is pre-enabled, and some apic id > 255
B: x2apic is not pre-enabled, but x2apic capable, suppose all apic id < 255.
in case A: if nox2apic is passed, or dmar table is not there or intr-remap can not be enabled.
that feature bit will be cleared. So check cpu_has_x2apic is enough there.
in case B: if can not enable x2apic, the feature is not cleared, but apic id already < 255.
so that check will pass too.
So it should not break the smpboot check.
Quoted 9 lines
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.I think the right thing is to have two different
apid_id_validchecks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.
that looks like more clear.
Thanks
Yinghai
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 29 lines · Yinghai Lu
Quoted 13 lines · Suresh Siddha
Quoted 12 lines · Yinghai Lu
Quoted 6 lines · Steffen Persvold
Use
x2apic_supported()in thedefault_apic_id_valid()function. If x2apic mode is disabled (via nox2apic for example),x2apic_supported()will return false.This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
Signed-off-by Steffen Persvold <[email protected]>Reviewed-by Daniel J Blueman <[email protected]>I double checked on system with x2apic preenabled, nox2apic in boot command line still works well and it skips starting APs with apic id > 255.
Quoted 5 lines
Quoted 1 line
Acked-by Yinghai Lu <[email protected]>This breaks the smpboot check if enabling interrupt-remapping/x2apic fails on a platform. We will be in xapic mode and we don't clear the x2apic cpufeature bit in this case and as such smpboot check will fail.
two cases:
A: x2apic is pre-enabled, and some apic id > 255
B: x2apic is not pre-enabled, but x2apic capable, suppose all apic id < 255.in case A: if nox2apic is passed, or dmar table is not there or intr-remap can not be enabled.
that feature bit will be cleared. So checkcpu_has_x2apicis enough there.
Quoted 9 lines
in case B: if can not enable x2apic, the feature is not cleared, but apic id already < 255.
so that check will pass too.So it should not break the smpboot check.
Quoted 3 lines
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.
Actually before I sent out acked-by, I did test the patch on my 8 sockets x2apic pre-enabled system with nox2apic.
It booted well while skipping all cpu with apic id > 255.
Thanks
Yinghai
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
In reply to Yinghai LuQuoted 10 lines · Yinghai Lu
Quoted 8 lines
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.I think the right thing is to have two different
apid_id_validchecks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.that looks like more clear.
after more thinking, I think We should still use cpu_has_x2apic checking.
one maybe invalid case:
System have some cpus apic id < 255, and some cpu apic id > 255. BSP apic id < 255.
those cpus apic id < 255 will be put into xapic mode, cpus > 255 will be put into x2apic mode.
and DMAR table intr-remapping will be working.
So if we check x2apic_mode early, will skip cpu with apic id > 255, even switch to x2apic later.
Thanks
Yinghai Lu
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 14 lines · Yinghai Lu
Quoted 10 lines · Yinghai Lu
Quoted 8 lines
So this change breaks the commit
c284b42abadbb22083bfde24d308899c08d44ffa.I think the right thing is to have two different
apid_id_validchecks one for xapic driver (apic_flat_64.c) and another for x2apic driver (x2apic_phys/cluster.c) and that way, x2apic MADT entries will be parsed only if bios has handed over the OS in x2apic mode or if we have selected the numachip model.that looks like more clear.
after more thinking, I think We should still use
cpu_has_x2apicchecking.
Quoted 7 lines
one maybe invalid case:
System have some cpus apic id< 255, and some cpu apic id> 255. BSP apic id< 255.
those cpus apic id< 255 will be put into xapic mode, cpus> 255 will be put into x2apic mode.
and DMAR table intr-remapping will be working.
Hmm, I didn't know you could have two apic drivers (e.g. apic_flat_64 and x2apic_*) available at the same time ? Or did I read the above wrong ?
Quoted 4 lines
So if we check
x2apic_modeearly, will skip cpu with apic id> 255, even switch to x2apic later.
Which one of the two patches I sent, do you (Suresh/Yinghai/others) believe is the best/cleanest and works in all cases. I, unfortunately, can't test the Intel case as I don't have any available to test on :/
Either patch works fine for NumaChip enabled systems.
If desired I will re-post the patch with the approach you find best, but add the apic->apic_id_valid() check in the SRAT code aswell.
Cheers,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Re: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 8 lines · Steffen Persvold
Which one of the two patches I sent, do you (Suresh/Yinghai/others) believe is the best/cleanest and works in all cases. I, unfortunately, can't test the Intel case as I don't have any available to test on :/
Either patch works fine for NumaChip enabled systems.
If desired I will re-post the patch with the approach you find best, but add the
apic->apic_id_valid()check in the SRAT code aswell.
Ok, let use second way that Suresh proposed, please repost that without removing checking in srat.
should like:
From: Steffen Persvold <[email protected]>
Subject: [PATCH] Added separate apic_id_valid() functions for selected apic drivers
This allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate apic_id_valid() functions which will accept x2apic type IDs :
x2apic_physx2apic_clusterx2apic_uv_xapic_numachip
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-)
arch/x86/include/asm/apic.h +1 -1
@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return (apicid <255 ); }extern void default_setup_apic_routing (void );
arch/x86/include/asm/x2apic.h +5 -0
@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_targreturn cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;
arch/x86/kernel/acpi/boot.c +1 -1
@@ -227,7 +227,7 @@ acpi_parse_x2apic(struct acpi_subtable_h* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);
arch/x86/kernel/apic/apic_numachip.c +0 -1
@@ -229,11 +229,10 @@ static int __init numachip_system_init(v }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check(char *oem_id, char
*oem_table_id)
+static int numachip_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
if (!strncmp(oem_id, "NUMASC", 6)) {
numachip_system = 1;
- setup_force_cpu_cap(X86_FEATURE_X2APIC);
return 1;
}
arch/x86/kernel/apic/x2apic_cluster.c +1 -1
@@ -218,7 +218,7 @@ static struct apic apic_x2apic_cluster = .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -1
@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +6 -1
@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;
@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/mm/srat.c +1 -1
@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct acreturn ; pxm = pa->proximity_domain; apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { +if (!apic->apic_id_valid (apic_id)) {printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , pxm, apic_id);return ;
Suresh Siddha
Acked-byRe: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 26 lines · Yinghai Lu
Quoted 8 lines · Steffen Persvold
Which one of the two patches I sent, do you (Suresh/Yinghai/others) believe is the best/cleanest and works in all cases. I, unfortunately, can't test the Intel case as I don't have any available to test on :/
Either patch works fine for NumaChip enabled systems.
If desired I will re-post the patch with the approach you find best, but add the
apic->apic_id_valid()check in the SRAT code aswell.Ok, let use second way that Suresh proposed, please repost that without removing checking in srat.
should like:
From: Steffen Persvold <[email protected]>
Subject: [PATCH] Added separateapic_id_valid()functions for selected apic driversThis allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate
apic_id_valid()functions which will accept x2apic type IDs :
Quoted 6 lines
x2apic_physx2apic_clusterx2apic_uv_xapic_numachipSigned-off-by Steffen Persvold <[email protected]>
I have no complaints with this version ;)
Quoted 135 lines
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-)Index:
linux-2.6/arch/x86/include/asm/apic.h
===================================================================arch/x86/include/asm/apic.h +1
-1@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return (apicid <255 ); }extern void default_setup_apic_routing (void );Index:
linux-2.6/arch/x86/include/asm/x2apic.h
===================================================================arch/x86/include/asm/x2apic.h +5
-0@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_targreturn cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;Index:
linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================arch/x86/kernel/acpi/boot.c +1
-1@@ -227,7 +227,7 @@ acpi_parse_x2apic(struct acpi_subtable_h* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);Index:
linux-2.6/arch/x86/kernel/apic/apic_numachip.c
===================================================================arch/x86/kernel/apic/apic_numachip.c +1
-2@@ -229,11 +229,10 @@ static int __init numachip_system_init(v }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }Index:
linux-2.6/arch/x86/kernel/apic/x2apic_cluster.c
===================================================================arch/x86/kernel/apic/x2apic_cluster.c +1
-1@@ -218,7 +218,7 @@ static struct apic apic_x2apic_cluster = .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,Index:
linux-2.6/arch/x86/kernel/apic/x2apic_phys.c
===================================================================arch/x86/kernel/apic/x2apic_phys.c +1
-1@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,Index:
linux-2.6/arch/x86/kernel/apic/x2apic_uv_x.c
===================================================================arch/x86/kernel/apic/x2apic_uv_x.c +6
-1@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,Index:
linux-2.6/arch/x86/mm/srat.c
===================================================================arch/x86/mm/srat.c +1
-1@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct acreturn ; pxm = pa->proximity_domain; apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { +if (!apic->apic_id_valid (apic_id)) {printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , pxm, apic_id);return ;
Yinghai Lu
Acked-byRe: [PATCH] Use x2apic_supported() in the default_apic_id_valid() function.
Quoted 32 lines · Suresh Siddha
Quoted 31 lines · Yinghai Lu
Quoted 8 lines · Steffen Persvold
Which one of the two patches I sent, do you (Suresh/Yinghai/others) believe is the best/cleanest and works in all cases. I, unfortunately, can't test the Intel case as I don't have any available to test on :/
Either patch works fine for NumaChip enabled systems.
If desired I will re-post the patch with the approach you find best, but add the
apic->apic_id_valid()check in the SRAT code aswell.Ok, let use second way that Suresh proposed, please repost that without removing checking in srat.
should like:
From: Steffen Persvold <[email protected]>
Subject: [PATCH] Added separateapic_id_valid()functions for selected apic driversThis allows us to substitute the check in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic and avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate
apic_id_valid()functions which will accept x2apic type IDs :
x2apic_physx2apic_clusterx2apic_uv_xapic_numachip
Quoted 5 lines
Quoted 1 line
Signed-off-by Steffen Persvold <[email protected]>I have no complaints with this version ;)
Acked-by Suresh Siddha <[email protected]>
good,
also we could add more lines in changelog:
for x2apic pre-enabled system, apic driver is set already early through
early_acpi_boot_init()/early_acpi_process_madt()/acpi_parse_madt()/default_acpi_madt_oem_check()
so that apic_id_valid() checking will let entry go during MADT and SRAT prasing.
for x2apic not pre-enabled system, all apic id should be less than 255.
Quoted 138 lines
Quoted 136 lines
---
arch/x86/include/asm/apic.h | 2 +-arch/x86/include/asm/x2apic.h| 5 +++++arch/x86/kernel/acpi/boot.c| 2 +-arch/x86/kernel/apic/apic_numachip.c| 3 +--arch/x86/kernel/apic/x2apic_cluster.c| 2 +-arch/x86/kernel/apic/x2apic_phys.c| 2 +-arch/x86/kernel/apic/x2apic_uv_x.c| 7 ++++++-arch/x86/mm/srat.c| 2 +-8 files changed, 17 insertions(+), 8 deletions(-)Index:
linux-2.6/arch/x86/include/asm/apic.h
===================================================================arch/x86/include/asm/apic.h +1
-1@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id( static inline int default_apic_id_valid(int apicid) { - return x2apic_mode || (apicid < 255); + return (apicid < 255); } extern void default_setup_apic_routing(void);Index:
linux-2.6/arch/x86/include/asm/x2apic.h
===================================================================arch/x86/include/asm/x2apic.h +5
-0@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_targ return cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ + return 1; +} + static int x2apic_apic_id_registered(void) { return 1;Index:
linux-2.6/arch/x86/kernel/acpi/boot.c
===================================================================arch/x86/kernel/acpi/boot.c +1
-1@@ -227,7 +227,7 @@ acpi_parse_x2apic(struct acpi_subtable_h* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ - if (!cpu_has_x2apic && (apic_id >= 0xff) && enabled) + if (!apic->apic_id_valid(apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else
acpi_register_lapic(apic_id, enabled);
Index:linux-2.6/arch/x86/kernel/apic/apic_numachip.c
===================================================================arch/x86/kernel/apic/apic_numachip.c +1
-2@@ -229,11 +229,10 @@ static int __init numachip_system_init(v } early_initcall(numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) { if (!strncmp(oem_id, "NUMASC", 6)) { numachip_system = 1; - setup_force_cpu_cap(X86_FEATURE_X2APIC); return 1; }Index:
linux-2.6/arch/x86/kernel/apic/x2apic_cluster.c
===================================================================arch/x86/kernel/apic/x2apic_cluster.c +1
-1@@ -218,7 +218,7 @@ static struct apic apic_x2apic_cluster = .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,Index:
linux-2.6/arch/x86/kernel/apic/x2apic_phys.c
===================================================================arch/x86/kernel/apic/x2apic_phys.c +1
-1@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,Index:
linux-2.6/arch/x86/kernel/apic/x2apic_uv_x.c
===================================================================arch/x86/kernel/apic/x2apic_uv_x.c +6
-1@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector) uv_send_IPI_mask(cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ + return 1; +} + static int uv_apic_id_registered(void) { return 1;@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,Index:
linux-2.6/arch/x86/mm/srat.c
===================================================================arch/x86/mm/srat.c +1
-1@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct ac return; pxm = pa->proximity_domain; apic_id = pa->apic_id; - if (!cpu_has_x2apic && (apic_id >= 0xff)) { + if (!apic->apic_id_valid(apic_id)) { printk(KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n", pxm, apic_id); return;
PATCH 1/1 Added separate apic_id_valid() functions for selected apic drivers.
As suggested by Suresh Siddha <[email protected]> and Yinghai Lu <[email protected]> :
For x2apic pre-enabled systems, apic driver is set already early through early_acpi_boot_init()/early_acpi_process_madt()/acpi_parse_madt()/default_acpi_madt_oem_check() so that apic_id_valid() checking will be sufficient during MADT and SRAT prasing. For non- x2apic pre-enabled systems, all apic ids should be less than 255.
This allows us to substitute the checks in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() and arch/x86/mm/srat.c::acpi_numa_x2apic_affinity_init() with apic->apic_id_valid().
In addition we can avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate apic_id_valid() functions which will accept x2apic type IDs :
x2apic_physx2apic_clusterx2apic_uv_xapic_numachip
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-)
arch/x86/include/asm/apic.h +1 -1
@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(void)static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return (apicid <255 ); }extern void default_setup_apic_routing (void );
arch/x86/include/asm/x2apic.h +5 -0
@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_target_cpus(void)return cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;
arch/x86/kernel/acpi/boot.c +1 -1
@@ -239,7 +239,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);
arch/x86/kernel/apic/apic_numachip.c +1 -2
@@ -229,11 +229,10 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
arch/x86/kernel/apic/x2apic_cluster.c +1 -1
@@ -213,7 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -1
@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +6 -1
@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;
@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/mm/srat.c +1 -1
@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; pxm = pa->proximity_domain; apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { +if (!apic->apic_id_valid (apic_id)) {printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , pxm, apic_id);return ;
Signature · 1 line
1.7.4.1
Re: [PATCH REPOST] Added separate apic_id_valid() functions for selected apic drivers.
Quoted 8 lines · Steffen Persvold
As suggested by Suresh Siddha<[email protected]> and Yinghai Lu<[email protected]> :
For x2apic pre-enabled systems, apic driver is set already early through early_acpi_boot_init()/early_acpi_process_madt()/acpi_parse_madt()/default_acpi_madt_oem_check() so that
apic_id_valid()checking will be sufficient during MADT and SRAT prasing. For non- x2apic pre-enabled systems, all apic ids should be less than 255.This allows us to substitute the checks in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() and arch/x86/mm/srat.c::acpi_numa_x2apic_affinity_init() with
apic->apic_id_valid().In addition we can avoid feigning the x2apic cpu feature in the NumaChip apic code.
Quoted 8 lines
The following apic drivers have separate
apic_id_valid()functions which will accept x2apic type IDs :
x2apic_physx2apic_clusterx2apic_uv_xapic_numachipSigned-off-by Steffen Persvold<[email protected]>
Ingo, any comments on this approach ? It should cover both cases as suggested by Suresh and Yinghai.
Kind regards,
Signature · 3 lines
Steffen Persvold, Chief Architect NumaChip Numascale AS - www.numascale.com Tel: +47 92 49 25 54 Skype: spersvold
Quoted 134 lines
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-)arch/x86/include/asm/apic.h +1
-1@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(void)static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid<255 ); +return (apicid<255 ); }extern void default_setup_apic_routing (void );arch/x86/include/asm/x2apic.h +5
-0@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_target_cpus(void)return cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;arch/x86/kernel/acpi/boot.c +1
-1@@ -239,7 +239,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic&& (apic_id>=0xff )&& enabled) +if (!apic->apic_id_valid (apic_id)&& enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);arch/x86/kernel/apic/apic_numachip.c +1
-2@@ -229,11 +229,10 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }arch/x86/kernel/apic/x2apic_cluster.c +1
-1@@ -213,7 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,arch/x86/kernel/apic/x2apic_phys.c +1
-1@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,arch/x86/kernel/apic/x2apic_uv_x.c +6
-1@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,arch/x86/mm/srat.c +1
-1@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; pxm = pa->proximity_domain; apic_id = pa->apic_id; -if (!cpu_has_x2apic&& (apic_id>=0xff )) { +if (!apic->apic_id_valid (apic_id)) {printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , pxm, apic_id);return ;
Re: [PATCH REPOST] Added separate apic_id_valid() functions for selected apic drivers.
Quoted 2 lines · Steffen Persvold
Ingo, any comments on this approach ? It should cover both cases as suggested by Suresh and Yinghai.
Looks good in principle, but we are in the v3.4 merge window right now - new patches will have to wait a bit.
Thanks,
Ingo
[tip:x86/urgent] x86/apic: Add separate apic_id_valid() functions for selected apic drivers
In reply to Steffen PersvoldCommit-ID: b7157acf429e6aef690646ba964b9ebd25049ec2 Gitweb: http://git.kernel.org/tip/b7157acf429e6aef690646ba964b9ebd25049ec2 Author: Steffen Persvold <[email protected]> AuthorDate: Fri, 16 Mar 2012 20:25:35 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 23 Mar 2012 13:28:43 +0100
x86/apic: Add separate apic_id_valid() functions for selected apic drivers
As suggested by Suresh Siddha and Yinghai Lu:
For x2apic pre-enabled systems, apic driver is set already early through early_acpi_boot_init()/early_acpi_process_madt()/ acpi_parse_madt()/default_acpi_madt_oem_check() path so that apic_id_valid() checking will be sufficient during MADT and SRAT parsing.
For non-x2apic pre-enabled systems, all apic ids should be less than 255.
This allows us to substitute the checks in arch/x86/kernel/acpi/boot.c::acpi_parse_x2apic() and arch/x86/mm/srat.c::acpi_numa_x2apic_affinity_init() with apic->apic_id_valid().
In addition we can avoid feigning the x2apic cpu feature in the NumaChip apic code.
The following apic drivers have separate apic_id_valid() functions which will accept x2apic type IDs :
x2apic_phys
x2apic_cluster
x2apic_uv_x
apic_numachip
--- arch/x86/include/asm/apic.h | 2 +- arch/x86/include/asm/x2apic.h | 5 +++++ arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/apic_numachip.c | 3 +-- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- arch/x86/mm/srat.c | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-)
arch/x86/include/asm/apic.h +1 -1
@@ -535,7 +535,7 @@ static inline unsigned int read_apic_id(void)static inline int default_apic_id_valid (int apicid) { -return x2apic_mode || (apicid <255 ); +return (apicid <255 ); }extern void default_setup_apic_routing (void );
arch/x86/include/asm/x2apic.h +5 -0
@@ -18,6 +18,11 @@ static const struct cpumask *x2apic_target_cpus(void)return cpu_online_mask; } +static int x2apic_apic_id_valid (int apicid) +{ +return 1 ; +} +static int x2apic_apic_id_registered (void ) {return 1 ;
arch/x86/kernel/acpi/boot.c +1 -1
@@ -239,7 +239,7 @@ acpi_parse_x2apic(struct acpi_subtable_header *header, const unsigned long end)* to not preallocating memory for all NR_CPUS * when we use CPU hotplug. */ -if (!cpu_has_x2apic && (apic_id >=0xff ) && enabled) +if (!apic->apic_id_valid (apic_id) && enabled) printk(KERN_WARNING PREFIX "x2apic entry ignored\n");else acpi_register_lapic (apic_id, enabled);
arch/x86/kernel/apic/apic_numachip.c +1 -2
@@ -229,11 +229,10 @@ static int __init numachip_system_init(void) }early_initcall (numachip_system_init); -static int __cpuinit numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) +static int numachip_acpi_madt_oem_check (char *oem_id,char *oem_table_id) {if (!strncmp (oem_id,"NUMASC" ,6 )) { numachip_system =1 ; -setup_force_cpu_cap (X86_FEATURE_X2APIC );return 1 ; }
arch/x86/kernel/apic/x2apic_cluster.c +1 -1
@@ -213,7 +213,7 @@ static struct apic apic_x2apic_cluster = { .name = "cluster x2apic", .probe = x2apic_cluster_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_LowestPrio,
arch/x86/kernel/apic/x2apic_phys.c +1 -1
@@ -119,7 +119,7 @@ static struct apic apic_x2apic_phys = { .name = "physical x2apic", .probe = x2apic_phys_probe, .acpi_madt_oem_check = x2apic_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = x2apic_apic_id_valid, .apic_id_registered = x2apic_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/kernel/apic/x2apic_uv_x.c +6 -1
@@ -266,6 +266,11 @@ static void uv_send_IPI_all(int vector)uv_send_IPI_mask (cpu_online_mask, vector); } +static int uv_apic_id_valid (int apicid) +{ +return 1 ; +} +static int uv_apic_id_registered (void ) {return 1 ;
@@ -351,7 +356,7 @@ static struct apic __refdata apic_x2apic_uv_x = { .name = "UV large system", .probe = uv_probe, .acpi_madt_oem_check = uv_acpi_madt_oem_check, - .apic_id_valid = default_apic_id_valid, + .apic_id_valid = uv_apic_id_valid, .apic_id_registered = uv_apic_id_registered, .irq_delivery_mode = dest_Fixed,
arch/x86/mm/srat.c +1 -1
@@ -70,7 +70,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)return ; pxm = pa->proximity_domain; apic_id = pa->apic_id; -if (!cpu_has_x2apic && (apic_id >=0xff )) { +if (!apic->apic_id_valid (apic_id)) {printk (KERN_INFO "SRAT: PXM %u -> X2APIC 0x%04x ignored\n" , pxm, apic_id);return ;
cover Improvements to Yinghai's x86 IOAPIC hotplug work
In reply to Yinghai LuThis patchset is based on Yinghua's work for IOAPIC hotplug on x86 systems, please refer to http://lwn.net/Articles/483671/. It applies to:
94738bb PCI: Disable mem in the ioapic removing path
atgit://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-irq
Due to resource limitation, (only an Intel Atom system available for building and testing), only the boot logic has been tested until now, so need more tests for the hotplug logic when having access to systems with IOAPIC hotplug feature.
BTW, it's really a nightmare to build and test kernel on an Intel Atom system.
Jiang Liu (6):
x86,IRQ: Fix possible invalid memory access after IOAPIC hot-plugging x86,IRQ: Mark unused entries in 'ioapics' array as free at startup x86,IRQ: Enhance irq allocation policy for hot-added IOAPICs x86,IRQ: split out function ioapic_setup_resource() x86,IRQ: Correctly manage MMIO resource used by IOAPIC when
hot-plugging IOPAICs
x86,IRQ: Use memory barriers to protect searching side code
arch/x86/kernel/apic/io_apic.c | 150 +++++++++++++++++++++++++++++----------- 1 files changed, 110 insertions(+), 40 deletions(-)
Signature · 1 line
1.7.5.4
cover Improvements to Yinghai's IOAPIC hotplug work on x86
This patchset is based on Yinghua's work for IOAPIC hotplug on x86, please refer to http://lwn.net/Articles/483671/.
The first two patches are minor bugfixes, the third and fourth are enhancement to Yinghai's implementation, and the fifth is a RFC patch.
I only have an Atom system at hand to build and test the patchset, so only the boot logic has been tested until now, need more tests about the hotplug logic when having access to systems which support IOAPIC hotplug feature.
BTW, it's really a nightmare to build and test kernel on an Atom system.
Jiang Liu (5):
x86:IRQ: Fix possible invalid memory access when hot-plugging IOAPICs x86:IRQ: Mark unused entries in 'ioapics' array as free at startup x86:IRQ: Enhance irq allocation policy for hot-added IOAPICs x86:IRQ: Correctly manage MMIO resource used by IOAPIC when
hot-plugging
x86:IRQ: Use memory barriers to protect searching side code
arch/x86/kernel/apic/io_apic.c | 159 ++++++++++++++++++++++++++++------------ 1 files changed, 113 insertions(+), 46 deletions(-)
Signature · 1 line
1.7.5.4
PATCH 1/6 x86,IRQ: Fix possible invalid memory access after IOAPIC hot-plugging
In reply to Jiang LiuFunction free_ioapic_saved_registers() should mark ioapic->saved_regiters as NULL after the memory has been freed. Otherwise when hot-adding another IOAPIC, function alloc_ioapic_saved_registers() may reuse the stale pointer and cause memory corruption.
--- arch/x86/kernel/apic/io_apic.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
arch/x86/kernel/apic/io_apic.c +1 -0
@@ -362,6 +362,7 @@ static void alloc_ioapic_saved_registers(int idx)static void free_ioapic_saved_registers (int idx) {kfree (ioapics[idx].saved_registers); + ioapics[idx].saved_registers =NULL ; }int __init arch_early_irq_init (void )
Signature · 1 line
1.7.5.4
PATCH 2/6 x86,IRQ: Mark unused entries in 'ioapics' array as free at startup
In reply to Jiang LiuUnused entries in ioapics array should be marked as free at startup, so they could be used by hot-added IOAPICs.
--- arch/x86/kernel/apic/io_apic.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/x86/kernel/apic/io_apic.c +4 -0
@@ -392,6 +392,10 @@ int __init arch_early_irq_init(void)cpumask_set_cpu (0 , cfg->domain); } +/* Mark all left entries as free for IOAPIC hot-adding. */ +for (i = nr_ioapics; i <MAX_IO_APICS ; i++) + ioapics[i].mp_config.apicid =0xff ; +return 0 ; }
Signature · 1 line
1.7.5.4
Re: [PATCH 2/6] x86,IRQ: Mark unused entries in 'ioapics' array as free at startup
Quoted 13 lines · Jiang Liu
Unused entries in ioapics array should be marked as free at startup, so they could be used by hot-added IOAPICs.
Signed-off-by Jiang Liu <[email protected]>---
arch/x86/kernel/apic/io_apic.c | 4 ++++1 files changed, 4 insertions(+), 0 deletions(-)arch/x86/kernel/apic/io_apic.c +0
-0
arch/x86/kernel/apic/io_apic.c int __init arch_early_irq_init(void) · line 400
Quoted 9 lines
arch/x86/kernel/apic/io_apic.c +4
-0@@ -392,6 +392,10 @@ int __init arch_early_irq_init(void) cpumask_set_cpu(0, cfg->domain); } + /* Mark all left entries as free for IOAPIC hot-adding. */ + for (i = nr_ioapics; i < MAX_IO_APICS; i++) + ioapics[i].mp_config.apicid = 0xff; + return 0; }
this one looks like not needed, we did not search that after nr_ioapics, and just use nr_ioapics if open spot is found.
Yinghai
Re: [PATCH 2/6] x86,IRQ: Mark unused entries in 'ioapics' array as free at startup
So seems another patch is needed to search all entries in the ioapics array to find a free entry for real hot-added IOAPICs. Current implementation can only support hot-replace scenario, but can't support real hot-add. If needed, I will work out another patch to address that.
Gerry
Quoted 30 lines · Yinghai Lu
Quoted 13 lines · Jiang Liu
Unused entries in ioapics array should be marked as free at startup, so they could be used by hot-added IOAPICs.
Signed-off-by Jiang Liu<[email protected]>--- arch/x86/kernel/apic/io_apic.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)arch/x86/kernel/apic/io_apic.c +0
-0arch/x86/kernel/apic/io_apic.c int __init arch_early_irq_init(void) · line 400
Quoted 9 lines
arch/x86/kernel/apic/io_apic.c +4
-0@@ -392,6 +392,10 @@ int __init arch_early_irq_init(void)cpumask_set_cpu (0 , cfg->domain); } +/* Mark all left entries as free for IOAPIC hot-adding. */ +for (i = nr_ioapics; i<MAX_IO_APICS ; i++) + ioapics[i].mp_config.apicid =0xff ; +return 0 ; }this one looks like not needed, we did not search that after
nr_ioapics, and just usenr_ioapicsif open spot is found.Yinghai
Re: [PATCH 2/6] x86,IRQ: Mark unused entries in 'ioapics' array as free at startup
Hi Yinghai,
Get your points now and will drop this patch from the series. Thanks!
Quoted 40 lines · Jiang Liu
So seems another patch is needed to search all entries in the ioapics array to find a free entry for real hot-added IOAPICs. Current implementation can only support hot-replace scenario, but can't support real hot-add. If needed, I will work out another patch to address that.
Gerry
Quoted 30 lines · Yinghai Lu
Quoted 13 lines · Jiang Liu
Unused entries in ioapics array should be marked as free at startup, so they could be used by hot-added IOAPICs.
Signed-off-by Jiang Liu<[email protected]>--- arch/x86/kernel/apic/io_apic.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)arch/x86/kernel/apic/io_apic.c +0
-0arch/x86/kernel/apic/io_apic.c int __init arch_early_irq_init(void) · line 400
Quoted 9 lines
arch/x86/kernel/apic/io_apic.c +4
-0@@ -392,6 +392,10 @@ int __init arch_early_irq_init(void)cpumask_set_cpu (0 , cfg->domain); } +/* Mark all left entries as free for IOAPIC hot-adding. */ +for (i = nr_ioapics; i<MAX_IO_APICS ; i++) + ioapics[i].mp_config.apicid =0xff ; +return 0 ; }this one looks like not needed, we did not search that after
nr_ioapics, and just usenr_ioapicsif open spot is found.Yinghai
PATCH 3/6 x86,IRQ: Enhance irq allocation policy for hot-added IOAPICs
In reply to Jiang LiuFor hot-added IOAPICs, try to allocate irqs starting from ioapic->gsi_base first, and fallback to starting from 0.
--- arch/x86/kernel/apic/io_apic.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
arch/x86/kernel/apic/io_apic.c +6 -3
@@ -294,13 +294,16 @@ static struct irq_cfg *realloc_irq_and_cfg_at(unsigned int at, int node)return alloc_irq_and_cfg_at (at, node); } -static int reserve_ioapic_gsi_irq_base (int idx) +static int reserve_ioapic_gsi_irq_base (int idx,bool hotadd) {int irq;struct mp_ioapic_gsi *gsi_cfg =mp_ioapic_gsi_routing (idx);int cnt = gsi_cfg->gsi_end - gsi_cfg->gsi_base +1 ; irq =__irq_reserve_irqs (-1 , gsi_cfg->gsi_base, cnt); +if (irq <0 && hotadd) + irq =__irq_reserve_irqs (-1 ,0 , cnt); +if (irq >=0 ) { gsi_cfg->irq_base = irq; printk(KERN_INFO
@@ -378,7 +381,7 @@ int __init arch_early_irq_init(void)alloc_ioapic_saved_registers (i);for (i =0 ; i < nr_ioapics; i++) -reserve_ioapic_gsi_irq_base (i); +reserve_ioapic_gsi_irq_base (i, false);reserve_ioapic_gsi_irq_extra ();
@@ -4181,7 +4184,7 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd)if (gsi_cfg->gsi_end >= gsi_top) gsi_top = gsi_cfg->gsi_end +1 ; }else { -int irq =reserve_ioapic_gsi_irq_base (idx); +int irq =reserve_ioapic_gsi_irq_base (idx, true);if (irq <0 ) goto failed;
Signature · 1 line
1.7.5.4
PATCH 4/6 x86,IRQ: split out function ioapic_setup_resource()
In reply to Jiang LiuSplit out function ioapic_setup_resource(), which will be used by IOAPIC hotplug logic.
--- arch/x86/kernel/apic/io_apic.c | 69 ++++++++++++++++++++++------------------ 1 files changed, 38 insertions(+), 31 deletions(-)
arch/x86/kernel/apic/io_apic.c +38 -31
@@ -85,6 +85,7 @@ static struct ioapic {* Saved state during suspend/resume, or while enabling intr-remap. */ struct IO_APIC_route_entry *saved_registers; +struct resource *resource;/* I/O APIC config */ struct mpc_ioapic mp_config;/* IO APIC gsi routing info */
@@ -3987,7 +3988,7 @@ void __init setup_ioapic_dest(void)static struct resource *ioapic_resources; -static struct resource *__init ioapic_setup_resources (int nr_ioapics) +static struct resource *__init ioapic_alloc_resources (int nr_ioapics) {unsigned long n;struct resource *res;
@@ -4010,6 +4011,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) res[i].flags =IORESOURCE_MEM |IORESOURCE_BUSY ;snprintf (mem,IOAPIC_RESOURCE_NAME_SIZE ,"IOAPIC %u" , i); mem +=IOAPIC_RESOURCE_NAME_SIZE ; + ioapics[i].resource = &res[i]; } ioapic_resources = res;
@@ -4017,43 +4019,48 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)return res; } -void __init ioapic_and_gsi_init (void ) +static void ioapic_setup_resource (int idx,struct resource *res,bool hotadd) { -unsigned long ioapic_phys, idx =FIX_IO_APIC_BASE_0 ; -struct resource *ioapic_res; -int i; +unsigned long ioapic_phys, vaddr; - ioapic_res =ioapic_setup_resources (nr_ioapics); -for (i =0 ; i < nr_ioapics; i++) { -if (smp_found_config) { - ioapic_phys =mpc_ioapic_addr (i); +if (hotadd) { + ioapic_phys =mpc_ioapic_addr (idx); + }else if (smp_found_config) { + ioapic_phys =mpc_ioapic_addr (idx);#ifdef CONFIG_X86_32 -if (!ioapic_phys) { -printk (KERN_ERR -"WARNING: bogus zero IO-APIC " -"address found in MPTABLE, " -"disabling IO/APIC support!\n" ); - smp_found_config =0 ; - skip_ioapic_setup =1 ; - goto fake_ioapic_page; - } +if (!ioapic_phys) { +printk (KERN_ERR +"WARNING: bogus zero IO-APIC address found " +"in MPTABLE, disabling IO/APIC support!\n" ); + smp_found_config =0 ; + skip_ioapic_setup =1 ; + goto fake_ioapic_page; + }#endif - }else { + }else {#ifdef CONFIG_X86_32 fake_ioapic_page:#endif - ioapic_phys = (unsigned long )alloc_bootmem_pages (PAGE_SIZE ); - ioapic_phys =__pa (ioapic_phys); - } -set_fixmap_nocache (idx, ioapic_phys); -apic_printk (APIC_VERBOSE ,"mapped IOAPIC to %08lx (%08lx)\n" , -__fix_to_virt (idx) + (ioapic_phys & ~PAGE_MASK ), - ioapic_phys); - idx++; - - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys +IO_APIC_SLOT_SIZE -1 ; - ioapic_res++; + ioapic_phys = (unsigned long )alloc_bootmem_pages (PAGE_SIZE ); + ioapic_phys =__pa (ioapic_phys); + } + + vaddr =__fix_to_virt (FIX_IO_APIC_BASE_0 + idx); + vaddr += (ioapic_phys & ~PAGE_MASK ); +apic_printk (APIC_VERBOSE ,"mapped IOAPIC to %08lx (%08lx)\n" , + vaddr, ioapic_phys); + + res->start = ioapic_phys; + res->end = ioapic_phys +IO_APIC_SLOT_SIZE -1 ; +} + +void __init ioapic_and_gsi_init (void ) +{ +int i; + +ioapic_alloc_resources (nr_ioapics); +for (i =0 ; i < nr_ioapics; i++) { +ioapic_setup_resource (i, ioapics[i].resource, false); }probe_nr_irqs_gsi ();
Signature · 1 line
1.7.5.4
Re: [PATCH 4/6] x86,IRQ: split out function ioapic_setup_resource()
Quoted 87 lines · Jiang Liu
Split out function
ioapic_setup_resource(), which will be used by IOAPIC hotplug logic.Signed-off-by Jiang Liu <[email protected]>---
arch/x86/kernel/apic/io_apic.c | 69 ++++++++++++++++++++++------------------1 files changed, 38 insertions(+), 31 deletions(-)arch/x86/kernel/apic/io_apic.c +18
-19@@ -85,6 +85,7 @@ static struct ioapic {* Saved state during suspend/resume, or while enabling intr-remap. */ struct IO_APIC_route_entry *saved_registers; + struct resource *resource; /* I/O APIC config */ struct mpc_ioapic mp_config; /* IO APIC gsi routing info */@@ -3987,7 +3988,7 @@ void __init setup_ioapic_dest(void) static struct resource *ioapic_resources; -static struct resource *__init ioapic_setup_resources (int nr_ioapics) +static struct resource *__init ioapic_alloc_resources (int nr_ioapics) { unsigned long n; struct resource *res;@@ -4010,6 +4011,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); mem += IOAPIC_RESOURCE_NAME_SIZE; + ioapics[i].resource = &res[i]; } ioapic_resources = res;@@ -4017,43 +4019,48 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) return res; } -void __init ioapic_and_gsi_init (void ) +static void ioapic_setup_resource (int idx,struct resource *res,bool hotadd) { - unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; - struct resource *ioapic_res; - int i; + unsigned long ioapic_phys, vaddr; - ioapic_res = ioapic_setup_resources(nr_ioapics); - for (i = 0; i < nr_ioapics; i++) { - if (smp_found_config) { - ioapic_phys = mpc_ioapic_addr(i); + if (hotadd) { + ioapic_phys = mpc_ioapic_addr(idx); + } else if (smp_found_config) { + ioapic_phys = mpc_ioapic_addr(idx); #ifdef CONFIG_X86_32 - if (!ioapic_phys) { - printk(KERN_ERR - "WARNING: bogus zero IO-APIC " - "address found in MPTABLE, " - "disabling IO/APIC support!\n"); - smp_found_config = 0; - skip_ioapic_setup = 1; - goto fake_ioapic_page; - } + if (!ioapic_phys) { + printk(KERN_ERR + "WARNING: bogus zero IO-APIC address found " + "in MPTABLE, disabling IO/APIC support!\n"); + smp_found_config = 0; + skip_ioapic_setup = 1; + goto fake_ioapic_page; + } #endif - } else { + } else { #ifdef CONFIG_X86_32fake_ioapic_page:
#endif
-ioapic_phys= (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
-ioapic_phys=__pa(ioapic_phys);
- }
-set_fixmap_nocache(idx, ioapic_phys);
- apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
-__fix_to_virt(idx)+ (ioapic_phys& ~PAGE_MASK),
Quoted 8 lines
-
ioapic_phys);
- idx++;
-
-ioapic_res->start=ioapic_phys;
-ioapic_res->end=ioapic_phys+IO_APIC_SLOT_SIZE- 1;
- ioapic_res++;
+ioapic_phys= (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
+ioapic_phys=__pa(ioapic_phys);
where is calling set_fixmap_nocache for fake ioapic one?
Quoted 18 lines
+ }
arch/x86/kernel/apic/io_apic.c +17
-0+ + vaddr = __fix_to_virt(FIX_IO_APIC_BASE_0 + idx); + vaddr += (ioapic_phys & ~PAGE_MASK); + apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n", + vaddr, ioapic_phys); + + res->start = ioapic_phys; + res->end = ioapic_phys + IO_APIC_SLOT_SIZE - 1; +} + +void __init ioapic_and_gsi_init (void ) +{ + int i; + + ioapic_alloc_resources(nr_ioapics); + for (i = 0; i < nr_ioapics; i++) { + ioapic_setup_resource(i, ioapics[i].resource, false);
Quoted 1 line
}
how about booting system with ioapic device and later hot remove it?
maybe we can just alloc one by one.
Yinghai
Re: [PATCH 4/6] x86,IRQ: split out function ioapic_setup_resource()
Quoted 90 lines · Yinghai Lu
Quoted 89 lines · Jiang Liu
Split out function
ioapic_setup_resource(), which will be used by IOAPIC hotplug logic.Signed-off-by Jiang Liu<[email protected]>--- arch/x86/kernel/apic/io_apic.c | 69 ++++++++++++++++++++++------------------ 1 files changed, 38 insertions(+), 31 deletions(-)arch/x86/kernel/apic/io_apic.c +18
-27@@ -85,6 +85,7 @@ static struct ioapic {* Saved state during suspend/resume, or while enabling intr-remap. */ struct IO_APIC_route_entry *saved_registers; +struct resource *resource;/* I/O APIC config */ struct mpc_ioapic mp_config;/* IO APIC gsi routing info */ @@ -3987,7 +3988,7 @@ void __init setup_ioapic_dest(void)static struct resource *ioapic_resources; -static struct resource *__init ioapic_setup_resources (int nr_ioapics) +static struct resource *__init ioapic_alloc_resources (int nr_ioapics) {unsigned long n;struct resource *res;@@ -4010,6 +4011,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics) res[i].flags =IORESOURCE_MEM |IORESOURCE_BUSY ;snprintf (mem,IOAPIC_RESOURCE_NAME_SIZE ,"IOAPIC %u" , i); mem +=IOAPIC_RESOURCE_NAME_SIZE ; + ioapics[i].resource =&res[i]; } ioapic_resources = res;@@ -4017,43 +4019,48 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)return res; } -void __init ioapic_and_gsi_init (void ) +static void ioapic_setup_resource (int idx,struct resource *res,bool hotadd) { -unsigned long ioapic_phys, idx =FIX_IO_APIC_BASE_0 ; -struct resource *ioapic_res; -int i; +unsigned long ioapic_phys, vaddr; - ioapic_res =ioapic_setup_resources (nr_ioapics); -for (i =0 ; i< nr_ioapics; i++) { -if (smp_found_config) { - ioapic_phys =mpc_ioapic_addr (i); +if (hotadd) { + ioapic_phys =mpc_ioapic_addr (idx); + }else if (smp_found_config) { + ioapic_phys =mpc_ioapic_addr (idx);#ifdef CONFIG_X86_32 -if (!ioapic_phys) { -printk (KERN_ERR -"WARNING: bogus zero IO-APIC " -"address found in MPTABLE, " -"disabling IO/APIC support!\n" ); - smp_found_config =0 ; - skip_ioapic_setup =1 ; - goto fake_ioapic_page; - } +if (!ioapic_phys) { +printk (KERN_ERR +"WARNING: bogus zero IO-APIC address found " +"in MPTABLE, disabling IO/APIC support!\n" ); + smp_found_config =0 ; + skip_ioapic_setup =1 ; + goto fake_ioapic_page; + }#endif - }else { + }else {#ifdef CONFIG_X86_32 fake_ioapic_page:#endif - ioapic_phys = (unsigned long )alloc_bootmem_pages (PAGE_SIZE ); - ioapic_phys =__pa (ioapic_phys); - } -set_fixmap_nocache (idx, ioapic_phys); -apic_printk (APIC_VERBOSE ,"mapped IOAPIC to %08lx (%08lx)\n" , -__fix_to_virt (idx) + (ioapic_phys& ~PAGE_MASK ), - ioapic_phys); - idx++;
Quoted 8 lines
arch/x86/kernel/apic/io_apic.c static struct resource * __init ioapic_setup_resources(int nr_ioapics) · line 4045
Quoted 6 lines
arch/x86/kernel/apic/io_apic.c +2
-4- - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys +IO_APIC_SLOT_SIZE -1 ; - ioapic_res++; + ioapic_phys = (unsigned long )alloc_bootmem_pages (PAGE_SIZE ); + ioapic_phys =__pa (ioapic_phys);where is calling
set_fixmap_nocachefor fake ioapic one?
My bad, doesn't notice the case for fake ioapic, will add back the set_fixmap_nocache. I just noticed that set_fixmap_nocache() will be called twice for real IOAPICs.
Quoted 23 lines
Quoted 10 lines
arch/x86/kernel/apic/io_apic.c +9
-0+ } + + vaddr =__fix_to_virt (FIX_IO_APIC_BASE_0 + idx); + vaddr += (ioapic_phys& ~PAGE_MASK ); +apic_printk (APIC_VERBOSE ,"mapped IOAPIC to %08lx (%08lx)\n" , + vaddr, ioapic_phys); + + res->start = ioapic_phys; + res->end = ioapic_phys +IO_APIC_SLOT_SIZE -1 ;arch/x86/kernel/apic/io_apic.c static struct resource * __init ioapic_setup_resources(int nr_ioapics) · line 4064
Quoted 10 lines
arch/x86/kernel/apic/io_apic.c +9
-0+} + +void __init ioapic_and_gsi_init (void ) +{ +int i; + +ioapic_alloc_resources (nr_ioapics); +for (i =0 ; i< nr_ioapics; i++) { +ioapic_setup_resource (i, ioapics[i].resource, false); }how about booting system with ioapic device and later hot remove it?
Quoted 1 line
maybe we can just alloc one by one.
Here the issue is that, it uses bootmem allocator at boot time, which is paged aligned. So seems a little waste to allocate one page for each ioapic. The tradeoff here is to leak the memory if all IOAPICs are removed at runtime. If needed, we could add counter to track the allcoated bootmem and free it when counter reaches zero.
Quoted 5 lines
Yinghai
.
PATCH 5/6 x86,IRQ: Correctly manage MMIO resource used by IOAPIC when hot-plugging IOPAICs
In reply to Jiang LiuCorrectly manage MMIO resource used by IOAPIC when hot-plugging IOAPICs.
--- arch/x86/kernel/apic/io_apic.c | 46 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 45 insertions(+), 1 deletions(-)
arch/x86/kernel/apic/io_apic.c +45 -1
@@ -4054,6 +4054,42 @@ fake_ioapic_page: res->end = ioapic_phys +IO_APIC_SLOT_SIZE -1 ; } +static struct resource *ioapic_add_resource (int idx) +{ +char *name; +struct resource *res; +size_t sz =IOAPIC_RESOURCE_NAME_SIZE +sizeof (struct resource ); + + res =kzalloc (sz,GFP_KERNEL ); +if (res) { + res->flags =IORESOURCE_MEM |IORESOURCE_BUSY ; + res->name = name = (char *)(res +1 ); +snprintf (name,IOAPIC_RESOURCE_NAME_SIZE ,"IOAPIC %u" , idx); +ioapic_setup_resource (idx, res, true); + ioapics[idx].resource = res; + +if (insert_resource (&iomem_resource, res)) { +kfree (res); + res =NULL ; + } + } + +return res; +} + +static void ioapic_remove_resource (int idx) +{ +struct resource *res = ioapics[idx].resource; + +if (res) { +if (res->parent) +release_resource (res); +if (PageSlab (virt_to_page (res))) +kfree (res); + ioapics[idx].resource =NULL ; + } +} +void __init ioapic_and_gsi_init (void ) {int i;
@@ -4191,8 +4227,12 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd)if (gsi_cfg->gsi_end >= gsi_top) gsi_top = gsi_cfg->gsi_end +1 ; }else { -int irq =reserve_ioapic_gsi_irq_base (idx, true); +int irq; +if (ioapic_add_resource (idx) ==NULL ) + goto failed; + + irq =reserve_ioapic_gsi_irq_base (idx, true);if (irq <0 ) goto failed;
@@ -4210,6 +4250,7 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd)return 0 ; failed: +ioapic_remove_resource (idx);clear_fixmap (FIX_IO_APIC_BASE_0 + idx);memset (&ioapics[idx],0 ,sizeof (struct ioapic )); ioapics[idx].mp_config.apicid =0xff ;
@@ -4234,6 +4275,9 @@ int mp_unregister_ioapic(u32 gsi_base)free_ioapic_gsi_irq_base (idx);clear_fixmap (FIX_IO_APIC_BASE_0 + idx); + +ioapic_remove_resource (idx); +memset (&ioapics[idx],0 ,sizeof (struct ioapic )); ioapics[idx].mp_config.apicid =0xff ;
Signature · 1 line
1.7.5.4
PATCH 6/6 x86,IRQ: Use memory barriers to protect searching side code
In reply to Jiang LiuUse memory barriers to protect searching side code when hot-plugging IOAPICs.
--- arch/x86/kernel/apic/io_apic.c | 25 ++++++++++++++++++------- 1 files changed, 18 insertions(+), 7 deletions(-)
arch/x86/kernel/apic/io_apic.c +18 -7
@@ -352,12 +352,15 @@ static void free_ioapic_gsi_irq_base(int idx)static void alloc_ioapic_saved_registers (int idx) { +struct mp_ioapic_gsi *gsi_cfg =mp_ioapic_gsi_routing (idx); +int irq_cnt = gsi_cfg->gsi_end - gsi_cfg->gsi_base +1 ; +if (ioapics[idx].saved_registers)return ; ioapics[idx].saved_registers =kzalloc (sizeof (struct IO_APIC_route_entry ) * - ioapics[idx].nr_registers,GFP_KERNEL ); + irq_cnt,GFP_KERNEL );if (!ioapics[idx].saved_registers)pr_err ("IOAPIC %d: suspend/resume impossible!\n" , idx);
@@ -1174,6 +1177,8 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin,for (ioapic_idx =0 ; ioapic_idx < nr_ioapics; ioapic_idx++) {if (!ioapics[ioapic_idx].nr_registers)continue ; + +smp_rmb ();if (mpc_ioapic_id (ioapic_idx) == mp_irqs[i].dstapic || mp_irqs[i].dstapic ==MP_APIC_ALL )break ;
@@ -2083,7 +2088,7 @@ void __init enable_IO_APIC(void)if (!legacy_pic->nr_legacy_irqs)return ; -for (apic =0 ; apic < nr_ioapics; apic++) { +for (apic =0 ; apic < nr_ioapics; apic++) {int pin;/* See if any of the pins is in ExtINT mode */ for (pin =0 ; pin < ioapics[apic].nr_registers; pin++) {
@@ -4134,6 +4139,7 @@ int mp_find_ioapic(u32 gsi)if (!ioapics[i].nr_registers)continue ; +smp_rmb ();if ((gsi >= gsi_cfg->gsi_base) && (gsi <= gsi_cfg->gsi_end))return i; }
@@ -4214,11 +4220,6 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd) gsi_cfg->gsi_base = gsi_base; gsi_cfg->gsi_end = gsi_base + entries -1 ; -/* -* The number of IO-APIC IRQ registers (== #pins): -*/ - ioapics[idx].nr_registers = entries; -if (!hotadd) {/* * irqs will be reserved in arch_early_irq_init()
@@ -4247,6 +4248,13 @@ int __mp_register_ioapic(int id, u32 address, u32 gsi_base, bool hotadd)if (idx == nr_ioapics) nr_ioapics++; +smp_wmb (); + +/* +* The number of IO-APIC IRQ registers (== #pins): +*/ + ioapics[idx].nr_registers = entries; +return 0 ; failed:
@@ -4270,6 +4278,9 @@ int mp_unregister_ioapic(u32 gsi_base)if (idx <0 )return -EINVAL ; + ioapics[idx].nr_registers =0 ; +smp_wmb (); +free_ioapic_saved_registers (idx);free_ioapic_gsi_irq_base (idx);
Signature · 1 line
1.7.5.4