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
42084208 skl_format_attr);
42094209 WARN_ON(!x86_pmu.format_attrs);
42104210 x86_pmu.cpu_events = hsw_events_attrs;
4211+ intel_pmu_pebs_data_source_skl(
4212+ boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X);
42114213 pr_cont("Skylake events, ");
42124214 break;
42134215
arch/x86/events/intel/ds.c+32−19
@@ -49,34 +49,47 @@ union intel_x86_pebs_dse { · 48 unmodified lines
4949 */
5050 #define P(a, b) PERF_MEM_S(a, b)
5151 #define OP_LH (P(OP, LOAD) | P(LVL, HIT))
52+#define LEVEL(x) P(LVLNUM, x)
53+#define REM P(REMOTE, REMOTE)
5254 #define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS))
5355
5456 /* Version for Sandy Bridge and later */
5557 static u64 pebs_data_source[] = {
56− P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
57− OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */
58− OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
59− OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */
60− OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */
61− OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */
62− OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */
63− OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */
64− OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */
65− OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
66− OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */
67− OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */
68− OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */
69− OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */
70− OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */
71− OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */
58+ P(OP, LOAD) | P(LVL, MISS) | LEVEL(L3) | P(SNOOP, NA),/* 0x00:ukn L3 */
59+ OP_LH | P(LVL, L1) | LEVEL(L1) | P(SNOOP, NONE), /* 0x01: L1 local */
60+ OP_LH | P(LVL, LFB) | LEVEL(LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */
61+ OP_LH | P(LVL, L2) | LEVEL(L2) | P(SNOOP, NONE), /* 0x03: L2 hit */
62+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, NONE), /* 0x04: L3 hit */
63+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */
64+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */
65+ OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */
66+ OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */
67+ OP_LH | P(LVL, REM_CCE1) | REM | LEVEL(L3) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/
68+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */
69+ OP_LH | P(LVL, REM_RAM1) | REM | LEVEL(L3) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */
70+ OP_LH | P(LVL, LOC_RAM) | LEVEL(RAM) | SNOOP_NONE_MISS, /* 0x0c: L3 miss, excl */
71+ OP_LH | P(LVL, REM_RAM1) | LEVEL(RAM) | REM | SNOOP_NONE_MISS, /* 0x0d: L3 miss, excl */
72+ OP_LH | P(LVL, IO) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0e: I/O */
73+ OP_LH | P(LVL, UNC) | LEVEL(NA) | P(SNOOP, NONE), /* 0x0f: uncached */
7274 };
7375
7476 /* Patch up minor differences in the bits */
7577 void __init intel_pmu_pebs_data_source_nhm(void)
7678 {
77− pebs_data_source[0x05] = OP_LH | P(LVL, L3) | P(SNOOP, HIT);
78− pebs_data_source[0x06] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
79− pebs_data_source[0x07] = OP_LH | P(LVL, L3) | P(SNOOP, HITM);
79+ pebs_data_source[0x05] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HIT);
80+ pebs_data_source[0x06] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM);
81+ pebs_data_source[0x07] = OP_LH | P(LVL, L3) | LEVEL(L3) | P(SNOOP, HITM);
82+}
83+
84+void __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);
8093 }
8194
8295 static 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
948948
949949 void intel_pmu_pebs_data_source_nhm(void);
950950
951+void intel_pmu_pebs_data_source_skl(bool pmem);
952+
951953 int intel_pmu_setup_lbr_filter(struct perf_event *event);
952954
953955 void intel_pt_interrupt(void);
include/uapi/linux/perf_event.h+28−2
@@ -954,14 +954,20 @@ union perf_mem_data_src { · 953 unmodified lines
954954 mem_snoop:5, /* snoop mode */
955955 mem_lock:2, /* lock instr */
956956 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;
958961 };
959962 };
960963 #elif defined(__BIG_ENDIAN_BITFIELD)
961964 union perf_mem_data_src {
962965 __u64 val;
963966 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 */
965971 mem_dtlb:7, /* tlb access */
966972 mem_lock:2, /* lock instr */
967973 mem_snoop:5, /* snoop mode */
@@ -998,6 +1004,22 @@ union perf_mem_data_src { · 30 unmodified lines
9981004 #define PERF_MEM_LVL_UNC 0x2000 /* Uncached memory */
9991005 #define PERF_MEM_LVL_SHIFT 5
10001006
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+
10011023 /* snoop mode */
10021024 #define PERF_MEM_SNOOP_NA 0x01 /* not available */
10031025 #define PERF_MEM_SNOOP_NONE 0x02 /* no snoop */
@@ -1006,6 +1028,10 @@ union perf_mem_data_src { · 2 unmodified lines
10061028 #define PERF_MEM_SNOOP_HITM 0x10 /* snoop hit modified */
10071029 #define PERF_MEM_SNOOP_SHIFT 19
10081030
1031+#define PERF_MEM_SNOOPX_FWD 0x01 /* forward */
1032+/* 1 free */
1033+#define PERF_MEM_SNOOPX_SHIFT 37
1034+
10091035 /* locked instruction */
10101036 #define PERF_MEM_LOCK_NA 0x01 /* not available */
10111037 #define PERF_MEM_LOCK_LOCKED 0x02 /* locked transaction */