perf/x86/amd: Rework AMD PMU init code
authorPeter Zijlstra <peterz@infradead.org>
Tue, 21 May 2013 11:05:37 +0000 (13:05 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 28 May 2013 07:13:55 +0000 (09:13 +0200)
Josh reported that his QEMU is a bad hardware emulator and trips a
WARN in the AMD PMU init code. He requested the WARN be turned into a
pr_err() or similar.

While there, rework the code a little.

Reported-by: Josh Boyer <jwboyer@redhat.com>
Acked-by: Robert Richter <rric@kernel.org>
Acked-by: Jacob Shin <jacob.shin@amd.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20130521110537.GG26912@twins.programming.kicks-ass.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/kernel/cpu/perf_event_amd.c

index 7e28d9467bb491e61a51c827b1582f16cb2cc30a..4cbe03287b0892594f4c84fca58746f82e5acdbd 100644 (file)
@@ -648,48 +648,48 @@ static __initconst const struct x86_pmu amd_pmu = {
        .cpu_dead               = amd_pmu_cpu_dead,
 };
 
-static int setup_event_constraints(void)
+static int __init amd_core_pmu_init(void)
 {
-       if (boot_cpu_data.x86 == 0x15)
+       if (!cpu_has_perfctr_core)
+               return 0;
+
+       switch (boot_cpu_data.x86) {
+       case 0x15:
+               pr_cont("Fam15h ");
                x86_pmu.get_event_constraints = amd_get_event_constraints_f15h;
-       return 0;
-}
+               break;
 
-static int setup_perfctr_core(void)
-{
-       if (!cpu_has_perfctr_core) {
-               WARN(x86_pmu.get_event_constraints == amd_get_event_constraints_f15h,
-                    KERN_ERR "Odd, counter constraints enabled but no core perfctrs detected!");
+       default:
+               pr_err("core perfctr but no constraints; unknown hardware!\n");
                return -ENODEV;
        }
 
-       WARN(x86_pmu.get_event_constraints == amd_get_event_constraints,
-            KERN_ERR "hw perf events core counters need constraints handler!");
-
        /*
         * If core performance counter extensions exists, we must use
         * MSR_F15H_PERF_CTL/MSR_F15H_PERF_CTR msrs. See also
-        * x86_pmu_addr_offset().
+        * amd_pmu_addr_offset().
         */
        x86_pmu.eventsel        = MSR_F15H_PERF_CTL;
        x86_pmu.perfctr         = MSR_F15H_PERF_CTR;
        x86_pmu.num_counters    = AMD64_NUM_COUNTERS_CORE;
 
-       printk(KERN_INFO "perf: AMD core performance counters detected\n");
-
+       pr_cont("core perfctr, ");
        return 0;
 }
 
 __init int amd_pmu_init(void)
 {
+       int ret;
+
        /* Performance-monitoring supported from K7 and later: */
        if (boot_cpu_data.x86 < 6)
                return -ENODEV;
 
        x86_pmu = amd_pmu;
 
-       setup_event_constraints();
-       setup_perfctr_core();
+       ret = amd_core_pmu_init();
+       if (ret)
+               return ret;
 
        /* Events are common for all AMDs */
        memcpy(hw_cache_event_ids, amd_hw_cache_event_ids,