]> rtime.felk.cvut.cz Git - can-eth-gw-linux.git/blobdiff - arch/powerpc/kernel/smp.c
Merge tag 'kvm-3.8-1' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[can-eth-gw-linux.git] / arch / powerpc / kernel / smp.c
index 2b952b5386fd5eae72bcf6a7c8320d1768156277..e5b133ebd8a57820bb65ff0ad5243afb85fa8fdd 100644 (file)
@@ -427,6 +427,45 @@ int generic_check_cpu_restart(unsigned int cpu)
 {
        return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE;
 }
+
+static atomic_t secondary_inhibit_count;
+
+/*
+ * Don't allow secondary CPU threads to come online
+ */
+void inhibit_secondary_onlining(void)
+{
+       /*
+        * This makes secondary_inhibit_count stable during cpu
+        * online/offline operations.
+        */
+       get_online_cpus();
+
+       atomic_inc(&secondary_inhibit_count);
+       put_online_cpus();
+}
+EXPORT_SYMBOL_GPL(inhibit_secondary_onlining);
+
+/*
+ * Allow secondary CPU threads to come online again
+ */
+void uninhibit_secondary_onlining(void)
+{
+       get_online_cpus();
+       atomic_dec(&secondary_inhibit_count);
+       put_online_cpus();
+}
+EXPORT_SYMBOL_GPL(uninhibit_secondary_onlining);
+
+static int secondaries_inhibited(void)
+{
+       return atomic_read(&secondary_inhibit_count);
+}
+
+#else /* HOTPLUG_CPU */
+
+#define secondaries_inhibited()                0
+
 #endif
 
 static void cpu_idle_thread_init(unsigned int cpu, struct task_struct *idle)
@@ -445,6 +484,13 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *tidle)
 {
        int rc, c;
 
+       /*
+        * Don't allow secondary threads to come online if inhibited
+        */
+       if (threads_per_core > 1 && secondaries_inhibited() &&
+           cpu % threads_per_core != 0)
+               return -EBUSY;
+
        if (smp_ops == NULL ||
            (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
                return -EINVAL;