cpumask_t cpu_core_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_core_map);
 
+static DECLARE_COMPLETION(cpu_starting);
 static DECLARE_COMPLETION(cpu_running);
 
 /*
        cpumask_set_cpu(cpu, &cpu_coherent_mask);
        notify_cpu_starting(cpu);
 
+       /* Notify boot CPU that we're starting & ready to sync counters */
+       complete(&cpu_starting);
+
+       synchronise_count_slave(cpu);
+
+       /* The CPU is running and counters synchronised, now mark it online */
        set_cpu_online(cpu, true);
 
        set_cpu_sibling_map(cpu);
 
        calculate_cpu_foreign_map();
 
+       /*
+        * Notify boot CPU that we're up & online and it can safely return
+        * from __cpu_up
+        */
        complete(&cpu_running);
-       synchronise_count_slave(cpu);
 
        /*
         * irq will be enabled in ->smp_finish(), enabling it too early
        if (err)
                return err;
 
-       /*
-        * We must check for timeout here, as the CPU will not be marked
-        * online until the counters are synchronised.
-        */
-       if (!wait_for_completion_timeout(&cpu_running,
+       /* Wait for CPU to start and be ready to sync counters */
+       if (!wait_for_completion_timeout(&cpu_starting,
                                         msecs_to_jiffies(1000))) {
                pr_crit("CPU%u: failed to start\n", cpu);
                return -EIO;
        }
 
        synchronise_count_master(cpu);
+
+       /* Wait for CPU to finish startup & mark itself online before return */
+       wait_for_completion(&cpu_running);
        return 0;
 }