Install the callbacks via the state machine and let the core invoke
the callbacks on the already online cpus.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/kernel/cpu/perf_event_amd_ibs.c |   54 +++++++++++--------------------
 include/linux/cpuhotplug.h               |    1 
 2 files changed, 21 insertions(+), 34 deletions(-)

Index: linux-2.6/arch/x86/kernel/cpu/perf_event_amd_ibs.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ linux-2.6/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -637,13 +637,10 @@ static __init int perf_ibs_pmu_init(stru
        return ret;
 }
 
-static __init int perf_event_ibs_init(void)
+static __init void perf_event_ibs_init(void)
 {
        struct attribute **attr = ibs_op_format_attrs;
 
-       if (!ibs_caps)
-               return -ENODEV; /* ibs not supported by the cpu */
-
        perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
 
        if (ibs_caps & IBS_CAPS_OPCNT) {
@@ -654,13 +651,11 @@ static __init int perf_event_ibs_init(vo
 
        register_nmi_handler(NMI_LOCAL, perf_ibs_nmi_handler, 0, "perf_ibs");
        printk(KERN_INFO "perf: AMD IBS detected (0x%08x)\n", ibs_caps);
-
-       return 0;
 }
 
 #else /* defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) */
 
-static __init int perf_event_ibs_init(void) { return 0; }
+static __init void perf_event_ibs_init(void) { }
 
 #endif
 
@@ -827,11 +822,10 @@ static inline int get_ibs_lvt_offset(voi
        return val & IBSCTL_LVT_OFFSET_MASK;
 }
 
-static void setup_APIC_ibs(void *dummy)
+static void setup_APIC_ibs(void)
 {
-       int offset;
+       int offset = get_ibs_lvt_offset();
 
-       offset = get_ibs_lvt_offset();
        if (offset < 0)
                goto failed;
 
@@ -842,30 +836,19 @@ failed:
                smp_processor_id());
 }
 
-static void clear_APIC_ibs(void *dummy)
+static int __cpuinit x86_pmu_amd_ibs_starting_cpu(unsigned int cpu)
 {
-       int offset;
-
-       offset = get_ibs_lvt_offset();
-       if (offset >= 0)
-               setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+       setup_APIC_ibs();
+       return 0;
 }
 
-static int __cpuinit
-perf_ibs_cpu_notifier(struct notifier_block *self, unsigned long action, void 
*hcpu)
+static int __cpuinit x86_pmu_amd_ibs_dying_cpu(unsigned int cpu)
 {
-       switch (action & ~CPU_TASKS_FROZEN) {
-       case CPU_STARTING:
-               setup_APIC_ibs(NULL);
-               break;
-       case CPU_DYING:
-               clear_APIC_ibs(NULL);
-               break;
-       default:
-               break;
-       }
+       int offset = get_ibs_lvt_offset();
 
-       return NOTIFY_OK;
+       if (offset >= 0)
+               setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_FIX, 1);
+       return 0;
 }
 
 static __init int amd_ibs_init(void)
@@ -889,15 +872,18 @@ static __init int amd_ibs_init(void)
        if (!ibs_eilvt_valid())
                goto out;
 
-       get_online_cpus();
        ibs_caps = caps;
        /* make ibs_caps visible to other cpus: */
        smp_mb();
-       perf_cpu_notifier(perf_ibs_cpu_notifier);
-       smp_call_function(setup_APIC_ibs, NULL, 1);
-       put_online_cpus();
+       /*
+        * x86_pmu_amd_ibs_starting_cpu will be called from core on
+        * all online cpus.
+        */
+       cpuhp_setup_state(CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
+                         x86_pmu_amd_ibs_starting_cpu,
+                         x86_pmu_amd_ibs_dying_cpu);
 
-       ret = perf_event_ibs_init();
+       perf_event_ibs_init();
 out:
        if (ret)
                pr_err("Failed to setup IBS, %d\n", ret);
Index: linux-2.6/include/linux/cpuhotplug.h
===================================================================
--- linux-2.6.orig/include/linux/cpuhotplug.h
+++ linux-2.6/include/linux/cpuhotplug.h
@@ -14,6 +14,7 @@ enum cpuhp_states {
        CPUHP_AP_OFFLINE,
        CPUHP_AP_SCHED_STARTING,
        CPUHP_AP_PERF_X86_UNCORE_STARTING,
+       CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
        CPUHP_AP_PERF_X86_STARTING,
        CPUHP_AP_NOTIFY_STARTING,
        CPUHP_AP_NOTIFY_DYING,


--
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