Add CPU_STARTING notifier during CPU bringup.
authorKeir Fraser <keir@xen.org>
Thu, 9 Dec 2010 16:17:33 +0000 (16:17 +0000)
committerKeir Fraser <keir@xen.org>
Thu, 9 Dec 2010 16:17:33 +0000 (16:17 +0000)
Signed-off-by: Keir Fraser <keir@xen.org>
xen/arch/ia64/linux-xen/smpboot.c
xen/arch/x86/smpboot.c
xen/common/cpu.c
xen/include/xen/cpu.h

index 57454d8e7f4e86342d8d6b02b5afa5a918fc599b..ba352809448ce7ffae0df838d82057e540d61911 100644 (file)
@@ -387,6 +387,7 @@ smp_callin (void)
        fix_b0_for_bsp();
 
 #ifdef XEN
+       notify_cpu_starting(cpuid);
        lock_ipi_calllock(&flags);
 #else
        lock_ipi_calllock();
index 90b4bfb56cc7c7715fa87171c8ed37fd57d07921..7f5c63339c20111e6be98d41b5b48adf84ab0b0b 100644 (file)
@@ -357,7 +357,8 @@ void start_secondary(void *unused)
 
     /* This must be done before setting cpu_online_map */
     spin_debug_enable();
-    set_cpu_sibling_map(smp_processor_id());
+    set_cpu_sibling_map(cpu);
+    notify_cpu_starting(cpu);
     wmb();
 
     /*
@@ -366,8 +367,8 @@ void start_secondary(void *unused)
      * this lock ensures we don't half assign or remove an irq from a cpu.
      */
     lock_vector_lock();
-    __setup_vector_irq(smp_processor_id());
-    cpu_set(smp_processor_id(), cpu_online_map);
+    __setup_vector_irq(cpu);
+    cpu_set(cpu, cpu_online_map);
     unlock_vector_lock();
 
     init_percpu_time();
index b7bf377e009e5249a856377bf78607b0947348e0..2a248275a267f802cf926bf6c64e96b7dd00381c 100644 (file)
@@ -155,6 +155,14 @@ int cpu_up(unsigned int cpu)
     return err;
 }
 
+void notify_cpu_starting(unsigned int cpu)
+{
+    void *hcpu = (void *)(long)cpu;
+    int notifier_rc = notifier_call_chain(
+        &cpu_chain, CPU_STARTING, hcpu, NULL);
+    BUG_ON(notifier_rc != NOTIFY_DONE);
+}
+
 static cpumask_t frozen_cpus;
 
 int disable_nonboot_cpus(void)
index 78aa7773edcd4e5ee96b184db145b22c49d3605e..ffefc09f8e3b84b534055823ae3faa1aa0aaaed0 100644 (file)
@@ -18,10 +18,10 @@ void register_cpu_notifier(struct notifier_block *nb);
 
 /*
  * Possible event sequences for a given CPU:
- *  CPU_UP_PREPARE -> CPU_UP_CANCELLED        -- failed CPU up
- *  CPU_UP_PREPARE -> CPU_ONLINE              -- successful CPU up
- *  CPU_DOWN_PREPARE -> CPU_DOWN_FAILED       -- failed CPU down
- *  CPU_DOWN_PREPARE -> CPU_DYING -> CPU_DEAD -- successful CPU down
+ *  CPU_UP_PREPARE -> CPU_UP_CANCELLED           -- failed CPU up
+ *  CPU_UP_PREPARE -> CPU_STARTING -> CPU_ONLINE -- successful CPU up
+ *  CPU_DOWN_PREPARE -> CPU_DOWN_FAILED          -- failed CPU down
+ *  CPU_DOWN_PREPARE -> CPU_DYING -> CPU_DEAD    -- successful CPU down
  * 
  * Hence note that only CPU_*_PREPARE handlers are allowed to fail. Also note
  * that once CPU_DYING is delivered, an offline action can no longer fail.
@@ -31,10 +31,12 @@ void register_cpu_notifier(struct notifier_block *nb);
  * Notifiers are called lowest-priority-first when:
  *  (a) A CPU is going down; or (b) CPU_UP_CANCELED
  */
-/* CPU_UP_PREPARE: CPU is coming up */
-#define CPU_UP_PREPARE   (0x0002 | NOTIFY_FORWARD)
-/* CPU_UP_CANCELED: CPU is no longer coming up. */
-#define CPU_UP_CANCELED  (0x0003 | NOTIFY_REVERSE)
+/* CPU_UP_PREPARE: Preparing to bring CPU online. */
+#define CPU_UP_PREPARE   (0x0001 | NOTIFY_FORWARD)
+/* CPU_UP_CANCELED: CPU is no longer being brought online. */
+#define CPU_UP_CANCELED  (0x0002 | NOTIFY_REVERSE)
+/* CPU_STARTING: CPU nearly online. Runs on new CPU, irqs still disabled. */
+#define CPU_STARTING     (0x0003 | NOTIFY_FORWARD)
 /* CPU_ONLINE: CPU is up. */
 #define CPU_ONLINE       (0x0004 | NOTIFY_FORWARD)
 /* CPU_DOWN_PREPARE: CPU is going down. */
@@ -50,6 +52,9 @@ void register_cpu_notifier(struct notifier_block *nb);
 int cpu_down(unsigned int cpu);
 int cpu_up(unsigned int cpu);
 
+/* From arch code, send CPU_STARTING notification. */
+void notify_cpu_starting(unsigned int cpu);
+
 /* Power management. */
 int disable_nonboot_cpus(void);
 void enable_nonboot_cpus(void);