1 // SPDX-License-Identifier: GPL-2.0
6 #include <linux/kernel.h>
7 #include <linux/types.h>
8 #include <linux/perf_event.h>
9 #include "util/evsel_fprintf.h"
11 #include "util/pmus.h"
12 #include "trace-event.h"
19 static void __p_bits(char *buf
, size_t size
, u64 value
, struct bit_names
*bits
)
21 bool first_bit
= true;
25 if (value
& bits
[i
].bit
) {
26 buf
+= scnprintf(buf
, size
, "%s%s", first_bit
? "" : "|", bits
[i
].name
);
29 } while (bits
[++i
].name
!= NULL
);
32 static void __p_sample_type(char *buf
, size_t size
, u64 value
)
34 #define bit_name(n) { PERF_SAMPLE_##n, #n }
35 struct bit_names bits
[] = {
36 bit_name(IP
), bit_name(TID
), bit_name(TIME
), bit_name(ADDR
),
37 bit_name(READ
), bit_name(CALLCHAIN
), bit_name(ID
), bit_name(CPU
),
38 bit_name(PERIOD
), bit_name(STREAM_ID
), bit_name(RAW
),
39 bit_name(BRANCH_STACK
), bit_name(REGS_USER
), bit_name(STACK_USER
),
40 bit_name(IDENTIFIER
), bit_name(REGS_INTR
), bit_name(DATA_SRC
),
41 bit_name(WEIGHT
), bit_name(PHYS_ADDR
), bit_name(AUX
),
42 bit_name(CGROUP
), bit_name(DATA_PAGE_SIZE
), bit_name(CODE_PAGE_SIZE
),
43 bit_name(WEIGHT_STRUCT
),
47 __p_bits(buf
, size
, value
, bits
);
50 static void __p_branch_sample_type(char *buf
, size_t size
, u64 value
)
52 #define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n }
53 struct bit_names bits
[] = {
54 bit_name(USER
), bit_name(KERNEL
), bit_name(HV
), bit_name(ANY
),
55 bit_name(ANY_CALL
), bit_name(ANY_RETURN
), bit_name(IND_CALL
),
56 bit_name(ABORT_TX
), bit_name(IN_TX
), bit_name(NO_TX
),
57 bit_name(COND
), bit_name(CALL_STACK
), bit_name(IND_JUMP
),
58 bit_name(CALL
), bit_name(NO_FLAGS
), bit_name(NO_CYCLES
),
59 bit_name(TYPE_SAVE
), bit_name(HW_INDEX
), bit_name(PRIV_SAVE
),
64 __p_bits(buf
, size
, value
, bits
);
67 static void __p_read_format(char *buf
, size_t size
, u64 value
)
69 #define bit_name(n) { PERF_FORMAT_##n, #n }
70 struct bit_names bits
[] = {
71 bit_name(TOTAL_TIME_ENABLED
), bit_name(TOTAL_TIME_RUNNING
),
72 bit_name(ID
), bit_name(GROUP
), bit_name(LOST
),
76 __p_bits(buf
, size
, value
, bits
);
79 #define ENUM_ID_TO_STR_CASE(x) case x: return (#x);
80 static const char *stringify_perf_type_id(struct perf_pmu
*pmu
, u32 type
)
86 ENUM_ID_TO_STR_CASE(PERF_TYPE_HARDWARE
)
87 ENUM_ID_TO_STR_CASE(PERF_TYPE_SOFTWARE
)
88 ENUM_ID_TO_STR_CASE(PERF_TYPE_TRACEPOINT
)
89 ENUM_ID_TO_STR_CASE(PERF_TYPE_HW_CACHE
)
90 ENUM_ID_TO_STR_CASE(PERF_TYPE_RAW
)
91 ENUM_ID_TO_STR_CASE(PERF_TYPE_BREAKPOINT
)
97 static const char *stringify_perf_hw_id(u64 value
)
100 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CPU_CYCLES
)
101 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_INSTRUCTIONS
)
102 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_REFERENCES
)
103 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_MISSES
)
104 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_BRANCH_INSTRUCTIONS
)
105 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_BRANCH_MISSES
)
106 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_BUS_CYCLES
)
107 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
)
108 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_STALLED_CYCLES_BACKEND
)
109 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_REF_CPU_CYCLES
)
115 static const char *stringify_perf_hw_cache_id(u64 value
)
118 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_L1D
)
119 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_L1I
)
120 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_LL
)
121 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_DTLB
)
122 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_ITLB
)
123 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_BPU
)
124 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_NODE
)
130 static const char *stringify_perf_hw_cache_op_id(u64 value
)
133 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_OP_READ
)
134 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_OP_WRITE
)
135 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_OP_PREFETCH
)
141 static const char *stringify_perf_hw_cache_op_result_id(u64 value
)
144 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_RESULT_ACCESS
)
145 ENUM_ID_TO_STR_CASE(PERF_COUNT_HW_CACHE_RESULT_MISS
)
151 static const char *stringify_perf_sw_id(u64 value
)
154 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_CPU_CLOCK
)
155 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_TASK_CLOCK
)
156 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_PAGE_FAULTS
)
157 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_CONTEXT_SWITCHES
)
158 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_CPU_MIGRATIONS
)
159 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_PAGE_FAULTS_MIN
)
160 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_PAGE_FAULTS_MAJ
)
161 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_ALIGNMENT_FAULTS
)
162 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_EMULATION_FAULTS
)
163 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_DUMMY
)
164 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_BPF_OUTPUT
)
165 ENUM_ID_TO_STR_CASE(PERF_COUNT_SW_CGROUP_SWITCHES
)
170 #undef ENUM_ID_TO_STR_CASE
172 #define PRINT_ID(_s, _f) \
174 const char *__s = _s; \
176 snprintf(buf, size, _f, value); \
178 snprintf(buf, size, _f" (%s)", value, __s); \
180 #define print_id_unsigned(_s) PRINT_ID(_s, "%"PRIu64)
181 #define print_id_hex(_s) PRINT_ID(_s, "%#"PRIx64)
183 static void __p_type_id(struct perf_pmu
*pmu
, char *buf
, size_t size
, u64 value
)
185 print_id_unsigned(stringify_perf_type_id(pmu
, value
));
188 static void __p_config_hw_id(char *buf
, size_t size
, u64 value
)
190 print_id_hex(stringify_perf_hw_id(value
));
193 static void __p_config_sw_id(char *buf
, size_t size
, u64 value
)
195 print_id_hex(stringify_perf_sw_id(value
));
198 static void __p_config_hw_cache_id(char *buf
, size_t size
, u64 value
)
200 const char *hw_cache_str
= stringify_perf_hw_cache_id(value
& 0xff);
201 const char *hw_cache_op_str
=
202 stringify_perf_hw_cache_op_id((value
& 0xff00) >> 8);
203 const char *hw_cache_op_result_str
=
204 stringify_perf_hw_cache_op_result_id((value
& 0xff0000) >> 16);
206 if (hw_cache_str
== NULL
|| hw_cache_op_str
== NULL
||
207 hw_cache_op_result_str
== NULL
) {
208 snprintf(buf
, size
, "%#"PRIx64
, value
);
210 snprintf(buf
, size
, "%#"PRIx64
" (%s | %s | %s)", value
,
211 hw_cache_op_result_str
, hw_cache_op_str
, hw_cache_str
);
215 #ifdef HAVE_LIBTRACEEVENT
216 static void __p_config_tracepoint_id(char *buf
, size_t size
, u64 value
)
218 char *str
= tracepoint_id_to_name(value
);
225 static void __p_config_id(struct perf_pmu
*pmu
, char *buf
, size_t size
, u32 type
, u64 value
)
227 const char *name
= perf_pmu__name_from_config(pmu
, value
);
234 case PERF_TYPE_HARDWARE
:
235 return __p_config_hw_id(buf
, size
, value
);
236 case PERF_TYPE_SOFTWARE
:
237 return __p_config_sw_id(buf
, size
, value
);
238 case PERF_TYPE_HW_CACHE
:
239 return __p_config_hw_cache_id(buf
, size
, value
);
240 case PERF_TYPE_TRACEPOINT
:
241 #ifdef HAVE_LIBTRACEEVENT
242 return __p_config_tracepoint_id(buf
, size
, value
);
245 case PERF_TYPE_BREAKPOINT
:
247 snprintf(buf
, size
, "%#"PRIx64
, value
);
252 #define BUF_SIZE 1024
254 #define p_hex(val) snprintf(buf, BUF_SIZE, "%#"PRIx64, (uint64_t)(val))
255 #define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val))
256 #define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val))
257 #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val)
258 #define p_branch_sample_type(val) __p_branch_sample_type(buf, BUF_SIZE, val)
259 #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val)
260 #define p_type_id(val) __p_type_id(pmu, buf, BUF_SIZE, val)
261 #define p_config_id(val) __p_config_id(pmu, buf, BUF_SIZE, attr->type, val)
263 #define PRINT_ATTRn(_n, _f, _p, _a) \
265 if (_a || attr->_f) { \
267 ret += attr__fprintf(fp, _n, buf, priv);\
271 #define PRINT_ATTRf(_f, _p) PRINT_ATTRn(#_f, _f, _p, false)
273 int perf_event_attr__fprintf(FILE *fp
, struct perf_event_attr
*attr
,
274 attr__fprintf_f attr__fprintf
, void *priv
)
276 struct perf_pmu
*pmu
= perf_pmus__find_by_type(attr
->type
);
280 PRINT_ATTRn("type", type
, p_type_id
, true);
281 PRINT_ATTRf(size
, p_unsigned
);
282 PRINT_ATTRn("config", config
, p_config_id
, true);
283 PRINT_ATTRn("{ sample_period, sample_freq }", sample_period
, p_unsigned
, false);
284 PRINT_ATTRf(sample_type
, p_sample_type
);
285 PRINT_ATTRf(read_format
, p_read_format
);
287 PRINT_ATTRf(disabled
, p_unsigned
);
288 PRINT_ATTRf(inherit
, p_unsigned
);
289 PRINT_ATTRf(pinned
, p_unsigned
);
290 PRINT_ATTRf(exclusive
, p_unsigned
);
291 PRINT_ATTRf(exclude_user
, p_unsigned
);
292 PRINT_ATTRf(exclude_kernel
, p_unsigned
);
293 PRINT_ATTRf(exclude_hv
, p_unsigned
);
294 PRINT_ATTRf(exclude_idle
, p_unsigned
);
295 PRINT_ATTRf(mmap
, p_unsigned
);
296 PRINT_ATTRf(comm
, p_unsigned
);
297 PRINT_ATTRf(freq
, p_unsigned
);
298 PRINT_ATTRf(inherit_stat
, p_unsigned
);
299 PRINT_ATTRf(enable_on_exec
, p_unsigned
);
300 PRINT_ATTRf(task
, p_unsigned
);
301 PRINT_ATTRf(watermark
, p_unsigned
);
302 PRINT_ATTRf(precise_ip
, p_unsigned
);
303 PRINT_ATTRf(mmap_data
, p_unsigned
);
304 PRINT_ATTRf(sample_id_all
, p_unsigned
);
305 PRINT_ATTRf(exclude_host
, p_unsigned
);
306 PRINT_ATTRf(exclude_guest
, p_unsigned
);
307 PRINT_ATTRf(exclude_callchain_kernel
, p_unsigned
);
308 PRINT_ATTRf(exclude_callchain_user
, p_unsigned
);
309 PRINT_ATTRf(mmap2
, p_unsigned
);
310 PRINT_ATTRf(comm_exec
, p_unsigned
);
311 PRINT_ATTRf(use_clockid
, p_unsigned
);
312 PRINT_ATTRf(context_switch
, p_unsigned
);
313 PRINT_ATTRf(write_backward
, p_unsigned
);
314 PRINT_ATTRf(namespaces
, p_unsigned
);
315 PRINT_ATTRf(ksymbol
, p_unsigned
);
316 PRINT_ATTRf(bpf_event
, p_unsigned
);
317 PRINT_ATTRf(aux_output
, p_unsigned
);
318 PRINT_ATTRf(cgroup
, p_unsigned
);
319 PRINT_ATTRf(text_poke
, p_unsigned
);
320 PRINT_ATTRf(build_id
, p_unsigned
);
321 PRINT_ATTRf(inherit_thread
, p_unsigned
);
322 PRINT_ATTRf(remove_on_exec
, p_unsigned
);
323 PRINT_ATTRf(sigtrap
, p_unsigned
);
325 PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events
, p_unsigned
, false);
326 PRINT_ATTRf(bp_type
, p_unsigned
);
327 PRINT_ATTRn("{ bp_addr, config1 }", bp_addr
, p_hex
, false);
328 PRINT_ATTRn("{ bp_len, config2 }", bp_len
, p_hex
, false);
329 PRINT_ATTRf(branch_sample_type
, p_branch_sample_type
);
330 PRINT_ATTRf(sample_regs_user
, p_hex
);
331 PRINT_ATTRf(sample_stack_user
, p_unsigned
);
332 PRINT_ATTRf(clockid
, p_signed
);
333 PRINT_ATTRf(sample_regs_intr
, p_hex
);
334 PRINT_ATTRf(aux_watermark
, p_unsigned
);
335 PRINT_ATTRf(sample_max_stack
, p_unsigned
);
336 PRINT_ATTRf(aux_sample_size
, p_unsigned
);
337 PRINT_ATTRf(sig_data
, p_unsigned
);