ACPI: boot correctly with "nosmp" or "maxcpus=0"
Subsystems (2)
Len Brown
reviewerPATCH 1/1 ACPI: boot correctly with "nosmp" or "maxcpus=0"
From: Len Brown <[email protected]>
In MPS mode, "nosmp" and "maxcpus=0" boot a UP kernel with IOAPIC disabled. However, in ACPI mode, these parameters didn't completely disable the IO APIC initialization code and boot failed.
init/main.c:
Disable the IO_APIC if "nosmp" or "maxcpus=0" undefine disable_ioapic_setup() when it doesn't apply.
i386:
delete ioapic_setup(), it was a duplicate of parse_noapic() delete undefinition of disable_ioapic_setup()
x86_64:
rename disable_ioapic_setup() to parse_noapic() to match i386 define disable_ioapic_setup() in header to match i386
http://bugzilla.kernel.org/show_bug.cgi?id=1641
--- Documentation/kernel-parameters.txt | 15 ++++++--------- arch/i386/kernel/io_apic.c | 8 -------- arch/x86_64/kernel/io_apic.c | 8 +++----- include/asm-i386/io_apic.h | 1 - include/asm-x86_64/io_apic.h | 6 ++++++ init/main.c | 12 ++++++++++-- 6 files changed, 25 insertions(+), 25 deletions(-)
Documentation/kernel-parameters.txt +6 -9
@@ -952,14 +952,10 @@ and is between 256 and 4096 characters. Format: <1-256> maxcpus= [SMP] Maximum number of processors that an SMP kernel - should make use of. - Using "nosmp" or "maxcpus=0" will disable SMP - entirely (the MPS table probe still happens, though). - A command-line option of "maxcpus=<NUM>", where <NUM> - is an integer greater than 0, limits the maximum number - of CPUs activated in SMP mode to <NUM>. - Using "maxcpus=1" on an SMP kernel is the trivial - case of an SMP kernel with only one CPU. + should make use of. maxcpus=n : n >= 0 limits the + kernel to using 'n' processors. n=0 is a special case, + it is equivalent to "nosmp", which also disables + the IO APIC. max_addr=[KMG] [KNL,BOOT,ia64] All physical memory greater than or equal to this physical address is ignored.
@@ -1184,7 +1180,8 @@ and is between 256 and 4096 characters. nosep [BUGS=X86-32] Disables x86 SYSENTER/SYSEXIT support. - nosmp [SMP] Tells an SMP kernel to act as a UP kernel. + nosmp [SMP] Tells an SMP kernel to act as a UP kernel, + and disable the IO APIC. legacy for "maxcpus=0". nosoftlockup [KNL] Disable the soft-lockup detector.
arch/i386/kernel/io_apic.c +0 -8
@@ -754,14 +754,6 @@ static int pirq_entries [MAX_PIRQS];static int pirqs_enabled;int skip_ioapic_setup; -static int __init ioapic_setup (char *str) -{ - skip_ioapic_setup =1 ; -return 1 ; -} - -__setup ("noapic" , ioapic_setup); -static int __init ioapic_pirq_setup (char *str) {int i, max;
arch/x86_64/kernel/io_apic.c +3 -5
@@ -397,14 +397,12 @@ static void clear_IO_APIC (void)int skip_ioapic_setup;int ioapic_force; -/* dummy parsing: see setup.c */ - -static int __init disable_ioapic_setup (char *str) +static int __init parse_noapic (char *str) { - skip_ioapic_setup =1 ; +disable_ioapic_setup ();return 0 ; } -early_param ("noapic" , disable_ioapic_setup); +early_param ("noapic" , parse_noapic);/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ static int __init disable_timer_pin_setup (char *arg)
include/asm-i386/io_apic.h +0 -1
@@ -150,7 +150,6 @@ extern int (*ioapic_renumber_irq)(int io#else /* !CONFIG_X86_IO_APIC */ #define io_apic_assign_pci_irqs 0 -static inline void disable_ioapic_setup (void ) { }#endif #endif
include/asm-x86_64/io_apic.h +6 -0
@@ -109,6 +109,12 @@ extern int mpc_default_type;/* 1 if "noapic" boot option passed */ extern int skip_ioapic_setup; +static inline void disable_ioapic_setup (void ) +{ + skip_ioapic_setup =1 ; +} + +/* * If we use the IO-APIC for IRQ routing, disable automatic * assignment of PCI IRQ's.
init/main.c +10 -2
@@ -146,9 +146,14 @@ static unsigned int __initdata max_cpus* greater than 0, limits the maximum number of CPUs activated in * SMP mode to <NUM>. */ +#ifndef CONFIG_X86_IO_APIC +static inline void disable_ioapic_setup (void ) {}; +#endif +static int __init nosmp (char *str) { max_cpus =0 ; +disable_ioapic_setup ();return 0 ; }
@@ -157,10 +162,13 @@ early_param("nosmp", nosmp);static int __init maxcpus (char *str) {get_option (&str, &max_cpus); -return 1 ; +if (max_cpus ==0 ) +disable_ioapic_setup (); + +return 0 ; } -__setup ("maxcpus=" , maxcpus); +early_param ("maxcpus=" , maxcpus);#else #define max_cpus NR_CPUS#endif
init/main.c early_param("nosmp", nosmp); · line 166
Quoted 7 lines
init/main.c +2
-1@@ -157,10 +162,13 @@ early_param("nosmp", nosmp);static int __init maxcpus (char *str) {get_option (&str, &max_cpus); -return 1 ; +if (max_cpus ==0 ) +disable_ioapic_setup ();
I must say I never liked that maxcpus=0 ... does disable the APIC too. There can be situations where you want only a single CPU, but still full APICs because modern systems don't boot without.
It's the old traditional documented semantics though,
but on the other hand if it never worked with ACPI i guess people are not relying on it.
So perhaps it would be better to change that?
Or add a new option to limit CPUs without disabling ACPIC?
-Andi
Len Brown
reviewerQuoted 11 lines · Andi Kleen
init/main.c early_param("nosmp", nosmp); · line 166
Quoted 7 lines
init/main.c +2
-1@@ -157,10 +162,13 @@ early_param("nosmp", nosmp);static int __init maxcpus (char *str) {get_option (&str, &max_cpus); -return 1 ; +if (max_cpus ==0 ) +disable_ioapic_setup ();I must say I never liked that maxcpus=0 ... does disable the APIC too. There can be situations where you want only a single CPU, but still full APICs because modern systems don't boot without.
maxcpus=1 will give you that.
new kernel-parameters.txt in patch should say this (matching what comment in the code says)
Quoted 6 lines
It's the old traditional documented semantics though,
but on the other hand if it never worked with ACPI i guess people are not relying on it.So perhaps it would be better to change that?
Or add a new option to limit CPUs without disabling ACPIC?
If we cared not for tradition, I'd delete "nosmp", maxcpus=0 would be a synonym for maxcpus=1
and if you didn't want an IOAPIC, you'd use "noapic" (heh, don't get me started on the noapic vs. nolapic legacy:-)
The only reason I fixed it instead of changing it per above is because people may be used to it in non ACPI configurations and get surprised when it doesn't do exactly the same thing (or in this case doesn't boot at all) in an ACPI configuration.
Either way is fine with me, but I can't leave it as "nosmp" and "maxcpus=0" not booting at all on ACPI boxes.
thanks,
-Len
Quoted 13 lines · On Friday 17 August 2007 01:06:47 Len Brown wrote:
Quoted 11 lines · Andi Kleen
init/main.c early_param("nosmp", nosmp); · line 166
Quoted 7 lines
init/main.c +2
-1@@ -157,10 +162,13 @@ early_param("nosmp", nosmp);static int __init maxcpus (char *str) {get_option (&str, &max_cpus); -return 1 ; +if (max_cpus ==0 ) +disable_ioapic_setup ();I must say I never liked that maxcpus=0 ... does disable the APIC too. There can be situations where you want only a single CPU, but still full APICs because modern systems don't boot without.
Quoted 3 lines
maxcpus=1 will give you that.
new kernel-parameters.txt in patch should say this (matching what comment in the code says)
Ok.
Quoted 4 lines
The only reason I fixed it instead of changing it per above is because people may be used to it in non ACPI configurations and get surprised when it doesn't do exactly the same thing (or in this case doesn't boot at all) in an ACPI configuration.
Patch is fine for me.
-Andi