2 * Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include <linux/perf_event.h>
10 #include <perfmon/perf_event.h>
11 #include <perfmon/pfmlib_perf_event.h>
15 int main(int argc
, char **argv
)
19 /* pfm query objects */
20 pfm_perf_encode_arg_t pencoder
;
21 pfm_event_info_t info
;
23 /* Perf event object to be populated by libpfm */
24 struct perf_event_attr attr
;
28 "Usage: %s <pmu counter to find>\n"
29 "ex: %s UNHALTED_REFERENCE_CYCLES\n"
30 "Returns the event raw number if found and actionable with"
32 "If not found returns 1,"
33 "If not actionable return 2,"
34 "on error returns 255\n",
41 /* Initialize perf_event_attr. */
42 memset(&attr
, 0, sizeof(struct perf_event_attr
));
44 /* Initialize libpfm encoder structure. */
45 memset(&pencoder
, 0, sizeof(pencoder
));
46 pencoder
.size
= sizeof(pfm_perf_encode_arg_t
);
48 /* Initialize libpfm event info structure. */
49 memset(&info
, 0, sizeof(info
));
50 info
.size
= sizeof(info
);
52 /* Prepare the encoder for query. */
53 pencoder
.attr
= &attr
; /* Set the perf_event_attr pointer. */
54 pencoder
.fstr
= NULL
; /* Not interested by the fully qualified event string. */
56 ret
= pfm_initialize();
57 if (ret
!= PFM_SUCCESS
) {
58 fprintf(stderr
, "Failed to initialise libpfm: %s", pfm_strerror(ret
));
63 ret
= pfm_get_os_event_encoding(
64 argv
[1], PFM_PLM0
| PFM_PLM1
| PFM_PLM2
| PFM_PLM3
, PFM_OS_PERF_EVENT
, &pencoder
);
65 if (ret
!= PFM_SUCCESS
) {
66 fprintf(stderr
, "libpfm: error pfm_get_os_event_encoding: %s\n", pfm_strerror(ret
));
72 * Query the raw code for later use. Do it now to simplify error
75 ret
= pfm_get_event_info(pencoder
.idx
, PFM_OS_NONE
, &info
);
76 if (ret
!= PFM_SUCCESS
) {
77 fprintf(stderr
, "libpfm: error pfm_get_event_info: %s\n", pfm_strerror(ret
));
83 * Now that the event is found, try to use it to validate that
84 * the current user has access to it and that it can be used on that
88 /* Set the event to disabled to prevent unnecessary side effects. */
89 pencoder
.attr
->disabled
= 1;
91 /* perf_event_open is provided by perfmon/perf_event.h. */
92 fd
= perf_event_open(pencoder
.attr
, 0, -1, -1, 0);
94 fprintf(stderr
, "perf: error perf_event_open: %d: %s\n", errno
, strerror(errno
));
99 /* We close the fd immediately since the event is actionable. */
102 /* Output the raw code for the event */
103 fprintf(stdout
, "r%" PRIx64
"\n", info
.code
);