x86: fix wakeup_cpu with numaq/es7000, v2, fix
authorYinghai Lu <yinghai@kernel.org>
Mon, 17 Nov 2008 23:19:53 +0000 (15:19 -0800)
committerIngo Molnar <mingo@elte.hu>
Mon, 17 Nov 2008 23:27:24 +0000 (00:27 +0100)
Impact: fix wakeup_secondary_cpu with hotplug

We can not put that into x86_quirks, because that is __initdata.
So try to move that to genapic, and add update_genapic in x86_quirks.

later we even could use that stub to:

 1. autodetect CONFIG_ES7000_CLUSTERED_APIC
 2. more correct inquire_remote_apic with apic_verbosity setting.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/genapic_32.h
arch/x86/include/asm/genapic_64.h
arch/x86/include/asm/mach-default/mach_apic.h
arch/x86/include/asm/mach-generic/mach_apic.h
arch/x86/include/asm/setup.h
arch/x86/kernel/es7000_32.c
arch/x86/kernel/genapic_64.c
arch/x86/kernel/numaq_32.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/mach-generic/probe.c

index 39bd8c1db3f5fecf26ba2ace87822e531dcc045f..455d6c27a98b16d37d772b80b5d632b11931370b 100644 (file)
@@ -66,6 +66,7 @@ struct genapic {
        void (*send_IPI_allbutself)(int vector);
        void (*send_IPI_all)(int vector);
 #endif
+       int (*wakeup_cpu)(int apicid, unsigned long start_eip);
        int trampoline_phys_low;
        int trampoline_phys_high;
        void (*wait_for_init_deassert)(atomic_t *deassert);
index 13c4e96199ea17d1e52430dac24a85f4291f50d7..2cae011668b7e09a1397e09b7fc9241f63b48d1d 100644 (file)
@@ -32,6 +32,8 @@ struct genapic {
        unsigned int (*get_apic_id)(unsigned long x);
        unsigned long (*set_apic_id)(unsigned int id);
        unsigned long apic_id_mask;
+       /* wakeup_secondary_cpu */
+       int (*wakeup_cpu)(int apicid, unsigned long start_eip);
 };
 
 extern struct genapic *genapic;
index ff3a6c236c00c940d3cbc94d0895399fd25828f8..6cb3a467e0673c031c6e39b675481466a0c7531a 100644 (file)
@@ -32,11 +32,13 @@ static inline cpumask_t target_cpus(void)
 #define vector_allocation_domain    (genapic->vector_allocation_domain)
 #define read_apic_id()  (GET_APIC_ID(apic_read(APIC_ID)))
 #define send_IPI_self (genapic->send_IPI_self)
+#define wakeup_secondary_cpu (genapic->wakeup_cpu)
 extern void setup_apic_routing(void);
 #else
 #define INT_DELIVERY_MODE dest_LowestPrio
 #define INT_DEST_MODE 1     /* logical delivery broadcast to all procs */
 #define TARGET_CPUS (target_cpus())
+#define wakeup_secondary_cpu wakeup_secondary_cpu_via_init
 /*
  * Set up the logical destination ID.
  *
index 5180bd7478fbc3d2cfc533f22e707a8099201e23..e430f47df667255e26bab25ecb123702426b6e63 100644 (file)
@@ -27,6 +27,7 @@
 #define vector_allocation_domain (genapic->vector_allocation_domain)
 #define enable_apic_mode (genapic->enable_apic_mode)
 #define phys_pkg_id (genapic->phys_pkg_id)
+#define wakeup_secondary_cpu (genapic->wakeup_cpu)
 
 extern void generic_bigsmp_probe(void);
 
index 40b2d330491150555b4751eb56fb84b2f2ba6fdc..294daeb3a006dbbe9eab0a659ac3708d802011fb 100644 (file)
@@ -17,6 +17,7 @@ static inline int is_visws_box(void) { return 0; }
 #endif
 
 extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
+extern int wakeup_secondary_cpu_via_init(int apicid, unsigned long start_eip);
 /*
  * Any setup quirks to be performed?
  */
@@ -40,7 +41,7 @@ struct x86_quirks {
        void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable,
                                     unsigned short oemsize);
        int (*setup_ioapic_ids)(void);
-       int (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
+       int (*update_genapic)(void);
 };
 
 extern struct x86_quirks *x86_quirks;
index bed10dddf099a8e2a670f8c8a899cf2f6b979119..fb3bfe66fbe291b98aeb6f2032afd3a83cbbccbb 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/smp.h>
 #include <asm/apicdef.h>
 #include <mach_mpparse.h>
+#include <asm/genapic.h>
 #include <asm/setup.h>
 
 /*
@@ -180,6 +181,13 @@ static int wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
 
        return 0;
 }
+
+static int __init es7000_update_genapic(void)
+{
+       genapic->wakeup_cpu = wakeup_secondary_cpu_via_mip;
+
+       return 0;
+}
 #endif
 
 void __init
@@ -197,8 +205,9 @@ setup_unisys(void)
        else
                es7000_plat = ES7000_CLASSIC;
        ioapic_renumber_irq = es7000_rename_gsi;
+
 #ifdef CONFIG_ES7000_CLUSTERED_APIC
-       x86_quirks->wakeup_secondary_cpu = wakeup_secondary_cpu_via_mip;
+       x86_quirks->update_genapic = es7000_update_genapic;
 #endif
 }
 
index 6c9bfc9e1e95cbc5f8aa2273bd06f9eb75c2ca11..2bced78b0b8e85d6317c729c9554919cac2eb67b 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/smp.h>
 #include <asm/ipi.h>
 #include <asm/genapic.h>
+#include <asm/setup.h>
 
 extern struct genapic apic_flat;
 extern struct genapic apic_physflat;
@@ -53,6 +54,9 @@ void __init setup_apic_routing(void)
                        genapic = &apic_physflat;
                printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
        }
+
+       if (x86_quirks->update_genapic)
+               x86_quirks->update_genapic();
 }
 
 /* Same for both flat and physical. */
index 745891b7d0fb93fc35c22e31605a86cd79e1d445..0deea37a53cf5613477a17d304a03f8bf254325f 100644 (file)
@@ -31,7 +31,7 @@
 #include <asm/numaq.h>
 #include <asm/topology.h>
 #include <asm/processor.h>
-#include <asm/mpspec.h>
+#include <asm/genapic.h>
 #include <asm/e820.h>
 #include <asm/setup.h>
 
@@ -235,6 +235,13 @@ static int __init numaq_setup_ioapic_ids(void)
        return 1;
 }
 
+static int __init numaq_update_genapic(void)
+{
+       genapic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
+
+       return 0;
+}
+
 static struct x86_quirks numaq_x86_quirks __initdata = {
        .arch_pre_time_init     = numaq_pre_time_init,
        .arch_time_init         = NULL,
@@ -250,7 +257,7 @@ static struct x86_quirks numaq_x86_quirks __initdata = {
        .mpc_oem_pci_bus        = mpc_oem_pci_bus,
        .smp_read_mpc_oem       = smp_read_mpc_oem,
        .setup_ioapic_ids       = numaq_setup_ioapic_ids,
-       .wakeup_secondary_cpu   = wakeup_secondary_cpu_via_nmi,
+       .update_genapic         = numaq_update_genapic,
 };
 
 void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
index 0fa6790c1dd37d76e257de661ba3ed9312de89e0..c366e891e10b3db252daa9aa284267d0d0d779eb 100644 (file)
@@ -583,7 +583,18 @@ static int __init setup_elfcorehdr(char *arg)
 early_param("elfcorehdr", setup_elfcorehdr);
 #endif
 
-static struct x86_quirks default_x86_quirks __initdata;
+static int __init default_update_genapic(void)
+{
+#if defined(CONFIG_X86_GENERICARCH) || defined(CONFIG_X86_64)
+       genapic->wakeup_cpu = wakeup_secondary_cpu_via_nmi;
+#endif
+
+       return 0;
+}
+
+static struct x86_quirks default_x86_quirks __initdata = {
+       .update_genapic         = default_update_genapic,
+};
 
 struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
 
index 498c1ef37fe0e26988a31ac65ca63a3b8507b4ae..0e9f446269f41bc2334f1a826ee365a98c6cecd9 100644 (file)
@@ -615,7 +615,7 @@ wakeup_secondary_cpu_via_nmi(int logical_apicid, unsigned long start_eip)
        return (send_status | accept_status);
 }
 
-static int __devinit
+int __devinit
 wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
 {
        unsigned long send_status, accept_status = 0;
@@ -736,15 +736,6 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
        return (send_status | accept_status);
 }
 
-static int __devinit
-wakeup_secondary_cpu(int apicid, unsigned long start_eip)
-{
-       if (x86_quirks->wakeup_secondary_cpu)
-               return x86_quirks->wakeup_secondary_cpu(apicid, start_eip);
-
-       return wakeup_secondary_cpu_via_init(apicid, start_eip);
-}
-
 struct create_idle {
        struct work_struct work;
        struct task_struct *idle;
index 5a7e4619e1c47589fc6745d5843c7ef743170318..90b134f3cd742123eeaba7e3251118968ce1d467 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/mpspec.h>
 #include <asm/apicdef.h>
 #include <asm/genapic.h>
+#include <asm/setup.h>
 
 extern struct genapic apic_numaq;
 extern struct genapic apic_summit;
@@ -57,6 +58,9 @@ static int __init parse_apic(char *arg)
                }
        }
 
+       if (x86_quirks->update_genapic)
+               x86_quirks->update_genapic();
+
        /* Parsed again by __setup for debug/verbose */
        return 0;
 }