aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-05-23 05:08:15 -0400
committerIngo Molnar <mingo@elte.hu>2011-07-01 05:06:37 -0400
commitb79e8941fb9af07d810da91b4e29da2bba331b6e (patch)
tree8bb9c7ec132d185dc79f9a05274c1535d3634762
parentee89cbc2d48150c7c0e9f2aaac00afde99af098c (diff)
perf, intel: Try alternative OFFCORE encodings
Since the OFFCORE registers are fully symmetric, try the other one when the specified one is already in use. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1306141897.18455.8.camel@twins Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/cpu/perf_event.c5
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c44
2 files changed, 41 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 583f3113436d..c53d433c3dde 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -327,9 +327,12 @@ struct x86_pmu {
327 * Extra registers for events 327 * Extra registers for events
328 */ 328 */
329 struct extra_reg *extra_regs; 329 struct extra_reg *extra_regs;
330 bool regs_no_ht_sharing; 330 unsigned int er_flags;
331}; 331};
332 332
333#define ERF_NO_HT_SHARING 1
334#define ERF_HAS_RSP_1 2
335
333static struct x86_pmu x86_pmu __read_mostly; 336static struct x86_pmu x86_pmu __read_mostly;
334 337
335static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { 338static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index a674ae45a472..5c448622468c 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -1018,6 +1018,29 @@ intel_bts_constraints(struct perf_event *event)
1018 return NULL; 1018 return NULL;
1019} 1019}
1020 1020
1021static bool intel_try_alt_er(struct perf_event *event, int orig_idx)
1022{
1023 if (!(x86_pmu.er_flags & ERF_HAS_RSP_1))
1024 return false;
1025
1026 if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) {
1027 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
1028 event->hw.config |= 0x01bb;
1029 event->hw.extra_reg.idx = EXTRA_REG_RSP_1;
1030 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
1031 } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) {
1032 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
1033 event->hw.config |= 0x01b7;
1034 event->hw.extra_reg.idx = EXTRA_REG_RSP_0;
1035 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
1036 }
1037
1038 if (event->hw.extra_reg.idx == orig_idx)
1039 return false;
1040
1041 return true;
1042}
1043
1021/* 1044/*
1022 * manage allocation of shared extra msr for certain events 1045 * manage allocation of shared extra msr for certain events
1023 * 1046 *
@@ -1027,16 +1050,19 @@ intel_bts_constraints(struct perf_event *event)
1027 */ 1050 */
1028static struct event_constraint * 1051static struct event_constraint *
1029__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, 1052__intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
1030 struct hw_perf_event_extra *reg) 1053 struct perf_event *event)
1031{ 1054{
1032 struct event_constraint *c = &emptyconstraint; 1055 struct event_constraint *c = &emptyconstraint;
1056 struct hw_perf_event_extra *reg = &event->hw.extra_reg;
1033 struct er_account *era; 1057 struct er_account *era;
1034 unsigned long flags; 1058 unsigned long flags;
1059 int orig_idx = reg->idx;
1035 1060
1036 /* already allocated shared msr */ 1061 /* already allocated shared msr */
1037 if (reg->alloc) 1062 if (reg->alloc)
1038 return &unconstrained; 1063 return &unconstrained;
1039 1064
1065again:
1040 era = &cpuc->shared_regs->regs[reg->idx]; 1066 era = &cpuc->shared_regs->regs[reg->idx];
1041 /* 1067 /*
1042 * we use spin_lock_irqsave() to avoid lockdep issues when 1068 * we use spin_lock_irqsave() to avoid lockdep issues when
@@ -1065,6 +1091,9 @@ __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
1065 * the regular event constraint table. 1091 * the regular event constraint table.
1066 */ 1092 */
1067 c = &unconstrained; 1093 c = &unconstrained;
1094 } else if (intel_try_alt_er(event, orig_idx)) {
1095 raw_spin_unlock(&era->lock);
1096 goto again;
1068 } 1097 }
1069 raw_spin_unlock_irqrestore(&era->lock, flags); 1098 raw_spin_unlock_irqrestore(&era->lock, flags);
1070 1099
@@ -1099,11 +1128,10 @@ intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
1099 struct perf_event *event) 1128 struct perf_event *event)
1100{ 1129{
1101 struct event_constraint *c = NULL; 1130 struct event_constraint *c = NULL;
1102 struct hw_perf_event_extra *xreg;
1103 1131
1104 xreg = &event->hw.extra_reg; 1132 if (event->hw.extra_reg.idx != EXTRA_REG_NONE)
1105 if (xreg->idx != EXTRA_REG_NONE) 1133 c = __intel_shared_reg_get_constraints(cpuc, event);
1106 c = __intel_shared_reg_get_constraints(cpuc, xreg); 1134
1107 return c; 1135 return c;
1108} 1136}
1109 1137
@@ -1264,7 +1292,7 @@ static void intel_pmu_cpu_starting(int cpu)
1264 */ 1292 */
1265 intel_pmu_lbr_reset(); 1293 intel_pmu_lbr_reset();
1266 1294
1267 if (!cpuc->shared_regs || x86_pmu.regs_no_ht_sharing) 1295 if (!cpuc->shared_regs || (x86_pmu.er_flags & ERF_NO_HT_SHARING))
1268 return; 1296 return;
1269 1297
1270 for_each_cpu(i, topology_thread_cpumask(cpu)) { 1298 for_each_cpu(i, topology_thread_cpumask(cpu)) {
@@ -1489,6 +1517,7 @@ static __init int intel_pmu_init(void)
1489 x86_pmu.enable_all = intel_pmu_nhm_enable_all; 1517 x86_pmu.enable_all = intel_pmu_nhm_enable_all;
1490 x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints; 1518 x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
1491 x86_pmu.extra_regs = intel_westmere_extra_regs; 1519 x86_pmu.extra_regs = intel_westmere_extra_regs;
1520 x86_pmu.er_flags |= ERF_HAS_RSP_1;
1492 1521
1493 /* UOPS_ISSUED.STALLED_CYCLES */ 1522 /* UOPS_ISSUED.STALLED_CYCLES */
1494 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e; 1523 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
@@ -1508,7 +1537,8 @@ static __init int intel_pmu_init(void)
1508 x86_pmu.pebs_constraints = intel_snb_pebs_events; 1537 x86_pmu.pebs_constraints = intel_snb_pebs_events;
1509 x86_pmu.extra_regs = intel_snb_extra_regs; 1538 x86_pmu.extra_regs = intel_snb_extra_regs;
1510 /* all extra regs are per-cpu when HT is on */ 1539 /* all extra regs are per-cpu when HT is on */
1511 x86_pmu.regs_no_ht_sharing = true; 1540 x86_pmu.er_flags |= ERF_HAS_RSP_1;
1541 x86_pmu.er_flags |= ERF_NO_HT_SHARING;
1512 1542
1513 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ 1543 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
1514 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e; 1544 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;