]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/events/intel/core.c
Merge branches 'for-4.10/upstream-fixes', 'for-4.11/intel-ish', 'for-4.11/mayflash...
[karo-tx-linux.git] / arch / x86 / events / intel / core.c
index cb8522290e6a3f6dc3b5baacfc618d0ee8db65e3..eb1484c86bb4b4611450c49df01aab1a18d8fa5f 100644 (file)
@@ -2110,6 +2110,27 @@ again:
                    GLOBAL_STATUS_LBRS_FROZEN);
        if (!status)
                goto done;
+       /*
+        * In case multiple PEBS events are sampled at the same time,
+        * it is possible to have GLOBAL_STATUS bit 62 set indicating
+        * PEBS buffer overflow and also seeing at most 3 PEBS counters
+        * having their bits set in the status register. This is a sign
+        * that there was at least one PEBS record pending at the time
+        * of the PMU interrupt. PEBS counters must only be processed
+        * via the drain_pebs() calls and not via the regular sample
+        * processing loop coming after that the function, otherwise
+        * phony regular samples may be generated in the sampling buffer
+        * not marked with the EXACT tag. Another possibility is to have
+        * one PEBS event and at least one non-PEBS event whic hoverflows
+        * while PEBS has armed. In this case, bit 62 of GLOBAL_STATUS will
+        * not be set, yet the overflow status bit for the PEBS counter will
+        * be on Skylake.
+        *
+        * To avoid this problem, we systematically ignore the PEBS-enabled
+        * counters from the GLOBAL_STATUS mask and we always process PEBS
+        * events via drain_pebs().
+        */
+       status &= ~cpuc->pebs_enabled;
 
        /*
         * PEBS overflow sets bit 62 in the global status register
@@ -2117,15 +2138,6 @@ again:
        if (__test_and_clear_bit(62, (unsigned long *)&status)) {
                handled++;
                x86_pmu.drain_pebs(regs);
-               /*
-                * There are cases where, even though, the PEBS ovfl bit is set
-                * in GLOBAL_OVF_STATUS, the PEBS events may also have their
-                * overflow bits set for their counters. We must clear them
-                * here because they have been processed as exact samples in
-                * the drain_pebs() routine. They must not be processed again
-                * in the for_each_bit_set() loop for regular samples below.
-                */
-               status &= ~cpuc->pebs_enabled;
                status &= x86_pmu.intel_ctrl | GLOBAL_STATUS_TRACE_TOPAPMI;
        }
 
@@ -3164,13 +3176,16 @@ static void intel_pmu_cpu_starting(int cpu)
 
        if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) {
                for_each_cpu(i, topology_sibling_cpumask(cpu)) {
+                       struct cpu_hw_events *sibling;
                        struct intel_excl_cntrs *c;
 
-                       c = per_cpu(cpu_hw_events, i).excl_cntrs;
+                       sibling = &per_cpu(cpu_hw_events, i);
+                       c = sibling->excl_cntrs;
                        if (c && c->core_id == core_id) {
                                cpuc->kfree_on_online[1] = cpuc->excl_cntrs;
                                cpuc->excl_cntrs = c;
-                               cpuc->excl_thread_id = 1;
+                               if (!sibling->excl_thread_id)
+                                       cpuc->excl_thread_id = 1;
                                break;
                        }
                }
@@ -3975,7 +3990,7 @@ __init int intel_pmu_init(void)
                     x86_pmu.num_counters, INTEL_PMC_MAX_GENERIC);
                x86_pmu.num_counters = INTEL_PMC_MAX_GENERIC;
        }
-       x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+       x86_pmu.intel_ctrl = (1ULL << x86_pmu.num_counters) - 1;
 
        if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED) {
                WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",