summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Syromyatnikov <evgsyr@gmail.com>2021-06-29 04:59:10 +0200
committerDmitry V. Levin <ldv@strace.io>2021-06-30 09:52:37 +0000
commit8c220966546642102e784acb992a1346f750dc76 (patch)
tree48f9642fdff909810e1b82495c1344b2a7c73936
parent6fc2892f702e4fbc4020738cb6f8378afe325309 (diff)
downloadstrace-8c220966546642102e784acb992a1346f750dc76.tar.gz
perf: extended PERF_TYPE_HARDWARE/PERF_TYPE_HW_CACHE config decoding
Introduced in Linux commit v5.13-rc1~119^2~7. * src/perf.c (print_perf_event_attr) <case PERF_TYPE_HARDWARE>: Decode extended PMU tupe separately. <case PERF_TYPE_HW_CACHE>: Decode extended PMU type separatel, reorder the rest of the fields. * src/perf_event_struct.h (PERF_PMU_TYPE_SHIFT, PERF_HW_EVENT_MASK): New macros. * tests/perf_event_open.c:Update expected output.
-rw-r--r--src/perf.c59
-rw-r--r--src/perf_event_struct.h3
-rw-r--r--tests/perf_event_open.c20
3 files changed, 42 insertions, 40 deletions
diff --git a/src/perf.c b/src/perf.c
index 01badde1d..a4780b205 100644
--- a/src/perf.c
+++ b/src/perf.c
@@ -150,9 +150,18 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
switch (attr->type) {
case PERF_TYPE_HARDWARE:
+ /*
+ * EEEEEEEE000000AA
+ * EEEEEEEE - PMU type ID
+ * AA - perf_hw_id
+ */
tprint_struct_next();
- PRINT_FIELD_XVAL(*attr, config, perf_hw_id,
- "PERF_COUNT_HW_???");
+ tprints_field_name("config");
+ if (attr->config >> 32) {
+ tprintf("%#" PRIx64 "<<32|", attr->config >> 32);
+ }
+ printxval(perf_hw_id, attr->config & PERF_HW_EVENT_MASK,
+ "PERF_COUNT_HW_???");
break;
case PERF_TYPE_SOFTWARE:
tprint_struct_next();
@@ -170,40 +179,30 @@ print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
break;
case PERF_TYPE_HW_CACHE:
/*
- * (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) |
- * (perf_hw_cache_op_result_id << 16)
+ * EEEEEEEE00DDCCBB
+ * EEEEEEEE - PMU type ID
+ * BB - perf_hw_cache_id
+ * CC - perf_hw_cache_op_id
+ * DD - perf_hw_cache_op_result_id
*/
tprint_struct_next();
tprints_field_name("config");
- printxval(perf_hw_cache_id, attr->config & 0xFF,
- "PERF_COUNT_HW_CACHE_???");
- tprints("|");
- printxval(perf_hw_cache_op_id, (attr->config >> 8) & 0xFF,
- "PERF_COUNT_HW_CACHE_OP_???");
- tprints("<<8|");
- /*
- * Current code (see set_ext_hw_attr in arch/x86/events/core.c,
- * tile_map_cache_event in arch/tile/kernel/perf_event.c,
- * arc_pmu_cache_event in arch/arc/kernel/perf_event.c,
- * hw_perf_cache_event in arch/blackfin/kernel/perf_event.c,
- * _hw_perf_cache_event in arch/metag/kernel/perf/perf_event.c,
- * mipspmu_map_cache_event in arch/mips/kernel/perf_event_mipsxx.c,
- * hw_perf_cache_event in arch/powerpc/perf/core-book3s.c,
- * hw_perf_cache_event in arch/powerpc/perf/core-fsl-emb.c,
- * hw_perf_cache_event in arch/sh/kernel/perf_event.c,
- * sparc_map_cache_event in arch/sparc/kernel/perf_event.c,
- * xtensa_pmu_cache_event in arch/xtensa/kernel/perf_event.c,
- * armpmu_map_cache_event in drivers/perf/arm_pmu.c) assumes
- * that cache result is 8 bits in size.
- */
+ if (attr->config >> 32){
+ tprintf("%#" PRIx64 "<<32|", attr->config >> 32);
+ }
+ if ((attr->config & PERF_HW_EVENT_MASK) >> 24) {
+ tprintf("%#" PRIx64 "<<24|",
+ (attr->config & PERF_HW_EVENT_MASK) >> 24);
+ }
printxval(perf_hw_cache_op_result_id,
(attr->config >> 16) & 0xFF,
"PERF_COUNT_HW_CACHE_RESULT_???");
- tprints("<<16");
- if (attr->config >> 24) {
- tprintf("|%#" PRIx64 "<<24", attr->config >> 24);
- tprints_comment("PERF_COUNT_HW_CACHE_???");
- }
+ tprints("<<16|");
+ printxval(perf_hw_cache_op_id, (attr->config >> 8) & 0xFF,
+ "PERF_COUNT_HW_CACHE_OP_???");
+ tprints("<<8|");
+ printxval(perf_hw_cache_id, attr->config & 0xFF,
+ "PERF_COUNT_HW_CACHE_???");
break;
case PERF_TYPE_RAW:
/*
diff --git a/src/perf_event_struct.h b/src/perf_event_struct.h
index 4ab716599..22e379b1b 100644
--- a/src/perf_event_struct.h
+++ b/src/perf_event_struct.h
@@ -11,6 +11,9 @@
# include <stdint.h>
+#define PERF_PMU_TYPE_SHIFT 32
+#define PERF_HW_EVENT_MASK 0xffffffff
+
struct perf_event_attr {
uint32_t type;
uint32_t size;
diff --git a/tests/perf_event_open.c b/tests/perf_event_open.c
index ba5e22695..b83a52b20 100644
--- a/tests/perf_event_open.c
+++ b/tests/perf_event_open.c
@@ -512,8 +512,8 @@ main(void)
/* PERF_TYPE_HARDWARE */ {
{ 9, "PERF_COUNT_HW_REF_CPU_CYCLES" },
{ 10, "0xa /* PERF_COUNT_HW_??? */" },
- { ARG_ULL_STR(0xfaceca75deadb0d4)
- " /* PERF_COUNT_HW_??? */" },
+ { 0xfaceca7500000004, "0xfaceca75<<32|"
+ "PERF_COUNT_HW_BRANCH_INSTRUCTIONS" },
},
/* PERF_TYPE_SOFTWARE */ {
{ 11, "PERF_COUNT_SW_CGROUP_SWITCHES" },
@@ -527,17 +527,17 @@ main(void)
{ ARG_ULL_STR(16051074073505095380) },
},
/* PERF_TYPE_HW_CACHE */ {
- { 0, "PERF_COUNT_HW_CACHE_L1D|"
+ { 0, "PERF_COUNT_HW_CACHE_RESULT_ACCESS<<16|"
"PERF_COUNT_HW_CACHE_OP_READ<<8|"
- "PERF_COUNT_HW_CACHE_RESULT_ACCESS<<16" },
- { 0x020207, "0x7 /* PERF_COUNT_HW_CACHE_??? */|"
+ "PERF_COUNT_HW_CACHE_L1D" },
+ { 0x01020207, "0x1<<24|"
+ "0x2 /* PERF_COUNT_HW_CACHE_RESULT_??? */<<16|"
"PERF_COUNT_HW_CACHE_OP_PREFETCH<<8|"
- "0x2 /* PERF_COUNT_HW_CACHE_RESULT_??? */<<16" },
- { 0xdeadf157ed010306ULL, "PERF_COUNT_HW_CACHE_NODE|"
- "0x3 /* PERF_COUNT_HW_CACHE_OP_??? */<<8|"
+ "0x7 /* PERF_COUNT_HW_CACHE_??? */" },
+ { 0xdeadf15700010306ULL, "0xdeadf157<<32|"
"PERF_COUNT_HW_CACHE_RESULT_MISS<<16|"
- "0xdeadf157ed<<24 "
- "/* PERF_COUNT_HW_CACHE_??? */" },
+ "0x3 /* PERF_COUNT_HW_CACHE_OP_??? */<<8|"
+ "PERF_COUNT_HW_CACHE_NODE" },
},
/* PERF_TYPE_RAW */ {
{ ARG_STR(0) },