diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 22:56:33 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-11 22:56:33 -0500 |
| commit | 74b84233458e9db7c160cec67638efdbec748ca9 (patch) | |
| tree | 0d174c7386386dca17f494396d7febc300ffa3dd | |
| parent | 507447473756e316f3f182324071389a51736a83 (diff) | |
| parent | a71c8bc5dfefbbf80ef90739791554ef7ea4401b (diff) | |
Merge branch 'x86-bsp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 BSP hotplug changes from Ingo Molnar:
"This tree enables CPU#0 (the boot processor) to be onlined/offlined on
x86, just like any other CPU. Enabled on Intel CPUs for now.
Allowing this required the identification and fixing of latent CPU#0
assumptions (such as CPU#0 initializations, etc.) in the x86
architecture code, plus the identification of barriers to
BSP-offlining, such as active PIC interrupts which can only be
serviced on the BSP.
It's behind a default-off option, and there's a debug option that
allows the automatic testing of this feature.
The motivation of this feature is to allow and prepare for true
CPU-hotplug hardware support: recent changes to MCE support enable us
to detect a deteriorating but not yet hard-failing L1/L2 cache on a
CPU that could be soft-unplugged - or a failing L3 cache on a
multi-socket system.
Note that true hardware hot-plug is not yet fully enabled by this,
because that requires a special platform wakeup sequence to be sent to
the freshly powered up CPU#0. Future patches for this are planned,
once such a platform exists. Chicken and egg"
* 'x86-bsp-hotplug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86, topology: Debug CPU0 hotplug
x86/i387.c: Initialize thread xstate only on CPU0 only once
x86, hotplug: Handle retrigger irq by the first available CPU
x86, hotplug: The first online processor saves the MTRR state
x86, hotplug: During CPU0 online, enable x2apic, set_numa_node.
x86, hotplug: Wake up CPU0 via NMI instead of INIT, SIPI, SIPI
x86-32, hotplug: Add start_cpu0() entry point to head_32.S
x86-64, hotplug: Add start_cpu0() entry point to head_64.S
kernel/cpu.c: Add comment for priority in cpu_hotplug_pm_callback
x86, hotplug, suspend: Online CPU0 for suspend or hibernate
x86, hotplug: Support functions for CPU0 online/offline
x86, topology: Don't offline CPU0 if any PIC irq can not be migrated out of it
x86, Kconfig: Add config switch for CPU0 hotplug
doc: Add x86 CPU0 online/offline feature
| -rw-r--r-- | Documentation/cpu-hotplug.txt | 24 | ||||
| -rw-r--r-- | Documentation/kernel-parameters.txt | 14 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 44 | ||||
| -rw-r--r-- | arch/x86/include/asm/cpu.h | 4 | ||||
| -rw-r--r-- | arch/x86/include/asm/smp.h | 1 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 4 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/cpu/mtrr/main.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/head_32.S | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/head_64.S | 16 | ||||
| -rw-r--r-- | arch/x86/kernel/i387.c | 6 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 149 | ||||
| -rw-r--r-- | arch/x86/kernel/topology.c | 101 | ||||
| -rw-r--r-- | arch/x86/power/cpu.c | 82 | ||||
| -rw-r--r-- | kernel/cpu.c | 5 |
15 files changed, 436 insertions, 41 deletions
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 66ef8f35613d..9f401350f502 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt | |||
| @@ -207,6 +207,30 @@ by making it not-removable. | |||
| 207 | 207 | ||
| 208 | In such cases you will also notice that the online file is missing under cpu0. | 208 | In such cases you will also notice that the online file is missing under cpu0. |
| 209 | 209 | ||
| 210 | Q: Is CPU0 removable on X86? | ||
| 211 | A: Yes. If kernel is compiled with CONFIG_BOOTPARAM_HOTPLUG_CPU0=y, CPU0 is | ||
| 212 | removable by default. Otherwise, CPU0 is also removable by kernel option | ||
| 213 | cpu0_hotplug. | ||
| 214 | |||
| 215 | But some features depend on CPU0. Two known dependencies are: | ||
| 216 | |||
| 217 | 1. Resume from hibernate/suspend depends on CPU0. Hibernate/suspend will fail if | ||
| 218 | CPU0 is offline and you need to online CPU0 before hibernate/suspend can | ||
| 219 | continue. | ||
| 220 | 2. PIC interrupts also depend on CPU0. CPU0 can't be removed if a PIC interrupt | ||
| 221 | is detected. | ||
| 222 | |||
| 223 | It's said poweroff/reboot may depend on CPU0 on some machines although I haven't | ||
| 224 | seen any poweroff/reboot failure so far after CPU0 is offline on a few tested | ||
| 225 | machines. | ||
| 226 | |||
| 227 | Please let me know if you know or see any other dependencies of CPU0. | ||
| 228 | |||
| 229 | If the dependencies are under your control, you can turn on CPU0 hotplug feature | ||
| 230 | either by CONFIG_BOOTPARAM_HOTPLUG_CPU0 or by kernel parameter cpu0_hotplug. | ||
| 231 | |||
| 232 | --Fenghua Yu <fenghua.yu@intel.com> | ||
| 233 | |||
| 210 | Q: How do i find out if a particular CPU is not removable? | 234 | Q: How do i find out if a particular CPU is not removable? |
| 211 | A: Depending on the implementation, some architectures may show this by the | 235 | A: Depending on the implementation, some architectures may show this by the |
| 212 | absence of the "online" file. This is done if it can be determined ahead of | 236 | absence of the "online" file. This is done if it can be determined ahead of |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 03d1251a915e..5190f1706414 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1984,6 +1984,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
| 1984 | 1984 | ||
| 1985 | nox2apic [X86-64,APIC] Do not enable x2APIC mode. | 1985 | nox2apic [X86-64,APIC] Do not enable x2APIC mode. |
| 1986 | 1986 | ||
| 1987 | cpu0_hotplug [X86] Turn on CPU0 hotplug feature when | ||
| 1988 | CONFIG_BOOTPARAM_HOTPLUG_CPU0 is off. | ||
| 1989 | Some features depend on CPU0. Known dependencies are: | ||
| 1990 | 1. Resume from suspend/hibernate depends on CPU0. | ||
| 1991 | Suspend/hibernate will fail if CPU0 is offline and you | ||
| 1992 | need to online CPU0 before suspend/hibernate. | ||
| 1993 | 2. PIC interrupts also depend on CPU0. CPU0 can't be | ||
| 1994 | removed if a PIC interrupt is detected. | ||
| 1995 | It's said poweroff/reboot may depend on CPU0 on some | ||
| 1996 | machines although I haven't seen such issues so far | ||
| 1997 | after CPU0 is offline on a few tested machines. | ||
| 1998 | If the dependencies are under your control, you can | ||
| 1999 | turn on cpu0_hotplug. | ||
| 2000 | |||
| 1987 | nptcg= [IA-64] Override max number of concurrent global TLB | 2001 | nptcg= [IA-64] Override max number of concurrent global TLB |
| 1988 | purges which is reported from either PAL_VM_SUMMARY or | 2002 | purges which is reported from either PAL_VM_SUMMARY or |
| 1989 | SAL PALO. | 2003 | SAL PALO. |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6c304438b503..2d643255c40d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
| @@ -1698,6 +1698,50 @@ config HOTPLUG_CPU | |||
| 1698 | automatically on SMP systems. ) | 1698 | automatically on SMP systems. ) |
| 1699 | Say N if you want to disable CPU hotplug. | 1699 | Say N if you want to disable CPU hotplug. |
| 1700 | 1700 | ||
| 1701 | config BOOTPARAM_HOTPLUG_CPU0 | ||
| 1702 | bool "Set default setting of cpu0_hotpluggable" | ||
| 1703 | default n | ||
| 1704 | depends on HOTPLUG_CPU && EXPERIMENTAL | ||
| 1705 | ---help--- | ||
| 1706 | Set whether default state of cpu0_hotpluggable is on or off. | ||
| 1707 | |||
| 1708 | Say Y here to enable CPU0 hotplug by default. If this switch | ||
| 1709 | is turned on, there is no need to give cpu0_hotplug kernel | ||
| 1710 | parameter and the CPU0 hotplug feature is enabled by default. | ||
| 1711 | |||
| 1712 | Please note: there are two known CPU0 dependencies if you want | ||
| 1713 | to enable the CPU0 hotplug feature either by this switch or by | ||
| 1714 | cpu0_hotplug kernel parameter. | ||
| 1715 | |||
| 1716 | First, resume from hibernate or suspend always starts from CPU0. | ||
| 1717 | So hibernate and suspend are prevented if CPU0 is offline. | ||
| 1718 | |||
| 1719 | Second dependency is PIC interrupts always go to CPU0. CPU0 can not | ||
| 1720 | offline if any interrupt can not migrate out of CPU0. There may | ||
| 1721 | be other CPU0 dependencies. | ||
| 1722 | |||
| 1723 | Please make sure the dependencies are under your control before | ||
| 1724 | you enable this feature. | ||
| 1725 | |||
| 1726 | Say N if you don't want to enable CPU0 hotplug feature by default. | ||
| 1727 | You still can enable the CPU0 hotplug feature at boot by kernel | ||
| 1728 | parameter cpu0_hotplug. | ||
| 1729 | |||
| 1730 | config DEBUG_HOTPLUG_CPU0 | ||
| 1731 | def_bool n | ||
| 1732 | prompt "Debug CPU0 hotplug" | ||
| 1733 | depends on HOTPLUG_CPU && EXPERIMENTAL | ||
| 1734 | ---help--- | ||
| 1735 | Enabling this option offlines CPU0 (if CPU0 can be offlined) as | ||
| 1736 | soon as possible and boots up userspace with CPU0 offlined. User | ||
| 1737 | can online CPU0 back after boot time. | ||
| 1738 | |||
| 1739 | To debug CPU0 hotplug, you need to enable CPU0 offline/online | ||
| 1740 | feature by either turning on CONFIG_BOOTPARAM_HOTPLUG_CPU0 during | ||
| 1741 | compilation or giving cpu0_hotplug kernel parameter at boot. | ||
| 1742 | |||
| 1743 | If unsure, say N. | ||
| 1744 | |||
| 1701 | config COMPAT_VDSO | 1745 | config COMPAT_VDSO |
| 1702 | def_bool y | 1746 | def_bool y |
| 1703 | prompt "Compat VDSO support" | 1747 | prompt "Compat VDSO support" |
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 4564c8e28a33..5f9a1243190e 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h | |||
| @@ -28,6 +28,10 @@ struct x86_cpu { | |||
| 28 | #ifdef CONFIG_HOTPLUG_CPU | 28 | #ifdef CONFIG_HOTPLUG_CPU |
| 29 | extern int arch_register_cpu(int num); | 29 | extern int arch_register_cpu(int num); |
| 30 | extern void arch_unregister_cpu(int); | 30 | extern void arch_unregister_cpu(int); |
| 31 | extern void __cpuinit start_cpu0(void); | ||
| 32 | #ifdef CONFIG_DEBUG_HOTPLUG_CPU0 | ||
| 33 | extern int _debug_hotplug_cpu(int cpu, int action); | ||
| 34 | #endif | ||
| 31 | #endif | 35 | #endif |
| 32 | 36 | ||
| 33 | DECLARE_PER_CPU(int, cpu_state); | 37 | DECLARE_PER_CPU(int, cpu_state); |
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h index 4f19a1526037..b073aaea747c 100644 --- a/arch/x86/include/asm/smp.h +++ b/arch/x86/include/asm/smp.h | |||
| @@ -166,6 +166,7 @@ void native_send_call_func_ipi(const struct cpumask *mask); | |||
| 166 | void native_send_call_func_single_ipi(int cpu); | 166 | void native_send_call_func_single_ipi(int cpu); |
| 167 | void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); | 167 | void x86_idle_thread_init(unsigned int cpu, struct task_struct *idle); |
| 168 | 168 | ||
| 169 | void smp_store_boot_cpu_info(void); | ||
| 169 | void smp_store_cpu_info(int id); | 170 | void smp_store_cpu_info(int id); |
| 170 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) | 171 | #define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu) |
| 171 | 172 | ||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 1817fa911024..f78fc2b4deb0 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
| @@ -2199,9 +2199,11 @@ static int ioapic_retrigger_irq(struct irq_data *data) | |||
| 2199 | { | 2199 | { |
| 2200 | struct irq_cfg *cfg = data->chip_data; | 2200 | struct irq_cfg *cfg = data->chip_data; |
| 2201 | unsigned long flags; | 2201 | unsigned long flags; |
| 2202 | int cpu; | ||
| 2202 | 2203 | ||
| 2203 | raw_spin_lock_irqsave(&vector_lock, flags); | 2204 | raw_spin_lock_irqsave(&vector_lock, flags); |
| 2204 | apic->send_IPI_mask(cpumask_of(cpumask_first(cfg->domain)), cfg->vector); | 2205 | cpu = cpumask_first_and(cfg->domain, cpu_online_mask); |
| 2206 | apic->send_IPI_mask(cpumask_of(cpu), cfg->vector); | ||
| 2205 | raw_spin_unlock_irqrestore(&vector_lock, flags); | 2207 | raw_spin_unlock_irqrestore(&vector_lock, flags); |
| 2206 | |||
