perf: x86, add SandyBridge support
Subsystems (2)
PATCH v2 1/1 perf: x86, add SandyBridge support
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
All PEBS events are tested on my SandyBridge machine and work well. Note that SandyBridge does not support INSTR_RETIRED.ANY(0x00c0) PEBS event, instead it supports INST_RETIRED.PRECDIST(0x01c0) event and PMC1 only.
v1 -> v2:
- add more raw and PEBS events constraints
- use offcore events for LLC-* cache events
- remove the call to Nehalem workaround enable_all function
todo:
- precise store
- precise distribution of instructions retired
--- arch/x86/kernel/cpu/perf_event.c | 2 + arch/x86/kernel/cpu/perf_event_intel.c | 123 +++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_ds.c | 44 ++++++++++- 3 files changed, 168 insertions(+), 1 deletions(-)
arch/x86/kernel/cpu/perf_event.c +2 -0
@@ -148,6 +148,8 @@ struct cpu_hw_events {*/ #define INTEL_EVENT_CONSTRAINT (c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)/* * Constraint on the Event code + UMask + fixed-mask
arch/x86/kernel/cpu/perf_event_intel.c +123 -0
141 lines not on this page · raw message
arch/x86/kernel/cpu/perf_event_intel_ds.c +43 -1
56 lines not on this page · raw message
Quoted 215 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
All PEBS events are tested on my SandyBridge machine and work well. Note that SandyBridge does not support
INSTR_RETIRED.ANY(0x00c0)PEBS event, instead it supportsINST_RETIRED.PRECDIST(0x01c0)event and PMC1 only.v1 -> v2:
- add more raw and PEBS events constraints
- use offcore events for LLC-* cache events
- remove the call to Nehalem workaroundenable_allfunctiontodo:
- precise store
- precise distribution of instructions retiredSigned-off-by Lin Ming <[email protected]>---
arch/x86/kernel/cpu/perf_event.c | 2 +arch/x86/kernel/cpu/perf_event_intel.c| 123 +++++++++++++++++++++++++++++arch/x86/kernel/cpu/perf_event_intel_ds.c| 44 ++++++++++-3 files changed, 168 insertions(+), 1 deletions(-)arch/x86/kernel/cpu/perf_event.c +2
-0@@ -148,6 +148,8 @@ struct cpu_hw_events {*/ #define INTEL_EVENT_CONSTRAINT(c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) /** Constraint on the Event code + UMask + fixed-mask arch/x86/kernel/cpu/perf_event_intel.c +0
-0@@ -76,6 +76,19 @@ static struct event_constraint intel_westmere_event_constraints[] =EVENT_CONSTRAINT_END
};arch/x86/kernel/cpu/perf_event_intel.c +13
-0+static struct event_constraint intel_snb_event_constraints[] = +{ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ + INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ + INTEL_EVENT_CONSTRAINT(0xb7, 0x1), /* OFF_CORE_RESPONSE_0 */ + INTEL_EVENT_CONSTRAINT(0xbb, 0x8), /* OFF_CORE_RESPONSE_1 */ + INTEL_EVENT_CONSTRAINT2(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ + INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ + EVENT_CONSTRAINT_END +}; +static struct
event_constraintintel_gen_event_constraints[] = {
FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */arch/x86/kernel/cpu/perf_event_intel.c +100
-0@@ -89,6 +102,106 @@ static u64 intel_pmu_event_map(int hw_event) return intel_perfmon_event_map[hw_event]; } +static __initconst const u64 snb_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = +{ + [C (L1D ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */ + [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */ + }, + }, + [C (L1I ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [ C(LL ) ] = { + /* + * TBD: Need Off-core Response Performance Monitoring support + */ + [ C(OP_READ) ] = { + /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + [ C(OP_WRITE) ] = { + /* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + [ C(OP_PREFETCH) ] = { + /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + }, + [C (DTLB ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x01d0, /* MEM_UOP_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x02d0, /* MEM_UOP_RETIRED.STORES */ + [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [C (ITLB ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */ + [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, + [C (BPU ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ + [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, +}; +static
__initconstconst u64westmere_hw_cache_event_ids[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX]arch/x86/kernel/cpu/perf_event_intel.c +10
-0@@ -1062,6 +1175,16 @@ static __init int intel_pmu_init(void) pr_cont("Westmere events, "); break; + case 42: /* SandyBridge */ + memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); + + intel_pmu_lbr_init_nhm(); + + x86_pmu.event_constraints = intel_snb_event_constraints; + pr_cont("SandyBridge events, "); + break; +default:
/*
* default constraints for v2 and uparch/x86/kernel/cpu/perf_event_intel_ds.c +0
-0@@ -388,6 +388,42 @@ static struct event_constraint intel_nehalem_pebs_events[] = {EVENT_CONSTRAINT_END
};+static struct
event_constraintintel_snb_pebs_events[] = {
+PEBS_EVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+PEBS_EVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+PEBS_EVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+PEBS_EVENT_CONSTRAINT(0x01c4, 0xf), /* BR_INST_RETIRED.CONDITIONAL */
+PEBS_EVENT_CONSTRAINT(0x02c4, 0xf), /* BR_INST_RETIRED.NEAR_CALL */
+PEBS_EVENT_CONSTRAINT(0x04c4, 0xf), /* BR_INST_RETIRED.ALL_BRANCHES */
+PEBS_EVENT_CONSTRAINT(0x08c4, 0xf), /* BR_INST_RETIRED.NEAR_RETURN */
+PEBS_EVENT_CONSTRAINT(0x10c4, 0xf), /* BR_INST_RETIRED.NOT_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x20c4, 0xf), /* BR_INST_RETIRED.NEAR_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x40c4, 0xf), /* BR_INST_RETIRED.FAR_BRANCH */
+PEBS_EVENT_CONSTRAINT(0x01c5, 0xf), /* BR_MISP_RETIRED.CONDITIONAL */
+PEBS_EVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
+PEBS_EVENT_CONSTRAINT(0x04c5, 0xf), /* BR_MISP_RETIRED.ALL_BRANCHES */
+PEBS_EVENT_CONSTRAINT(0x10c5, 0xf), /* BR_MISP_RETIRED.NOT_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x20c5, 0xf), /* BR_MISP_RETIRED.TAKEN */
+PEBS_EVENT_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+PEBS_EVENT_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORE */
Quoted 6 lines
+
PEBS_EVENT_CONSTRAINT(0x01d0, 0xf), /* MEM_UOP_RETIRED.LOADS */
+PEBS_EVENT_CONSTRAINT(0x02d0, 0xf), /* MEM_UOP_RETIRED.STORES */
+PEBS_EVENT_CONSTRAINT(0x10d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS */
+PEBS_EVENT_CONSTRAINT(0x20d0, 0xf), /* MEM_UOP_RETIRED.LOCK */
+PEBS_EVENT_CONSTRAINT(0x40d0, 0xf), /* MEM_UOP_RETIRED.SPLIT */
+PEBS_EVENT_CONSTRAINT(0x80d0, 0xf), /* MEM_UOP_RETIRED.ALL */
Not quite. For event 0xd0, you are not listing the right umask combinations. The following combinations are supported for event 0xd0:
0x5381d0 snb::MEM_UOP_RETIRED:ANY_LOADS0x5382d0 snb::MEM_UOP_RETIRED:ANY_STORES0x5321d0 snb::MEM_UOP_RETIRED:LOCK_LOADS0x5322d0 snb::MEM_UOP_RETIRED:LOCK_STORES0x5341d0 snb::MEM_UOP_RETIRED:SPLIT_LOADS0x5342d0 snb::MEM_UOP_RETIRED:SPLIT_STORES0x5311d0 snb::MEM_UOP_RETIRED:STLB_MISS_LOADS0x5312d0 snb::MEM_UOP_RETIRED:STLB_MISS_STORES
In other words, bit 0-3 of the umask cannot be zero.
Quoted 235 lines · Stephane Eranian
Quoted 211 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
All PEBS events are tested on my SandyBridge machine and work well. Note that SandyBridge does not support
INSTR_RETIRED.ANY(0x00c0)PEBS event, instead it supportsINST_RETIRED.PRECDIST(0x01c0)event and PMC1 only.v1 -> v2:
- add more raw and PEBS events constraints
- use offcore events for LLC-* cache events
- remove the call to Nehalem workaroundenable_allfunctiontodo:
- precise store
- precise distribution of instructions retiredSigned-off-by Lin Ming <[email protected]>--- arch/x86/kernel/cpu/perf_event.c | 2 + arch/x86/kernel/cpu/perf_event_intel.c | 123 +++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_ds.c | 44 ++++++++++- 3 files changed, 168 insertions(+), 1 deletions(-)arch/x86/kernel/cpu/perf_event.c +2
-0@@ -148,6 +148,8 @@ struct cpu_hw_events {*/ #define INTEL_EVENT_CONSTRAINT (c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)/* * Constraint on the Event code + UMask + fixed-mask arch/x86/kernel/cpu/perf_event_intel.c +123
-0@@ -76,6 +76,19 @@ static struct event_constraint intel_westmere_event_constraints[] =EVENT_CONSTRAINT_END }; +static struct event_constraint intel_snb_event_constraints[] = +{ +FIXED_EVENT_CONSTRAINT (0x00c0 ,0 ),/* INST_RETIRED.ANY */ +FIXED_EVENT_CONSTRAINT (0x003c ,1 ),/* CPU_CLK_UNHALTED.CORE */ +/* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ +INTEL_EVENT_CONSTRAINT (0x48 ,0x4 ),/* L1D_PEND_MISS.PENDING */ +INTEL_EVENT_CONSTRAINT (0xb7 ,0x1 ),/* OFF_CORE_RESPONSE_0 */ +INTEL_EVENT_CONSTRAINT (0xbb ,0x8 ),/* OFF_CORE_RESPONSE_1 */ +INTEL_EVENT_CONSTRAINT2 (0x01c0 ,0x2 ),/* INST_RETIRED.PREC_DIST */ +INTEL_EVENT_CONSTRAINT (0xcd ,0x8 ),/* MEM_TRANS_RETIRED.LOAD_LATENCY */ +EVENT_CONSTRAINT_END +}; +static struct event_constraint intel_gen_event_constraints[] = {FIXED_EVENT_CONSTRAINT (0x00c0 ,0 ),/* INST_RETIRED.ANY */ @@ -89,6 +102,106 @@ static u64 intel_pmu_event_map(int hw_event)return intel_perfmon_event_map[hw_event]; } +static __initconst const u64 snb_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX ] + [PERF_COUNT_HW_CACHE_OP_MAX ] + [PERF_COUNT_HW_CACHE_RESULT_MAX ] = +{ + [C (L1D ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0xf1d0 ,/* MEM_UOP_RETIRED.LOADS */ + [C (RESULT_MISS ) ] =0x0151 ,/* L1D.REPLACEMENT */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =0xf2d0 ,/* MEM_UOP_RETIRED.STORES */ + [C (RESULT_MISS ) ] =0x0851 ,/* L1D.ALL_M_REPLACEMENT */ + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x024e ,/* HW_PRE_REQ.DL1_MISS */ + }, + }, + [C (L1I ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0280 ,/* ICACHE.MISSES */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0 , + }, + }, + [C (LL ) ] = { +/* +* TBD: Need Off-core Response Performance Monitoring support +*/ + [C (OP_READ ) ] = { +/* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + [C (OP_WRITE ) ] = { +/* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + [C (OP_PREFETCH ) ] = { +/* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + }, + [C (DTLB ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x01d0 ,/* MEM_UOP_RETIRED.LOADS */ + [C (RESULT_MISS ) ] =0x0108 ,/* DTLB_LOAD_MISSES.CAUSES_A_WALK */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =0x02d0 ,/* MEM_UOP_RETIRED.STORES */ + [C (RESULT_MISS ) ] =0x0149 ,/* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0 , + }, + }, + [C (ITLB ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x1085 ,/* ITLB_MISSES.STLB_HIT */ + [C (RESULT_MISS ) ] =0x0185 ,/* ITLB_MISSES.CAUSES_A_WALK */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + }, + [C (BPU ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x00c4 ,/* BR_INST_RETIRED.ALL_BRANCHES */ + [C (RESULT_MISS ) ] =0x00c5 ,/* BR_MISP_RETIRED.ALL_BRANCHES */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + }, +}; +static __initconst const u64 westmere_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ]@@ -1062,6 +1175,16 @@ static __init int intel_pmu_init(void)pr_cont ("Westmere events, " );break ; +case 42 :/* SandyBridge */ +memcpy (hw_cache_event_ids, snb_hw_cache_event_ids, +sizeof (hw_cache_event_ids)); + +intel_pmu_lbr_init_nhm (); + + x86_pmu.event_constraints = intel_snb_event_constraints; +pr_cont ("SandyBridge events, " ); +break ; +default :/* * default constraints for v2 and up arch/x86/kernel/cpu/perf_event_intel_ds.c +15
-0@@ -388,6 +388,42 @@ static struct event_constraint intel_nehalem_pebs_events[] = {EVENT_CONSTRAINT_END }; +static struct event_constraint intel_snb_pebs_events[] = { +PEBS_EVENT_CONSTRAINT (0x01c0 ,0x2 ),/* INST_RETIRED.PRECDIST */ +PEBS_EVENT_CONSTRAINT (0x01c2 ,0xf ),/* UOPS_RETIRED.ALL */ +PEBS_EVENT_CONSTRAINT (0x02c2 ,0xf ),/* UOPS_RETIRED.RETIRE_SLOTS */ +PEBS_EVENT_CONSTRAINT (0x01c4 ,0xf ),/* BR_INST_RETIRED.CONDITIONAL */ +PEBS_EVENT_CONSTRAINT (0x02c4 ,0xf ),/* BR_INST_RETIRED.NEAR_CALL */ +PEBS_EVENT_CONSTRAINT (0x04c4 ,0xf ),/* BR_INST_RETIRED.ALL_BRANCHES */ +PEBS_EVENT_CONSTRAINT (0x08c4 ,0xf ),/* BR_INST_RETIRED.NEAR_RETURN */ +PEBS_EVENT_CONSTRAINT (0x10c4 ,0xf ),/* BR_INST_RETIRED.NOT_TAKEN */ +PEBS_EVENT_CONSTRAINT (0x20c4 ,0xf ),/* BR_INST_RETIRED.NEAR_TAKEN */ +PEBS_EVENT_CONSTRAINT (0x40c4 ,0xf ),/* BR_INST_RETIRED.FAR_BRANCH */ +PEBS_EVENT_CONSTRAINT (0x01c5 ,0xf ),/* BR_MISP_RETIRED.CONDITIONAL */ +PEBS_EVENT_CONSTRAINT (0x02c5 ,0xf ),/* BR_MISP_RETIRED.NEAR_CALL */ +PEBS_EVENT_CONSTRAINT (0x04c5 ,0xf ),/* BR_MISP_RETIRED.ALL_BRANCHES */ +PEBS_EVENT_CONSTRAINT (0x10c5 ,0xf ),/* BR_MISP_RETIRED.NOT_TAKEN */ arch/x86/kernel/cpu/perf_event_intel_ds.c static struct event_constraint intel_nehalem_pebs_events[] = { · line 415
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +9
-0+PEBS_EVENT_CONSTRAINT (0x20c5 ,0xf ),/* BR_MISP_RETIRED.TAKEN */ +PEBS_EVENT_CONSTRAINT (0x01cd ,0x8 ),/* MEM_TRANS_RETIRED.LOAD_LATENCY */ +PEBS_EVENT_CONSTRAINT (0x02cd ,0x8 ),/* MEM_TRANS_RETIRED.PRECISE_STORE */ +PEBS_EVENT_CONSTRAINT (0x01d0 ,0xf ),/* MEM_UOP_RETIRED.LOADS */ +PEBS_EVENT_CONSTRAINT (0x02d0 ,0xf ),/* MEM_UOP_RETIRED.STORES */ +PEBS_EVENT_CONSTRAINT (0x10d0 ,0xf ),/* MEM_UOP_RETIRED.STLB_MISS */ +PEBS_EVENT_CONSTRAINT (0x20d0 ,0xf ),/* MEM_UOP_RETIRED.LOCK */ +PEBS_EVENT_CONSTRAINT (0x40d0 ,0xf ),/* MEM_UOP_RETIRED.SPLIT */ + PEBS_EVENT_CONSTRAINT(0x80d0, 0xf), /* MEM_UOP_RETIRED.ALL */Not quite. For event
0xd0, you are not listing the right umask combinations. The following combinations are supported for event0xd0:
0x5381d0snb::MEM_UOP_RETIRED:ANY_LOADS0x5382d0snb::MEM_UOP_RETIRED:ANY_STORES0x5321d0snb::MEM_UOP_RETIRED:LOCK_LOADS0x5322d0snb::MEM_UOP_RETIRED:LOCK_STORES0x5341d0snb::MEM_UOP_RETIRED:SPLIT_LOADS0x5342d0snb::MEM_UOP_RETIRED:SPLIT_STORES0x5311d0snb::MEM_UOP_RETIRED:STLB_MISS_LOADS0x5312d0snb::MEM_UOP_RETIRED:STLB_MISS_STORES
Quoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
Quoted 238 lines · Lin Ming
Quoted 235 lines · Stephane Eranian
Quoted 215 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
All PEBS events are tested on my SandyBridge machine and work well. Note that SandyBridge does not support
INSTR_RETIRED.ANY(0x00c0)PEBS event, instead it supportsINST_RETIRED.PRECDIST(0x01c0)event and PMC1 only.v1 -> v2:
- add more raw and PEBS events constraints
- use offcore events for LLC-* cache events
- remove the call to Nehalem workaroundenable_allfunctiontodo:
- precise store
- precise distribution of instructions retiredSigned-off-by Lin Ming <[email protected]>---
arch/x86/kernel/cpu/perf_event.c | 2 +arch/x86/kernel/cpu/perf_event_intel.c| 123 +++++++++++++++++++++++++++++arch/x86/kernel/cpu/perf_event_intel_ds.c| 44 ++++++++++-3 files changed, 168 insertions(+), 1 deletions(-)arch/x86/kernel/cpu/perf_event.c +2
-0@@ -148,6 +148,8 @@ struct cpu_hw_events {*/ #define INTEL_EVENT_CONSTRAINT(c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) /** Constraint on the Event code + UMask + fixed-mask arch/x86/kernel/cpu/perf_event_intel.c +0
-0@@ -76,6 +76,19 @@ static struct event_constraint intel_westmere_event_constraints[] =EVENT_CONSTRAINT_END
};arch/x86/kernel/cpu/perf_event_intel.c +13
-0+static struct event_constraint intel_snb_event_constraints[] = +{ + FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ + FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ + /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ + INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ + INTEL_EVENT_CONSTRAINT(0xb7, 0x1), /* OFF_CORE_RESPONSE_0 */ + INTEL_EVENT_CONSTRAINT(0xbb, 0x8), /* OFF_CORE_RESPONSE_1 */ + INTEL_EVENT_CONSTRAINT2(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ + INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ + EVENT_CONSTRAINT_END +}; +static struct
event_constraintintel_gen_event_constraints[] = {
FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */arch/x86/kernel/cpu/perf_event_intel.c +100
-0@@ -89,6 +102,106 @@ static u64 intel_pmu_event_map(int hw_event) return intel_perfmon_event_map[hw_event]; } +static __initconst const u64 snb_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = +{ + [C (L1D ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */ + [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */ + }, + }, + [C (L1I ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [ C(LL ) ] = { + /* + * TBD: Need Off-core Response Performance Monitoring support + */ + [ C(OP_READ) ] = { + /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + [ C(OP_WRITE) ] = { + /* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + [ C(OP_PREFETCH) ] = { + /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ + [ C(RESULT_ACCESS) ] = 0x01b7, + /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ + [ C(RESULT_MISS) ] = 0x01bb, + }, + }, + [C (DTLB ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x01d0, /* MEM_UOP_RETIRED.LOADS */ + [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = 0x02d0, /* MEM_UOP_RETIRED.STORES */ + [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = 0x0, + [ C(RESULT_MISS) ] = 0x0, + }, + }, + [C (ITLB ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */ + [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, + [C (BPU ) ] = { + [ C(OP_READ) ] = { + [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ + [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */ + }, + [ C(OP_WRITE) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + [ C(OP_PREFETCH) ] = { + [ C(RESULT_ACCESS) ] = -1, + [ C(RESULT_MISS) ] = -1, + }, + }, +}; +static
__initconstconst u64westmere_hw_cache_event_ids[PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX]arch/x86/kernel/cpu/perf_event_intel.c +10
-0@@ -1062,6 +1175,16 @@ static __init int intel_pmu_init(void) pr_cont("Westmere events, "); break; + case 42: /* SandyBridge */ + memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, + sizeof(hw_cache_event_ids)); + + intel_pmu_lbr_init_nhm(); + + x86_pmu.event_constraints = intel_snb_event_constraints; + pr_cont("SandyBridge events, "); + break; +default:
/*
* default constraints for v2 and uparch/x86/kernel/cpu/perf_event_intel_ds.c +0
-0@@ -388,6 +388,42 @@ static struct event_constraint intel_nehalem_pebs_events[] = {EVENT_CONSTRAINT_END
};+static struct
event_constraintintel_snb_pebs_events[] = {
+PEBS_EVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */
+PEBS_EVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */
+PEBS_EVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */
+PEBS_EVENT_CONSTRAINT(0x01c4, 0xf), /* BR_INST_RETIRED.CONDITIONAL */
+PEBS_EVENT_CONSTRAINT(0x02c4, 0xf), /* BR_INST_RETIRED.NEAR_CALL */
+PEBS_EVENT_CONSTRAINT(0x04c4, 0xf), /* BR_INST_RETIRED.ALL_BRANCHES */
+PEBS_EVENT_CONSTRAINT(0x08c4, 0xf), /* BR_INST_RETIRED.NEAR_RETURN */
+PEBS_EVENT_CONSTRAINT(0x10c4, 0xf), /* BR_INST_RETIRED.NOT_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x20c4, 0xf), /* BR_INST_RETIRED.NEAR_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x40c4, 0xf), /* BR_INST_RETIRED.FAR_BRANCH */
+PEBS_EVENT_CONSTRAINT(0x01c5, 0xf), /* BR_MISP_RETIRED.CONDITIONAL */
+PEBS_EVENT_CONSTRAINT(0x02c5, 0xf), /* BR_MISP_RETIRED.NEAR_CALL */
+PEBS_EVENT_CONSTRAINT(0x04c5, 0xf), /* BR_MISP_RETIRED.ALL_BRANCHES */
+PEBS_EVENT_CONSTRAINT(0x10c5, 0xf), /* BR_MISP_RETIRED.NOT_TAKEN */
+PEBS_EVENT_CONSTRAINT(0x20c5, 0xf), /* BR_MISP_RETIRED.TAKEN */
+PEBS_EVENT_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
+PEBS_EVENT_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORE */Quoted 6 lines
+
PEBS_EVENT_CONSTRAINT(0x01d0, 0xf), /* MEM_UOP_RETIRED.LOADS */
+PEBS_EVENT_CONSTRAINT(0x02d0, 0xf), /* MEM_UOP_RETIRED.STORES */
+PEBS_EVENT_CONSTRAINT(0x10d0, 0xf), /* MEM_UOP_RETIRED.STLB_MISS */
+PEBS_EVENT_CONSTRAINT(0x20d0, 0xf), /* MEM_UOP_RETIRED.LOCK */
+PEBS_EVENT_CONSTRAINT(0x40d0, 0xf), /* MEM_UOP_RETIRED.SPLIT */
+PEBS_EVENT_CONSTRAINT(0x80d0, 0xf), /* MEM_UOP_RETIRED.ALL */Not quite. For event
0xd0, you are not listing the right umask combinations. The following combinations are supported for event0xd0:
0x5381d0snb::MEM_UOP_RETIRED:ANY_LOADS0x5382d0snb::MEM_UOP_RETIRED:ANY_STORES0x5321d0snb::MEM_UOP_RETIRED:LOCK_LOADS0x5322d0snb::MEM_UOP_RETIRED:LOCK_STORES0x5341d0snb::MEM_UOP_RETIRED:SPLIT_LOADS0x5342d0snb::MEM_UOP_RETIRED:SPLIT_STORES0x5311d0snb::MEM_UOP_RETIRED:STLB_MISS_LOADS0x5312d0snb::MEM_UOP_RETIRED:STLB_MISS_STORESQuoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
Quoted 9 lines
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
I think Table A-2 is correct. Umasks 10h, 20h, 40h, 80h MUST be combined to collect something meaningful.
Quoted 242 lines · Stephane Eranian
Quoted 241 lines · Lin Ming
Quoted 235 lines · Stephane Eranian
Quoted 211 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
All PEBS events are tested on my SandyBridge machine and work well. Note that SandyBridge does not support
INSTR_RETIRED.ANY(0x00c0)PEBS event, instead it supportsINST_RETIRED.PRECDIST(0x01c0)event and PMC1 only.v1 -> v2:
- add more raw and PEBS events constraints
- use offcore events for LLC-* cache events
- remove the call to Nehalem workaroundenable_allfunctiontodo:
- precise store
- precise distribution of instructions retiredSigned-off-by Lin Ming <[email protected]>--- arch/x86/kernel/cpu/perf_event.c | 2 + arch/x86/kernel/cpu/perf_event_intel.c | 123 +++++++++++++++++++++++++++++ arch/x86/kernel/cpu/perf_event_intel_ds.c | 44 ++++++++++- 3 files changed, 168 insertions(+), 1 deletions(-)arch/x86/kernel/cpu/perf_event.c +2
-0@@ -148,6 +148,8 @@ struct cpu_hw_events {*/ #define INTEL_EVENT_CONSTRAINT (c, n) \ EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)/* * Constraint on the Event code + UMask + fixed-mask arch/x86/kernel/cpu/perf_event_intel.c +123
-0@@ -76,6 +76,19 @@ static struct event_constraint intel_westmere_event_constraints[] =EVENT_CONSTRAINT_END }; +static struct event_constraint intel_snb_event_constraints[] = +{ +FIXED_EVENT_CONSTRAINT (0x00c0 ,0 ),/* INST_RETIRED.ANY */ +FIXED_EVENT_CONSTRAINT (0x003c ,1 ),/* CPU_CLK_UNHALTED.CORE */ +/* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ +INTEL_EVENT_CONSTRAINT (0x48 ,0x4 ),/* L1D_PEND_MISS.PENDING */ +INTEL_EVENT_CONSTRAINT (0xb7 ,0x1 ),/* OFF_CORE_RESPONSE_0 */ +INTEL_EVENT_CONSTRAINT (0xbb ,0x8 ),/* OFF_CORE_RESPONSE_1 */ +INTEL_EVENT_CONSTRAINT2 (0x01c0 ,0x2 ),/* INST_RETIRED.PREC_DIST */ +INTEL_EVENT_CONSTRAINT (0xcd ,0x8 ),/* MEM_TRANS_RETIRED.LOAD_LATENCY */ +EVENT_CONSTRAINT_END +}; +static struct event_constraint intel_gen_event_constraints[] = {FIXED_EVENT_CONSTRAINT (0x00c0 ,0 ),/* INST_RETIRED.ANY */ @@ -89,6 +102,106 @@ static u64 intel_pmu_event_map(int hw_event)return intel_perfmon_event_map[hw_event]; } +static __initconst const u64 snb_hw_cache_event_ids + [PERF_COUNT_HW_CACHE_MAX ] + [PERF_COUNT_HW_CACHE_OP_MAX ] + [PERF_COUNT_HW_CACHE_RESULT_MAX ] = +{ + [C (L1D ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0xf1d0 ,/* MEM_UOP_RETIRED.LOADS */ + [C (RESULT_MISS ) ] =0x0151 ,/* L1D.REPLACEMENT */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =0xf2d0 ,/* MEM_UOP_RETIRED.STORES */ + [C (RESULT_MISS ) ] =0x0851 ,/* L1D.ALL_M_REPLACEMENT */ + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x024e ,/* HW_PRE_REQ.DL1_MISS */ + }, + }, + [C (L1I ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0280 ,/* ICACHE.MISSES */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0 , + }, + }, + [C (LL ) ] = { +/* +* TBD: Need Off-core Response Performance Monitoring support +*/ + [C (OP_READ ) ] = { +/* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + [C (OP_WRITE ) ] = { +/* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + [C (OP_PREFETCH ) ] = { +/* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ + [C (RESULT_ACCESS ) ] =0x01b7 , +/* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ + [C (RESULT_MISS ) ] =0x01bb , + }, + }, + [C (DTLB ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x01d0 ,/* MEM_UOP_RETIRED.LOADS */ + [C (RESULT_MISS ) ] =0x0108 ,/* DTLB_LOAD_MISSES.CAUSES_A_WALK */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =0x02d0 ,/* MEM_UOP_RETIRED.STORES */ + [C (RESULT_MISS ) ] =0x0149 ,/* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =0x0 , + [C (RESULT_MISS ) ] =0x0 , + }, + }, + [C (ITLB ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x1085 ,/* ITLB_MISSES.STLB_HIT */ + [C (RESULT_MISS ) ] =0x0185 ,/* ITLB_MISSES.CAUSES_A_WALK */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + }, + [C (BPU ) ] = { + [C (OP_READ ) ] = { + [C (RESULT_ACCESS ) ] =0x00c4 ,/* BR_INST_RETIRED.ALL_BRANCHES */ + [C (RESULT_MISS ) ] =0x00c5 ,/* BR_MISP_RETIRED.ALL_BRANCHES */ + }, + [C (OP_WRITE ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + [C (OP_PREFETCH ) ] = { + [C (RESULT_ACCESS ) ] =-1 , + [C (RESULT_MISS ) ] =-1 , + }, + }, +}; +static __initconst const u64 westmere_hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX ] [PERF_COUNT_HW_CACHE_OP_MAX ]@@ -1062,6 +1175,16 @@ static __init int intel_pmu_init(void)pr_cont ("Westmere events, " );break ; +case 42 :/* SandyBridge */ +memcpy (hw_cache_event_ids, snb_hw_cache_event_ids, +sizeof (hw_cache_event_ids)); + +intel_pmu_lbr_init_nhm (); + + x86_pmu.event_constraints = intel_snb_event_constraints; +pr_cont ("SandyBridge events, " ); +break ; +default :/* * default constraints for v2 and up arch/x86/kernel/cpu/perf_event_intel_ds.c +15
-0@@ -388,6 +388,42 @@ static struct event_constraint intel_nehalem_pebs_events[] = {EVENT_CONSTRAINT_END }; +static struct event_constraint intel_snb_pebs_events[] = { +PEBS_EVENT_CONSTRAINT (0x01c0 ,0x2 ),/* INST_RETIRED.PRECDIST */ +PEBS_EVENT_CONSTRAINT (0x01c2 ,0xf ),/* UOPS_RETIRED.ALL */ +PEBS_EVENT_CONSTRAINT (0x02c2 ,0xf ),/* UOPS_RETIRED.RETIRE_SLOTS */ +PEBS_EVENT_CONSTRAINT (0x01c4 ,0xf ),/* BR_INST_RETIRED.CONDITIONAL */ +PEBS_EVENT_CONSTRAINT (0x02c4 ,0xf ),/* BR_INST_RETIRED.NEAR_CALL */ +PEBS_EVENT_CONSTRAINT (0x04c4 ,0xf ),/* BR_INST_RETIRED.ALL_BRANCHES */ +PEBS_EVENT_CONSTRAINT (0x08c4 ,0xf ),/* BR_INST_RETIRED.NEAR_RETURN */ +PEBS_EVENT_CONSTRAINT (0x10c4 ,0xf ),/* BR_INST_RETIRED.NOT_TAKEN */ +PEBS_EVENT_CONSTRAINT (0x20c4 ,0xf ),/* BR_INST_RETIRED.NEAR_TAKEN */ +PEBS_EVENT_CONSTRAINT (0x40c4 ,0xf ),/* BR_INST_RETIRED.FAR_BRANCH */ +PEBS_EVENT_CONSTRAINT (0x01c5 ,0xf ),/* BR_MISP_RETIRED.CONDITIONAL */ +PEBS_EVENT_CONSTRAINT (0x02c5 ,0xf ),/* BR_MISP_RETIRED.NEAR_CALL */ +PEBS_EVENT_CONSTRAINT (0x04c5 ,0xf ),/* BR_MISP_RETIRED.ALL_BRANCHES */ +PEBS_EVENT_CONSTRAINT (0x10c5 ,0xf ),/* BR_MISP_RETIRED.NOT_TAKEN */ arch/x86/kernel/cpu/perf_event_intel_ds.c static struct event_constraint intel_nehalem_pebs_events[] = { · line 415
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +9
-0+PEBS_EVENT_CONSTRAINT (0x20c5 ,0xf ),/* BR_MISP_RETIRED.TAKEN */ +PEBS_EVENT_CONSTRAINT (0x01cd ,0x8 ),/* MEM_TRANS_RETIRED.LOAD_LATENCY */ +PEBS_EVENT_CONSTRAINT (0x02cd ,0x8 ),/* MEM_TRANS_RETIRED.PRECISE_STORE */ +PEBS_EVENT_CONSTRAINT (0x01d0 ,0xf ),/* MEM_UOP_RETIRED.LOADS */ +PEBS_EVENT_CONSTRAINT (0x02d0 ,0xf ),/* MEM_UOP_RETIRED.STORES */ +PEBS_EVENT_CONSTRAINT (0x10d0 ,0xf ),/* MEM_UOP_RETIRED.STLB_MISS */ +PEBS_EVENT_CONSTRAINT (0x20d0 ,0xf ),/* MEM_UOP_RETIRED.LOCK */ +PEBS_EVENT_CONSTRAINT (0x40d0 ,0xf ),/* MEM_UOP_RETIRED.SPLIT */ + PEBS_EVENT_CONSTRAINT(0x80d0, 0xf), /* MEM_UOP_RETIRED.ALL */Not quite. For event
0xd0, you are not listing the right umask combinations. The following combinations are supported for event0xd0:0x5381d0 snb::MEM_UOP_RETIRED:ANY_LOADS 0x5382d0 snb::MEM_UOP_RETIRED:ANY_STORES 0x5321d0 snb::MEM_UOP_RETIRED:LOCK_LOADS 0x5322d0 snb::MEM_UOP_RETIRED:LOCK_STORES 0x5341d0 snb::MEM_UOP_RETIRED:SPLIT_LOADS 0x5342d0 snb::MEM_UOP_RETIRED:SPLIT_STORES 0x5311d0 snb::MEM_UOP_RETIRED:STLB_MISS_LOADS 0x5312d0 snb::MEM_UOP_RETIRED:STLB_MISS_STORESQuoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
Quoted 8 lines
Quoted 6 lines
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
I think Table A-2 is correct. Umasks 10h, 20h, 40h, 80h MUST be combined to collect something meaningful.
Yes, thanks for figuring this out.
Quoted 22 lines · Lin Ming
Quoted 22 lines
Quoted 22 lines
Quoted 13 lines
Not quite. For event
0xd0, you are not listing the right umask combinations. The following combinations are supported for event0xd0:0x5381d0 snb::MEM_UOP_RETIRED:ANY_LOADS 0x5382d0 snb::MEM_UOP_RETIRED:ANY_STORES 0x5321d0 snb::MEM_UOP_RETIRED:LOCK_LOADS 0x5322d0 snb::MEM_UOP_RETIRED:LOCK_STORES 0x5341d0 snb::MEM_UOP_RETIRED:SPLIT_LOADS 0x5342d0 snb::MEM_UOP_RETIRED:SPLIT_STORES 0x5311d0 snb::MEM_UOP_RETIRED:STLB_MISS_LOADS 0x5312d0 snb::MEM_UOP_RETIRED:STLB_MISS_STORESQuoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Which one is correct?
I think Table A-2 is correct. Umasks 10h, 20h, 40h, 80h MUST be combined to collect something meaningful.
Yes, thanks for figuring this out.
I also fix the dTLB-loads/stores events.
arch/x86/kernel/cpu/perf_event_intel.c +2 -2
@@ -160,11 +160,11 @@ static __initconst const u64 snb_hw_cache_event_ids }, [ C(DTLB) ] = { [ C(OP_READ) ] = { - [ C(RESULT_ACCESS) ] = 0x01d0, /* MEM_UOP_RETIRED.LOADS */ + [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ANY_LOADS */ [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */ }, [ C(OP_WRITE) ] = { - [ C(RESULT_ACCESS) ] = 0x02d0, /* MEM_UOP_RETIRED.STORES */ + [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ANY_STORES */ [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ }, [ C(OP_PREFETCH) ] = {
arch/x86/kernel/cpu/perf_event_intel_ds.c +8 -6
@@ -406,12 +406,14 @@ static struct event_constraint intel_snb_pebs_events[] = {PEBS_EVENT_CONSTRAINT (0x20c5 ,0xf ),/* BR_MISP_RETIRED.TAKEN */ PEBS_EVENT_CONSTRAINT (0x01cd ,0x8 ),/* MEM_TRANS_RETIRED.LOAD_LATENCY */ PEBS_EVENT_CONSTRAINT (0x02cd ,0x8 ),/* MEM_TRANS_RETIRED.PRECISE_STORE */ -PEBS_EVENT_CONSTRAINT (0x01d0 ,0xf ),/* MEM_UOP_RETIRED.LOADS */ -PEBS_EVENT_CONSTRAINT (0x02d0 ,0xf ),/* MEM_UOP_RETIRED.STORES */ -PEBS_EVENT_CONSTRAINT (0x10d0 ,0xf ),/* MEM_UOP_RETIRED.STLB_MISS */ -PEBS_EVENT_CONSTRAINT (0x20d0 ,0xf ),/* MEM_UOP_RETIRED.LOCK */ -PEBS_EVENT_CONSTRAINT (0x40d0 ,0xf ),/* MEM_UOP_RETIRED.SPLIT */ -PEBS_EVENT_CONSTRAINT (0x80d0 ,0xf ),/* MEM_UOP_RETIRED.ALL */ +PEBS_EVENT_CONSTRAINT (0x11d0 ,0xf ),/* MEM_UOP_RETIRED.STLB_MISS_LOADS */ +PEBS_EVENT_CONSTRAINT (0x12d0 ,0xf ),/* MEM_UOP_RETIRED.STLB_MISS_STORES */ +PEBS_EVENT_CONSTRAINT (0x21d0 ,0xf ),/* MEM_UOP_RETIRED.LOCK_LOADS */ +PEBS_EVENT_CONSTRAINT (0x22d0 ,0xf ),/* MEM_UOP_RETIRED.LOCK_STORES */ +PEBS_EVENT_CONSTRAINT (0x41d0 ,0xf ),/* MEM_UOP_RETIRED.SPLIT_LOADS */ +PEBS_EVENT_CONSTRAINT (0x42d0 ,0xf ),/* MEM_UOP_RETIRED.SPLIT_STORES */ +PEBS_EVENT_CONSTRAINT (0x81d0 ,0xf ),/* MEM_UOP_RETIRED.ANY_LOADS */ +PEBS_EVENT_CONSTRAINT (0x82d0 ,0xf ),/* MEM_UOP_RETIRED.ANY_STORES */ PEBS_EVENT_CONSTRAINT (0x01d1 ,0xf ),/* MEM_LOAD_UOPS_RETIRED.L1_HIT */ PEBS_EVENT_CONSTRAINT (0x02d1 ,0xf ),/* MEM_LOAD_UOPS_RETIRED.L2_HIT */ PEBS_EVENT_CONSTRAINT(0x04d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.LLC_HIT */
Quoted 10 lines · Lin Ming
Quoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
Since you have access to the hardware, could you please test and see it in practice which one is correct?
Thanks,
Ingo
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Lin Ming
Quoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
Quoted 8 lines
Quoted 5 lines
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
Since you have access to the hardware, could you please test and see it in practice which one is correct?
Stephane is right, need the combination.
Sorry that I may made mistake when I tested 0xd0 pebs events.
Re-test all PEBS events, now only below 2 events need more support to work.
PEBS_EVENT_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ PEBS_EVENT_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORE*/
Quoted 4 lines
Thanks,
Ingo
Also for offcore_reponse_*, the fact that they are marked as PMC3 only is just a convenience for scheduling. Given both events need an extra MSR, it makes scheduling easier if you consider offcore_reponse_0 to work only on one counter. That guarantees there won't be conflict on that extra MSR. The downside, is that you cannot measure the event twice if you only want to vary the counter filters (not the extra MSR), e.g., measure one instance at user level and the other at kernel level.
On SNB, the extra MSRs are not shared by HT threads anymore (Table B-9). That means that in the offcore patch, the extra_config logic is needed but not the mutual exclusion between HT threads.
Quoted 33 lines · Lin Ming
Quoted 7 lines · Ingo Molnar
Quoted 5 lines · Lin Ming
Quoted 1 line
In other words, bit 0-3 of the umask cannot be zero.
I got the umask from "Table 30-20. PEBS Performance Events for Intel microarchitecture code name Sandy Bridge".
Quoted 8 lines
Quoted 5 lines
But from "Table A-2. Non-Architectural Performance Events In the Processor Core for Intel Core Processor 2xxx Series", the combinations are needed as you show above.
Which one is correct?
Since you have access to the hardware, could you please test and see it in practice which one is correct?
Stephane is right, need the combination.
Sorry that I may made mistake when I tested0xd0pebs events.Re-test all PEBS events, now only below 2 events need more support to work.
PEBS_EVENT_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */PEBS_EVENT_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORE*/Quoted 4 lines
Thanks,
Ingo
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\arch/x86/kernel/cpu/perf_event.c +2
-0EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINT or somesuch.
Quoted 5 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events;
arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 750
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-0+switch (boot_cpu_data.x86_model) { +case 42 :/* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; +break ; +default : + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + }break ;default :
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 34 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;
Quoted 5 lines
Quoted 1 line
default:
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
My PEBS patch was going to cleanup this part, though it was using it's own switch
statement.
Quoted 35 lines · Stephane Eranian
Quoted 34 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)arch/x86/kernel/cpu/perf_event.c +2
-0+#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; +switch (boot_cpu_data.x86_model) { +case 42 :/* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; +break ; +default : + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + }break ;
Quoted 8 lines
Quoted 5 lines
Review static void intel_ds_init(void) · line 750
Quoted 1 line
(quoted diff) +0
-0default:We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
My PEBS patch was going to cleanup this part, though it was using it's own switch
statement.
Did you send out the patch? A link?
Quoted 41 lines · Lin Ming
Quoted 40 lines · Stephane Eranian
Quoted 39 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;Quoted 1 line
default:
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 6 lines
Quoted 3 lines
My PEBS patch was going to cleanup this part, though it was using it's own switch
statement.Did you send out the patch? A link?
For what?
Quoted 2 lines
Quoted 42 lines · Stephane Eranian
Quoted 41 lines · Lin Ming
Quoted 40 lines · Stephane Eranian
Quoted 39 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)arch/x86/kernel/cpu/perf_event.c +2
-0+#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 5 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events;arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 750
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-0+switch (boot_cpu_data.x86_model) { +case 42 :/* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; +break ; +default : + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + }break ;default :We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
My PEBS patch was going to cleanup this part, though it was using it's own switch
statement.Did you send out the patch? A link?
For what?
I mean your PEBS patch to do the cleanup.
Quoted 3 lines
Quoted 3 lines
Quoted 47 lines · Lin Ming
Quoted 46 lines · Stephane Eranian
Quoted 45 lines · Lin Ming
Quoted 43 lines · Stephane Eranian
Quoted 34 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;Quoted 5 lines
Quoted 1 line
default:
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
My PEBS patch was going to cleanup this part, though it was using it's own switch
statement.
Quoted 6 lines
Quoted 3 lines
Quoted 2 lines
Did you send out the patch? A link?
For what?
I mean your PEBS patch to do the cleanup.
I am updating it based on our discussion. Running a few tests and it should be out today.
Quoted 9 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
There is an event scheduling issue.
http://marc.info/?l=linux-kernel&m=129842356323752&w=2
I'll look at it.
Quoted 10 lines
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 6 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\arch/x86/kernel/cpu/perf_event.c +2
-0EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.
OK.
But any case it's duplicated with PEBS_EVENT_CONSTRAINT.
#define PEBS_EVENT_CONSTRAINT(c, n) \
EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
Quoted 19 lines
Quoted 6 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events;arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 750
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-0+switch (boot_cpu_data.x86_model) { +case 42 :/* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; +break ; +default : + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + }break ;default :We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 7 lines · Lin Ming
Quoted 7 lines
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)arch/x86/kernel/cpu/perf_event.c +2
-0+#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
Quoted 8 lines
Quoted 1 line
INTEL_UEVENT_CONSTRAINTor somesuch.OK.
But any case it's duplicated with
PEBS_EVENT_CONSTRAINT.#define
PEBS_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
Ah, indeed, so maybe we can remove PEBS_EVENT_CONSTRAINT and use regular INTEL_*_CONSTRAINTS there, that could also help for PEBS events where all umasks are allowed (not sure there are any such things but the SNB PEBS list was quite large).
Quoted 14 lines · Peter Zijlstra
Quoted 13 lines · Lin Ming
Quoted 8 lines
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)arch/x86/kernel/cpu/perf_event.c +2
-0+#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.OK.
But any case it's duplicated with
PEBS_EVENT_CONSTRAINT.
Quoted 7 lines
Quoted 2 lines
#define
PEBS_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)Ah, indeed, so maybe we can remove
PEBS_EVENT_CONSTRAINTand use regular INTEL_*_CONSTRAINTS there, that could also help for PEBS events where all umasks are allowed (not sure there are any such things but the SNB PEBS list was quite large).
Yes, there are, for example, BR_INST_RETIRED.*
Quoted 18 lines · Lin Ming
Quoted 17 lines · Peter Zijlstra
Quoted 15 lines · Lin Ming
Quoted 8 lines
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.OK.
But any case it's duplicated with
PEBS_EVENT_CONSTRAINT.#define
PEBS_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)
Quoted 7 lines
Quoted 4 lines
Ah, indeed, so maybe we can remove
PEBS_EVENT_CONSTRAINTand use regular INTEL_*_CONSTRAINTS there, that could also help for PEBS events where all umasks are allowed (not sure there are any such things but the SNB PEBS list was quite large).Yes, there are, for example, BR_INST_RETIRED.*
I think most of the time all umasks are allowed.
Quoted 1 line
Quoted 34 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
Review
Quoted 4 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\(quoted diff) +2
-0EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT) +#define INTEL_EVENT_CONSTRAINT2(c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
(quoted diff) +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;
Quoted 4 lines
Review static void intel_ds_init(void) · line 750
Quoted 1 line
(quoted diff) +0
-0default:We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
How about below?
Leave the default pebs constraint assignment in intel_ds_init, and overwrite it for snb in intel_pmu_init.
arch/x86/kernel/cpu/perf_event_intel.c +1 -0
@@ -1182,6 +1182,7 @@ static __init int intel_pmu_init(void)intel_pmu_lbr_init_nhm (); x86_pmu.event_constraints = intel_snb_event_constraints; + x86_pmu.pebs_constraints = intel_snb_pebs_events;pr_cont ("SandyBridge events, " );break ;
arch/x86/kernel/cpu/perf_event_intel_ds.c +0 -7
@@ -740,13 +740,6 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; -switch (boot_cpu_data.x86_model) { -case 42 :/* SandyBridge */ - x86_pmu.pebs_constraints = intel_snb_pebs_events; -break ; -default : - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; - }break ;default :
arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 743
Quoted 12 lines · Lin Ming
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-7@@ -740,13 +740,6 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; -switch (boot_cpu_data.x86_model) { -case 42 :/* SandyBridge */ - x86_pmu.pebs_constraints = intel_snb_pebs_events; -break ; -default : - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; - }break ;
it looks like you lost the nhm table assignment
Quoted 15 lines · Peter Zijlstra
arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 743
Quoted 12 lines · Lin Ming
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-7@@ -740,13 +740,6 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; -switch (boot_cpu_data.x86_model) { -case 42 :/* SandyBridge */ - x86_pmu.pebs_constraints = intel_snb_pebs_events; -break ; -default : - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; - }break ;it looks like you lost the nhm table assignment
Ah, yes. Will update all in v3 patch.
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with hwc->extra_alloc.
Could probably find a better name for that field.
static struct event_constraint *intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
unsigned int e = hwc->config & ARCH_PERFMON_EVENTSEL_EVENT;
struct event_constraint *c;
struct intel_percore *pc;
struct er_account *era;
int i;
int free_slot;
int found;
if (!x86_pmu.percore_constraints)
return NULL;
if (hwc->extra_alloc)
return NULL;
for (c = x86_pmu.percore_constraints; c->cmask; c++) {
if (e != c->code)
continue;
/*
* Allocate resource per core.
*/
c = NULL;
pc = cpuc->per_core;
if (!pc)
break;
c = &emptyconstraint;
raw_spin_lock(&pc->lock);
free_slot = -1;
found = 0;
for (i = 0; i < MAX_EXTRA_REGS; i++) {
era = &pc->regs[i];
if (era->ref > 0 && hwc->extra_reg == era->extra_reg) {
/* Allow sharing same config */
if (hwc->extra_config == era->extra_config) {
era->ref++;
cpuc->percore_used = 1;
hwc->extra_alloc = 1;
c = NULL;
}
/* else conflict */
found = 1;
break;
} else if (era->ref == 0 && free_slot == -1)
free_slot = i;
}
if (!found && free_slot != -1) {
era = &pc->regs[free_slot];
era->ref = 1;
era->extra_reg = hwc->extra_reg;
era->extra_config = hwc->extra_config;
cpuc->percore_used = 1;
hwc->extra_alloc = 1;
c = NULL;
}
raw_spin_unlock(&pc->lock);
return c;
}
return NULL;
}static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
struct perf_event *event)
{
struct extra_reg *er;
struct intel_percore *pc;
struct er_account *era;
struct hw_perf_event *hwc = &event->hw;
int i, allref;
if (!cpuc->percore_used)
return;
for (er = x86_pmu.extra_regs; er->msr; er++) {
if (er->event != (hwc->config & er->config_mask))
continue;
pc = cpuc->per_core;
raw_spin_lock(&pc->lock);
for (i = 0; i < MAX_EXTRA_REGS; i++) {
era = &pc->regs[i];
if (era->ref > 0 &&
era->extra_config == hwc->extra_config &&
era->extra_reg == er->msr) {
era->ref--;
hwc->extra_alloc = 0;
break;
}
}
allref = 0;
for (i = 0; i < MAX_EXTRA_REGS; i++)
allref += pc->regs[i].ref;
if (allref == 0)
cpuc->percore_used = 0;
raw_spin_unlock(&pc->lock);
break;
}
}Quoted 29 lines
Quoted 5 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;Quoted 1 line
default:
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 5 lines · Stephane Eranian
Quoted 4 lines · Peter Zijlstra
Quoted 3 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
Quoted 7 lines
Quoted 6 lines
Quoted 2 lines
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Let me make sure I understand the problem correctly.
perf top -C 0 -e LLC-loads -e LLC-store-misses
LLC-loads and LLC-store-misses events use different extra_config.
1. LLC-loads submitted successfully, era->ref=1
2. LLC-loads event is resubmitted because incremental scheduling, era->ref=2.
3. LLC-store-misses is submitted, but fail because conflict.
Step 2 is wrong, the reference count should not be incremented with the same event.
Is my understanding right?
Lin Ming
Quoted 136 lines
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.static struct
event_constraint*intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event){ struct hw_perf_event *hwc = &event->hw; unsigned int e = hwc->config & ARCH_PERFMON_EVENTSEL_EVENT; struct event_constraint *c; struct intel_percore *pc; struct er_account *era; int i; int free_slot; int found; if (!x86_pmu.percore_constraints) return NULL; if (hwc->extra_alloc) return NULL; for (c = x86_pmu.percore_constraints; c->cmask; c++) { if (e != c->code) continue; /* * Allocate resource per core. */ c = NULL; pc = cpuc->per_core; if (!pc) break; c = &emptyconstraint; raw_spin_lock(&pc->lock); free_slot = -1; found = 0; for (i = 0; i < MAX_EXTRA_REGS; i++) { era = &pc->regs[i]; if (era->ref > 0 && hwc->extra_reg == era->extra_reg) { /* Allow sharing same config */ if (hwc->extra_config == era->extra_config) { era->ref++; cpuc->percore_used = 1; hwc->extra_alloc = 1; c = NULL; } /* else conflict */ found = 1; break; } else if (era->ref == 0 && free_slot == -1) free_slot = i; } if (!found && free_slot != -1) { era = &pc->regs[free_slot]; era->ref = 1; era->extra_reg = hwc->extra_reg; era->extra_config = hwc->extra_config; cpuc->percore_used = 1; hwc->extra_alloc = 1; c = NULL; } raw_spin_unlock(&pc->lock); return c; } return NULL; }static void intel_put_event_constraints(struct
cpu_hw_events*cpuc,
structperf_event*event){ struct extra_reg *er; struct intel_percore *pc; struct er_account *era; struct hw_perf_event *hwc = &event->hw; int i, allref; if (!cpuc->percore_used) return; for (er = x86_pmu.extra_regs; er->msr; er++) { if (er->event != (hwc->config & er->config_mask)) continue; pc = cpuc->per_core; raw_spin_lock(&pc->lock); for (i = 0; i < MAX_EXTRA_REGS; i++) { era = &pc->regs[i]; if (era->ref > 0 && era->extra_config == hwc->extra_config && era->extra_reg == er->msr) { era->ref--; hwc->extra_alloc = 0; break; } } allref = 0; for (i = 0; i < MAX_EXTRA_REGS; i++) allref += pc->regs[i].ref; if (allref == 0) cpuc->percore_used = 0; raw_spin_unlock(&pc->lock); break; } }Quoted 29 lines
arch/x86/kernel/cpu/perf_event.c struct cpu_hw_events { · line 152
Quoted 5 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)arch/x86/kernel/cpu/perf_event.c +2
-0+#define INTEL_EVENT_CONSTRAINT2 (c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 5 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +0
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void)printk (KERN_CONT "PEBS fmt1%c, " , pebs_type); x86_pmu.pebs_record_size =sizeof (struct pebs_record_nhm ); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events;arch/x86/kernel/cpu/perf_event_intel_ds.c static void intel_ds_init(void) · line 750
Quoted 10 lines
arch/x86/kernel/cpu/perf_event_intel_ds.c +7
-0+switch (boot_cpu_data.x86_model) { +case 42 :/* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; +break ; +default : + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + }break ;default :We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 8 lines · Stephane Eranian
Quoted 7 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
Quoted 7 lines
Quoted 3 lines
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.
Stephane,
I'll integrate below changes to the offcore patches, OK?
arch/x86/kernel/cpu/perf_event_intel.c +4 -1
@@ -906,7 +906,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)int free_slot;int found; -if (!x86_pmu.percore_constraints) +if (!x86_pmu.percore_constraints || hwc->extra_alloc)return NULL ;for (c = x86_pmu.percore_constraints; c->cmask; c++) {
@@ -931,6 +931,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)if (hwc->extra_config == era->extra_config) { era->ref++; cpuc->percore_used =1 ; + hwc->extra_alloc =1 ; c =NULL ; }/* else conflict */
@@ -945,6 +946,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) era->extra_reg = hwc->extra_reg; era->extra_config = hwc->extra_config; cpuc->percore_used =1 ; + hwc->extra_alloc =1 ; c =NULL ; }raw_spin_unlock (&pc->lock);
@@ -998,6 +1000,7 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc, era->extra_config == hwc->extra_config && era->extra_reg == er->msr) { era->ref--; + hwc->extra_alloc =0 ;break ; } }
include/linux/perf_event.h +1 -0
@@ -546,6 +546,7 @@ struct hw_perf_event {int last_cpu;unsigned int extra_reg;u64 extra_config; +int extra_alloc; };struct {/* software */ struct hrtimer hrtimer;
Quoted 133 lines
static struct
event_constraint*intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event){ struct hw_perf_event *hwc = &event->hw; unsigned int e = hwc->config & ARCH_PERFMON_EVENTSEL_EVENT; struct event_constraint *c; struct intel_percore *pc; struct er_account *era; int i; int free_slot; int found; if (!x86_pmu.percore_constraints) return NULL; if (hwc->extra_alloc) return NULL; for (c = x86_pmu.percore_constraints; c->cmask; c++) { if (e != c->code) continue; /* * Allocate resource per core. */ c = NULL; pc = cpuc->per_core; if (!pc) break; c = &emptyconstraint; raw_spin_lock(&pc->lock); free_slot = -1; found = 0; for (i = 0; i < MAX_EXTRA_REGS; i++) { era = &pc->regs[i]; if (era->ref > 0 && hwc->extra_reg == era->extra_reg) { /* Allow sharing same config */ if (hwc->extra_config == era->extra_config) { era->ref++; cpuc->percore_used = 1; hwc->extra_alloc = 1; c = NULL; } /* else conflict */ found = 1; break; } else if (era->ref == 0 && free_slot == -1) free_slot = i; } if (!found && free_slot != -1) { era = &pc->regs[free_slot]; era->ref = 1; era->extra_reg = hwc->extra_reg; era->extra_config = hwc->extra_config; cpuc->percore_used = 1; hwc->extra_alloc = 1; c = NULL; } raw_spin_unlock(&pc->lock); return c; } return NULL; }static void intel_put_event_constraints(struct
cpu_hw_events*cpuc,
structperf_event*event){ struct extra_reg *er; struct intel_percore *pc; struct er_account *era; struct hw_perf_event *hwc = &event->hw; int i, allref; if (!cpuc->percore_used) return; for (er = x86_pmu.extra_regs; er->msr; er++) { if (er->event != (hwc->config & er->config_mask)) continue; pc = cpuc->per_core; raw_spin_lock(&pc->lock); for (i = 0; i < MAX_EXTRA_REGS; i++) { era = &pc->regs[i]; if (era->ref > 0 && era->extra_config == hwc->extra_config && era->extra_reg == er->msr) { era->ref--; hwc->extra_alloc = 0; break; } } allref = 0; for (i = 0; i < MAX_EXTRA_REGS; i++) allref += pc->regs[i].ref; if (allref == 0) cpuc->percore_used = 0; raw_spin_unlock(&pc->lock); break; } }Quoted 29 lines
Review
Quoted 5 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)(quoted diff) +2
-0+#define INTEL_EVENT_CONSTRAINT2(c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 5 lines
(quoted diff) +0
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events;Review static void intel_ds_init(void) · line 750
Quoted 10 lines
(quoted diff) +7
-0+ switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break; default:We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
Quoted 12 lines · Lin Ming
Quoted 11 lines · Stephane Eranian
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
Quoted 9 lines
Quoted 4 lines
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.Stephane,
I'll integrate below changes to the offcore patches, OK?
Let me try one more test on this.
I want to show the case the caused the problem in the first place.
Quoted 47 lines
arch/x86/kernel/cpu/perf_event_intel.c +3
-1@@ -906,7 +906,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) int free_slot; int found; - if (!x86_pmu.percore_constraints) + if (!x86_pmu.percore_constraints || hwc->extra_alloc) return NULL; for (c = x86_pmu.percore_constraints; c->cmask; c++) {@@ -931,6 +931,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) if (hwc->extra_config == era->extra_config) { era->ref++; cpuc->percore_used = 1; + hwc->extra_alloc = 1; c = NULL; } /* else conflict */@@ -945,6 +946,7 @@ intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) era->extra_reg = hwc->extra_reg; era->extra_config = hwc->extra_config; cpuc->percore_used = 1; + hwc->extra_alloc = 1; c = NULL; } raw_spin_unlock(&pc->lock);@@ -998,6 +1000,7 @@ static void intel_put_event_constraints(struct cpu_hw_events *cpuc,era->extra_config ==
hwc->extra_config&&era->extra_reg==er->msr) { era->ref--;
+hwc->extra_alloc= 0; break;
}
}include/linux/perf_event.h +1
-0@@ -546,6 +546,7 @@ struct hw_perf_event { int last_cpu; unsigned int extra_reg; u64 extra_config; + int extra_alloc; };
Quoted 140 lines
struct { /* software */
struct hrtimer hrtimer;Quoted 133 lines
static struct
event_constraint*intel_percore_constraints(struct cpu_hw_events *cpuc, struct perf_event *event){
structhw_perf_event*hwc =&event->hw;
unsigned int e =hwc->config&ARCH_PERFMON_EVENTSEL_EVENT; structevent_constraint*c;
structintel_percore*pc;
structer_account*era;
int i;
intfree_slot;
int found;if (!x86_pmu.percore_constraints)
return NULL;if (
hwc->extra_alloc)
return NULL;for (c = x86_pmu.percore_constraints;
c->cmask; c++) { if (e !=c->code)
continue;/*
* Allocate resource per core.
*/
c = NULL;
pc =cpuc->per_core;
if (!pc)
break;
c = &emptyconstraint;
raw_spin_lock(&pc->lock);
free_slot= -1;
found = 0;
for (i = 0; i <MAX_EXTRA_REGS; i++) {
era = &pc->regs[i];
if (era->ref> 0 &&hwc->extra_reg==era->extra_reg) { /* Allow sharing same config */
if (hwc->extra_config==era->extra_config) { era->ref++;cpuc->percore_used= 1;hwc->extra_alloc= 1;
c = NULL;
}
/* else conflict */
found = 1;
break;
} else if (era->ref== 0 &&free_slot== -1)free_slot= i;
}
if (!found &&free_slot!= -1) {
era = &pc->regs[free_slot];
era->ref= 1;
era->extra_reg=hwc->extra_reg;era->extra_config=hwc->extra_config;cpuc->percore_used= 1;
hwc->extra_alloc= 1;
c = NULL;
}
raw_spin_unlock(&pc->lock);
return c;
}return NULL;
}static void
intel_put_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event){
structextra_reg*er;
structintel_percore*pc;
structer_account*era;
structhw_perf_event*hwc =&event->hw;
int i, allref;if (!cpuc->percore_used)
return;for (er = x86_pmu.extra_regs;
er->msr; er++) { if (er->event!= (hwc->config&er->config_mask)) continue;pc =
cpuc->per_core;raw_spin_lock(&pc->lock);
for (i = 0; i <MAX_EXTRA_REGS; i++) {
era = &pc->regs[i];
if (era->ref> 0 &&era->extra_config==hwc->extra_config&&era->extra_reg==er->msr) { era->ref--;hwc->extra_alloc= 0; break;
}
}
allref = 0;
for (i = 0; i <MAX_EXTRA_REGS; i++) allref += pc->regs[i].ref;
if (allref == 0)
cpuc->percore_used= 0;raw_spin_unlock(&pc->lock);
break;
}
}Quoted 29 lines
Quoted 5 lines
#define
INTEL_EVENT_CONSTRAINT(c, n)\
EVENT_CONSTRAINT(c, n, ARCH_PERFMON_EVENTSEL_EVENT)+#defineINTEL_EVENT_CONSTRAINT2(c, n)\
+EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK)That's a particularly bad name, how about something like
INTEL_UEVENT_CONSTRAINTor somesuch.Quoted 14 lines
(quoted diff) +7
-1@@ -702,7 +738,13 @@ static void intel_ds_init(void) printk(KERN_CONT "PEBS fmt1%c, ", pebs_type); x86_pmu.pebs_record_size = sizeof(struct pebs_record_nhm); x86_pmu.drain_pebs = intel_pmu_drain_pebs_nhm; - x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + switch (boot_cpu_data.x86_model) { + case 42: /* SandyBridge */ + x86_pmu.pebs_constraints = intel_snb_pebs_events; + break; + default: + x86_pmu.pebs_constraints = intel_nehalem_pebs_events; + } break;Quoted 1 line
default:
We already have this massive model switch right after this function, might as well move the pebs constraint assignment there.
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Quoted 18 lines · Stephane Eranian
Quoted 17 lines · Lin Ming
Quoted 15 lines · Stephane Eranian
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.
Quoted 7 lines
Quoted 4 lines
Stephane,
I'll integrate below changes to the offcore patches, OK?
Let me try one more test on this.
I want to show the case the caused the problem in the first place.
There you go:
$ task -e offcore_response_0:DMND_DATA_RD:local_dram -e offcore_response_0:DMND_DATA_RD:local_dram noploop 1
Here the two instances of offcore_response are in two different event groups. I instrumented get/put percore constraint routines. get1 is where you do the first allocation, get2 is where you do ref++.
The scheduling algorithm will do:
- submit 1st group
- schedule 1st group
- submit 2nd group
- schedule 1st + 2nd group
Which results in the following trace:
[ 109.855713] CPU0 get1 cfg=1301b7 ref=1 [ 109.855717] CPU0 get2 cfg=1301b7 ref=2 [ 109.855718] CPU0 get2 cfg=1301b7 ref=3 <-- this one is bogus [ 109.856606] CPU0 put cfg=1301b7 ref=2 [ 109.856609] CPU0 put cfg=1301b7 ref=1 <- don't free the resource
[ 109.856616] CPU0 get2 cfg=1301b7 ref=2 [ 109.856619] CPU0 get2 cfg=1301b7 ref=3 [ 109.856622] CPU0 get2 cfg=1301b7 ref=4 [ 110.742151] CPU0 put cfg=1301b7 ref=3 [ 110.742154] CPU0 put cfg=1301b7 ref=2
[ 110.742160] CPU0 get2 cfg=1301b7 ref=3 [ 110.742161] CPU0 get2 cfg=1301b7 ref=4 [ 110.742163] CPU0 get2 cfg=1301b7 ref=5 [ 110.854448] CPU0 put cfg=1301b7 ref=4 [ 110.854450] CPU0 put cfg=1301b7 ref=3
Quoted 42 lines · Stephane Eranian
Quoted 18 lines · Stephane Eranian
Quoted 17 lines · Lin Ming
Quoted 15 lines · Stephane Eranian
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.Quoted 7 lines
Quoted 4 lines
Stephane,
I'll integrate below changes to the offcore patches, OK?
Let me try one more test on this.
I want to show the case the caused the problem in the first place.There you go:
$ task -e offcore_response_0:DMND_DATA_RD:local_dram -e offcore_response_0:DMND_DATA_RD:local_dram noploop 1Here the two instances of
offcore_responseare in two different event groups. I instrumented get/put percore constraint routines. get1 is where you do the first allocation, get2 is where you do ref++.The scheduling algorithm will do:
- submit 1st group
- schedule 1st group
- submit 2nd group
- schedule 1st + 2nd group
Quoted 7 lines
Which results in the following trace:
[ 109.855713] CPU0 get1 cfg=1301b7 ref=1 [ 109.855717] CPU0 get2 cfg=1301b7 ref=2 [ 109.855718] CPU0 get2 cfg=1301b7 ref=3 <-- this one is bogus [ 109.856606] CPU0 put cfg=1301b7 ref=2 [ 109.856609] CPU0 put cfg=1301b7 ref=1 <- don't free the resource
Do you mean the issue is still there even with your extra_alloc patch applied?
Quoted 12 lines
[ 109.856616] CPU0 get2 cfg=1301b7 ref=2 [ 109.856619] CPU0 get2 cfg=1301b7 ref=3 [ 109.856622] CPU0 get2 cfg=1301b7 ref=4 [ 110.742151] CPU0 put cfg=1301b7 ref=3 [ 110.742154] CPU0 put cfg=1301b7 ref=2[ 110.742160] CPU0 get2 cfg=1301b7 ref=3 [ 110.742161] CPU0 get2 cfg=1301b7 ref=4 [ 110.742163] CPU0 get2 cfg=1301b7 ref=5 [ 110.854448] CPU0 put cfg=1301b7 ref=4 [ 110.854450] CPU0 put cfg=1301b7 ref=3
Quoted 45 lines · Lin Ming
Quoted 44 lines · Stephane Eranian
Quoted 18 lines · Stephane Eranian
Quoted 17 lines · Lin Ming
Quoted 15 lines · Stephane Eranian
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.Quoted 7 lines
Quoted 4 lines
Stephane,
I'll integrate below changes to the offcore patches, OK?
Let me try one more test on this.
I want to show the case the caused the problem in the first place.There you go:
$ task -e offcore_response_0:DMND_DATA_RD:local_dram -e offcore_response_0:DMND_DATA_RD:local_dram noploop 1Here the two instances of
offcore_responseare in two different event groups. I instrumented get/put percore constraint routines. get1 is where you do the first allocation, get2 is where you do ref++.The scheduling algorithm will do:
- submit 1st group
- schedule 1st group
- submit 2nd group
- schedule 1st + 2nd groupWhich results in the following trace:
Quoted 9 lines
Quoted 5 lines
[ 109.855713] CPU0 get1 cfg=1301b7 ref=1
[ 109.855717] CPU0 get2 cfg=1301b7 ref=2
[ 109.855718] CPU0 get2 cfg=1301b7 ref=3 <-- this one is bogus [ 109.856606] CPU0 put cfg=1301b7 ref=2
[ 109.856609] CPU0 put cfg=1301b7 ref=1 <- don't free the resourceDo you mean the issue is still there even with your
extra_allocpatch applied?
No, I am showing you what happens without it.
If you try with it, it should work.
Quoted 15 lines
Quoted 12 lines
[ 109.856616] CPU0 get2 cfg=1301b7 ref=2
[ 109.856619] CPU0 get2 cfg=1301b7 ref=3
[ 109.856622] CPU0 get2 cfg=1301b7 ref=4
[ 110.742151] CPU0 put cfg=1301b7 ref=3
[ 110.742154] CPU0 put cfg=1301b7 ref=2[ 110.742160] CPU0 get2 cfg=1301b7 ref=3
[ 110.742161] CPU0 get2 cfg=1301b7 ref=4
[ 110.742163] CPU0 get2 cfg=1301b7 ref=5
[ 110.854448] CPU0 put cfg=1301b7 ref=4
[ 110.854450] CPU0 put cfg=1301b7 ref=3
Quoted 52 lines · Stephane Eranian
Quoted 51 lines · Lin Ming
Quoted 49 lines · Stephane Eranian
Quoted 18 lines · Stephane Eranian
Quoted 17 lines · Lin Ming
Quoted 15 lines · Stephane Eranian
Quoted 10 lines · Peter Zijlstra
Quoted 5 lines · Lin Ming
This patch adds basic SandyBridge support, including hardware cache events and PEBS events support.
LLC-* hareware cache events don't work for now, it depends on the offcore patches.
What's the status of those, Stephane reported some problems last I remember?
I tried the trick I mentioned and it seems to work.
Something like below with
hwc->extra_alloc.
Could probably find a better name for that field.Quoted 7 lines
Quoted 4 lines
Stephane,
I'll integrate below changes to the offcore patches, OK?
Let me try one more test on this.
I want to show the case the caused the problem in the first place.There you go:
$ task -e offcore_response_0:DMND_DATA_RD:local_dram -e offcore_response_0:DMND_DATA_RD:local_dram noploop 1Here the two instances of
offcore_responseare in two different event groups. I instrumented get/put percore constraint routines. get1 is where you do the first allocation, get2 is where you do ref++.The scheduling algorithm will do:
- submit 1st group
- schedule 1st group
- submit 2nd group
- schedule 1st + 2nd groupWhich results in the following trace:
[ 109.855713] CPU0 get1 cfg=1301b7 ref=1 [ 109.855717] CPU0 get2 cfg=1301b7 ref=2 [ 109.855718] CPU0 get2 cfg=1301b7 ref=3 <-- this one is bogus [ 109.856606] CPU0 put cfg=1301b7 ref=2 [ 109.856609] CPU0 put cfg=1301b7 ref=1 <- don't free the resource
Quoted 5 lines
Quoted 3 lines
Do you mean the issue is still there even with your
extra_allocpatch applied?No, I am showing you what happens without it.
If you try with it, it should work.
Got it. I'll send out a new version with all the fixes.
Thanks.
Quoted 16 lines
Quoted 16 lines
Quoted 13 lines
[ 109.856616] CPU0 get2 cfg=1301b7 ref=2 [ 109.856619] CPU0 get2 cfg=1301b7 ref=3 [ 109.856622] CPU0 get2 cfg=1301b7 ref=4 [ 110.742151] CPU0 put cfg=1301b7 ref=3 [ 110.742154] CPU0 put cfg=1301b7 ref=2[ 110.742160] CPU0 get2 cfg=1301b7 ref=3 [ 110.742161] CPU0 get2 cfg=1301b7 ref=4 [ 110.742163] CPU0 get2 cfg=1301b7 ref=5 [ 110.854448] CPU0 put cfg=1301b7 ref=4 [ 110.854450] CPU0 put cfg=1301b7 ref=3