Commit b7af41a1 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar

perf/x86: Suppress duplicated abort LBR records

Haswell always give an extra LBR record after every TSX abort.
Suppress the extra record.

This only works when the abort is visible in the LBR
If the original abort has already left the 16 LBR entries
the extra entry will will stay.
Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1379688044-14173-7-git-send-email-andi@firstfloor.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 475eeab9
...@@ -445,6 +445,7 @@ struct x86_pmu { ...@@ -445,6 +445,7 @@ struct x86_pmu {
int lbr_nr; /* hardware stack size */ int lbr_nr; /* hardware stack size */
u64 lbr_sel_mask; /* LBR_SELECT valid bits */ u64 lbr_sel_mask; /* LBR_SELECT valid bits */
const int *lbr_sel_map; /* lbr_select mappings */ const int *lbr_sel_map; /* lbr_select mappings */
bool lbr_double_abort; /* duplicated lbr aborts */
/* /*
* Extra registers for events * Extra registers for events
......
...@@ -2519,6 +2519,7 @@ __init int intel_pmu_init(void) ...@@ -2519,6 +2519,7 @@ __init int intel_pmu_init(void)
x86_pmu.hw_config = hsw_hw_config; x86_pmu.hw_config = hsw_hw_config;
x86_pmu.get_event_constraints = hsw_get_event_constraints; x86_pmu.get_event_constraints = hsw_get_event_constraints;
x86_pmu.cpu_events = hsw_events_attrs; x86_pmu.cpu_events = hsw_events_attrs;
x86_pmu.lbr_double_abort = true;
pr_cont("Haswell events, "); pr_cont("Haswell events, ");
break; break;
......
...@@ -284,6 +284,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) ...@@ -284,6 +284,7 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
int lbr_format = x86_pmu.intel_cap.lbr_format; int lbr_format = x86_pmu.intel_cap.lbr_format;
u64 tos = intel_pmu_lbr_tos(); u64 tos = intel_pmu_lbr_tos();
int i; int i;
int out = 0;
for (i = 0; i < x86_pmu.lbr_nr; i++) { for (i = 0; i < x86_pmu.lbr_nr; i++) {
unsigned long lbr_idx = (tos - i) & mask; unsigned long lbr_idx = (tos - i) & mask;
...@@ -306,15 +307,27 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc) ...@@ -306,15 +307,27 @@ static void intel_pmu_lbr_read_64(struct cpu_hw_events *cpuc)
} }
from = (u64)((((s64)from) << skip) >> skip); from = (u64)((((s64)from) << skip) >> skip);
cpuc->lbr_entries[i].from = from; /*
cpuc->lbr_entries[i].to = to; * Some CPUs report duplicated abort records,
cpuc->lbr_entries[i].mispred = mis; * with the second entry not having an abort bit set.
cpuc->lbr_entries[i].predicted = pred; * Skip them here. This loop runs backwards,
cpuc->lbr_entries[i].in_tx = in_tx; * so we need to undo the previous record.
cpuc->lbr_entries[i].abort = abort; * If the abort just happened outside the window
cpuc->lbr_entries[i].reserved = 0; * the extra entry cannot be removed.
*/
if (abort && x86_pmu.lbr_double_abort && out > 0)
out--;
cpuc->lbr_entries[out].from = from;
cpuc->lbr_entries[out].to = to;
cpuc->lbr_entries[out].mispred = mis;
cpuc->lbr_entries[out].predicted = pred;
cpuc->lbr_entries[out].in_tx = in_tx;
cpuc->lbr_entries[out].abort = abort;
cpuc->lbr_entries[out].reserved = 0;
out++;
} }
cpuc->lbr_stack.nr = i; cpuc->lbr_stack.nr = out;
} }
void intel_pmu_lbr_read(void) void intel_pmu_lbr_read(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment