From: Richard Weinberger <rich...@nod.at>

Signed-off-by: Richard Weinberger <rich...@nod.at>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/kernel/apic/x2apic_cluster.c |   80 ++++++++++++----------------------
 include/linux/cpuhotplug.h            |    1 
 2 files changed, 31 insertions(+), 50 deletions(-)

Index: linux-2.6/arch/x86/kernel/apic/x2apic_cluster.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/apic/x2apic_cluster.c
+++ linux-2.6/arch/x86/kernel/apic/x2apic_cluster.c
@@ -145,68 +145,48 @@ static void init_x2apic_ldr(void)
        }
 }
 
- /*
-  * At CPU state changes, update the x2apic cluster sibling info.
-  */
-static int __cpuinit
-update_clusterinfo(struct notifier_block *nfb, unsigned long action, void 
*hcpu)
+/*
+ * At CPU state changes, update the x2apic cluster sibling info.
+ */
+int __cpuinit x2apic_prepare_cpu(unsigned int cpu)
 {
-       unsigned int this_cpu = (unsigned long)hcpu;
-       unsigned int cpu;
-       int err = 0;
-
-       switch (action) {
-       case CPU_UP_PREPARE:
-               if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, this_cpu),
-                                       GFP_KERNEL)) {
-                       err = -ENOMEM;
-               } else if (!zalloc_cpumask_var(&per_cpu(ipi_mask, this_cpu),
-                                              GFP_KERNEL)) {
-                       free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
-                       err = -ENOMEM;
-               }
-               break;
-       case CPU_UP_CANCELED:
-       case CPU_UP_CANCELED_FROZEN:
-       case CPU_DEAD:
-               for_each_online_cpu(cpu) {
-                       if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
-                               continue;
-                       __cpu_clear(this_cpu, per_cpu(cpus_in_cluster, cpu));
-                       __cpu_clear(cpu, per_cpu(cpus_in_cluster, this_cpu));
-               }
-               free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
-               free_cpumask_var(per_cpu(ipi_mask, this_cpu));
-               break;
+       if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL))
+               return -ENOMEM;
+
+       if (!zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL)) {
+               free_cpumask_var(per_cpu(cpus_in_cluster, cpu));
+               return -ENOMEM;
        }
 
-       return notifier_from_errno(err);
+       return 0;
 }
 
-static struct notifier_block __refdata x2apic_cpu_notifier = {
-       .notifier_call = update_clusterinfo,
-};
-
-static int x2apic_init_cpu_notifier(void)
+int __cpuinit x2apic_dead_cpu(unsigned int this_cpu)
 {
-       int cpu = smp_processor_id();
-
-       zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL);
-       zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL);
+       int cpu;
 
-       BUG_ON(!per_cpu(cpus_in_cluster, cpu) || !per_cpu(ipi_mask, cpu));
-
-       __cpu_set(cpu, per_cpu(cpus_in_cluster, cpu));
-       register_hotcpu_notifier(&x2apic_cpu_notifier);
-       return 1;
+       for_each_online_cpu(cpu) {
+               if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
+                       continue;
+               __cpu_clear(this_cpu, per_cpu(cpus_in_cluster, cpu));
+               __cpu_clear(cpu, per_cpu(cpus_in_cluster, this_cpu));
+       }
+       free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
+       free_cpumask_var(per_cpu(ipi_mask, this_cpu));
+       return 0;
 }
 
 static int x2apic_cluster_probe(void)
 {
-       if (x2apic_mode)
-               return x2apic_init_cpu_notifier();
-       else
+       int cpu = smp_processor_id();
+
+       if (!x2apic_mode)
                return 0;
+
+       __cpu_set(cpu, per_cpu(cpus_in_cluster, cpu));
+       cpuhp_setup_state(CPUHP_X2APIC_PREPARE, x2apic_prepare_cpu,
+                         x2apic_dead_cpu);
+       return 1;
 }
 
 static const struct cpumask *x2apic_cluster_target_cpus(void)
Index: linux-2.6/include/linux/cpuhotplug.h
===================================================================
--- linux-2.6.orig/include/linux/cpuhotplug.h
+++ linux-2.6/include/linux/cpuhotplug.h
@@ -16,6 +16,7 @@ enum cpuhp_states {
        CPUHP_HRTIMERS_PREPARE,
        CPUHP_TIMERS_PREPARE,
        CPUHP_PROFILE_PREPARE,
+       CPUHP_X2APIC_PREPARE,
        CPUHP_NOTIFY_PREPARE,
        CPUHP_NOTIFY_DEAD,
        CPUHP_CLOCKEVENTS_DEAD,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to