|
@@ -30,23 +30,59 @@
|
|
|
#include <linux/mmzone.h>
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/smp.h>
|
|
|
+#include <linux/irq.h>
|
|
|
#include <asm/cpu.h>
|
|
|
|
|
|
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
|
|
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
|
+
|
|
|
+#ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0
|
|
|
+static int cpu0_hotpluggable = 1;
|
|
|
+#else
|
|
|
+static int cpu0_hotpluggable;
|
|
|
+static int __init enable_cpu0_hotplug(char *str)
|
|
|
+{
|
|
|
+ cpu0_hotpluggable = 1;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+__setup("cpu0_hotplug", enable_cpu0_hotplug);
|
|
|
+#endif
|
|
|
+
|
|
|
int __ref arch_register_cpu(int num)
|
|
|
{
|
|
|
+ struct cpuinfo_x86 *c = &cpu_data(num);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Currently CPU0 is only hotpluggable on Intel platforms. Other
|
|
|
+ * vendors can add hotplug support later.
|
|
|
+ */
|
|
|
+ if (c->x86_vendor != X86_VENDOR_INTEL)
|
|
|
+ cpu0_hotpluggable = 0;
|
|
|
+
|
|
|
/*
|
|
|
- * CPU0 cannot be offlined due to several
|
|
|
- * restrictions and assumptions in kernel. This basically
|
|
|
- * doesn't add a control file, one cannot attempt to offline
|
|
|
- * BSP.
|
|
|
+ * Two known BSP/CPU0 dependencies: Resume from suspend/hibernate
|
|
|
+ * depends on BSP. PIC interrupts depend on BSP.
|
|
|
*
|
|
|
- * Also certain PCI quirks require not to enable hotplug control
|
|
|
- * for all CPU's.
|
|
|
+ * If the BSP depencies are under control, one can tell kernel to
|
|
|
+ * enable BSP hotplug. This basically adds a control file and
|
|
|
+ * one can attempt to offline BSP.
|
|
|
*/
|
|
|
- if (num)
|
|
|
+ if (num == 0 && cpu0_hotpluggable) {
|
|
|
+ unsigned int irq;
|
|
|
+ /*
|
|
|
+ * We won't take down the boot processor on i386 if some
|
|
|
+ * interrupts only are able to be serviced by the BSP in PIC.
|
|
|
+ */
|
|
|
+ for_each_active_irq(irq) {
|
|
|
+ if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) {
|
|
|
+ cpu0_hotpluggable = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (num || cpu0_hotpluggable)
|
|
|
per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
|
|
|
|
|
|
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
|