History

perf/x86: Fix data source decoding for Skylake

Skylake changed the encoding of the PEBS data source field. Some combinations are not available anymore, but some new cases e.g. for L4 cache hit are added. Fix up the conversion table for Skylake, similar as had been done for Nehalem. On Skylake server the encoding for L4 actually means persistent memory. Handle this case too. To properly describe it in the abstracted perf format I had to add some new fields. Since a hit can have only one level add a new field that is an enumeration, not a bit field to describe the level. It can describe any level. Some numbers are also used to describe PMEM and LFB. Also add a new generic remote flag that can be combined with the generic level to signify a remote cache. And there is an extension field for the snoop indication to handle the Forward state. I didn't add a generic flag for hops because it's not needed for Skylake. I changed the existing encodings for older CPUs to also fill in the new level and remote fields.

Andi Kleen committed 9 years ago

Commit 6ae5fa61 parent 95298354 files · +64 −21Browse files

Unified · Split

4 files
  1. arch/x86/events/intel/core.c +2 −0
  2. arch/x86/events/intel/ds.c +32 −19
  3. arch/x86/events/perf_event.h +2 −0
  4. include/uapi/linux/perf_event.h +28 −2
arch/x86/events/intel/core.c+2−0
@@ -4208,6 +4208,8 @@ __init int intel_pmu_init(void) · 4207 unmodified lines
4208 skl_format_attr);4208 skl_format_attr);
4209 WARN_ON(!x86_pmu.format_attrs);4209 WARN_ON(!x86_pmu.format_attrs);
4210 x86_pmu.cpu_events = hsw_events_attrs;4210 x86_pmu.cpu_events = hsw_events_attrs;
4211 intel_pmu_pebs_data_source_skl(
4212 boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X);
4211 pr_cont("Skylake events, ");4213 pr_cont("Skylake events, ");
4212 break;4214 break;
4213 4215
arch/x86/events/intel/ds.c+32−19
@@ -49,34 +49,47 @@ union intel_x86_pebs_dse { · 48 unmodified lines
49 */49 */
50#define P(a, b) PERF_MEM_S(a, b)50#define P(a, b) PERF_MEM_S(a, b)
51#define OP_LH (P(OP, LOAD) | P(LVL, HIT))51#define OP_LH (P(OP, LOAD) | P(LVL, HIT))
52#define LEVEL(x) P(LVLNUM, x)
53#define REM P(REMOTE, REMOTE)
52#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))54#define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
53 55
54/* Version for Sandy Bridge and later */56/* Version for Sandy Bridge and later */
55static u64 pebs_data_source[] = {57static u64 pebs_data_source[] = {
56 P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */58 P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
57 OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */59 OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 local */
58 OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */60 OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
59 OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */61 OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x03: L2 hit */
60 OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */62 OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* 0x04: L3 hit */
61 OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */63 OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */
62 OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */64 OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */
63 OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */65 OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */
64 OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */66 OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */
65 OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/67 OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
66 OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */68 OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */
67 OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */69 OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */
68 OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */70 OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* 0x0c: L3 miss, excl */
69 OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */71 OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* 0x0d: L3 miss, excl */
70 OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */72 OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0e: I/O */
71 OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */73 OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */
72};74};
73 75
74/* Patch up minor differences in the bits */76/* Patch up minor differences in the bits */
75void __init intel_pmu_pebs_data_source_nhm(void)77void __init intel_pmu_pebs_data_source_nhm(void)
76{78{
77 pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT);79 pebs_data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT);
78 pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);80 pebs_data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM);
79 pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);81 pebs_data_source[0x07] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM);
82}
83
84void __init intel_pmu_pebs_data_source_skl(bool pmem)
85{
86 u64 pmem_or_l4 = pmem ? LEVEL(PMEM) : LEVEL(L4);
87
88 pebs_data_source[0x08] = OP_LH | pmem_or_l4 | P(SNOOP, HIT);
89 pebs_data_source[0x09] = OP_LH | pmem_or_l4 | REM | P(SNOOP, HIT);
90 pebs_data_source[0x0b] = OP_LH | LEVEL(RAM) | REM | P(SNOOP, NONE);
91 pebs_data_source[0x0c] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOPX, FWD);
92 pebs_data_source[0x0d] = OP_LH | LEVEL(ANY_CACHE) | REM | P(SNOOP, HITM);
80}93}
81 94
82static u64 precise_store_data(u64 status)95static u64 precise_store_data(u64 status)
arch/x86/events/perf_event.h+2−0
@@ -948,6 +948,8 @@ void intel_pmu_lbr_init_knl(void); · 947 unmodified lines
948 948
949void intel_pmu_pebs_data_source_nhm(void);949void intel_pmu_pebs_data_source_nhm(void);
950 950
951void intel_pmu_pebs_data_source_skl(bool pmem);
952
951int intel_pmu_setup_lbr_filter(struct perf_event *event);953int intel_pmu_setup_lbr_filter(struct perf_event *event);
952 954
953void intel_pt_interrupt(void);955void intel_pt_interrupt(void);
include/uapi/linux/perf_event.h+28−2
@@ -954,14 +954,20 @@ union perf_mem_data_src { · 953 unmodified lines
954 mem_snoop:5, /* snoop mode */954 mem_snoop:5, /* snoop mode */
955 mem_lock:2, /* lock instr */955 mem_lock:2, /* lock instr */
956 mem_dtlb:7, /* tlb access */956 mem_dtlb:7, /* tlb access */
957 mem_rsvd:31;957 mem_lvl_num:4, /* memory hierarchy level number */
958 mem_remote:1, /* remote */
959 mem_snoopx:2, /* snoop mode, ext */
960 mem_rsvd:24;
958 };961 };
959};962};
960#elif defined(__BIG_ENDIAN_BITFIELD)963#elif defined(__BIG_ENDIAN_BITFIELD)
961union perf_mem_data_src {964union perf_mem_data_src {
962 __u64 val;965 __u64 val;
963 struct {966 struct {
964 __u64 mem_rsvd:31,967 __u64 mem_rsvd:24,
968 mem_snoopx:2, /* snoop mode, ext */
969 mem_remote:1, /* remote */
970 mem_lvl_num:4, /* memory hierarchy level number */
965 mem_dtlb:7, /* tlb access */971 mem_dtlb:7, /* tlb access */
966 mem_lock:2, /* lock instr */972 mem_lock:2, /* lock instr */
967 mem_snoop:5, /* snoop mode */973 mem_snoop:5, /* snoop mode */
@@ -998,6 +1004,22 @@ union perf_mem_data_src { · 30 unmodified lines
998#define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */1004#define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */
999#define PERF_MEM_LVL_SHIFT 51005#define PERF_MEM_LVL_SHIFT 5
1000 1006
1007#define PERF_MEM_REMOTE_REMOTE 0x01 /* Remote */
1008#define PERF_MEM_REMOTE_SHIFT 37
1009
1010#define PERF_MEM_LVLNUM_L1 0x01 /* L1 */
1011#define PERF_MEM_LVLNUM_L2 0x02 /* L2 */
1012#define PERF_MEM_LVLNUM_L3 0x03 /* L3 */
1013#define PERF_MEM_LVLNUM_L4 0x04 /* L4 */
1014/* 5-0xa available */
1015#define PERF_MEM_LVLNUM_ANY_CACHE 0x0b /* Any cache */
1016#define PERF_MEM_LVLNUM_LFB 0x0c /* LFB */
1017#define PERF_MEM_LVLNUM_RAM 0x0d /* RAM */
1018#define PERF_MEM_LVLNUM_PMEM 0x0e /* PMEM */
1019#define PERF_MEM_LVLNUM_NA 0x0f /* N/A */
1020
1021#define PERF_MEM_LVLNUM_SHIFT 33
1022
1001/* snoop mode */1023/* snoop mode */
1002#define PERF_MEM_SNOOP_NA 0x01 /* not available */1024#define PERF_MEM_SNOOP_NA 0x01 /* not available */
1003#define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */1025#define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */
@@ -1006,6 +1028,10 @@ union perf_mem_data_src { · 2 unmodified lines
1006#define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */1028#define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */
1007#define PERF_MEM_SNOOP_SHIFT 191029#define PERF_MEM_SNOOP_SHIFT 19
1008 1030
1031#define PERF_MEM_SNOOPX_FWD 0x01 /* forward */
1032/* 1 free */
1033#define PERF_MEM_SNOOPX_SHIFT 37
1034
1009/* locked instruction */1035/* locked instruction */
1010#define PERF_MEM_LOCK_NA 0x01 /* not available */1036#define PERF_MEM_LOCK_NA 0x01 /* not available */
1011#define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */1037#define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */