2 * Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
12 #include <linux/perf_event.h>
13 #include <perfmon/perf_event.h>
14 #include <perfmon/pfmlib_perf_event.h>
16 int main(int argc
, char **argv
)
20 /* pfm query objects */
21 pfm_perf_encode_arg_t pencoder
;
22 pfm_event_info_t info
;
24 /* Perf event object to be populated by libpfm */
25 struct perf_event_attr attr
;
28 fprintf(stderr
, "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",
40 /* Initialize perf_event_attr. */
41 memset(&attr
, 0, sizeof(struct perf_event_attr
));
43 /* Initialize libpfm encoder structure. */
44 memset(&pencoder
, 0, sizeof(pencoder
));
45 pencoder
.size
= sizeof(pfm_perf_encode_arg_t
);
47 /* Initialize libpfm event info structure. */
48 memset(&info
, 0, sizeof(info
));
49 info
.size
= sizeof(info
);
51 /* Prepare the encoder for query. */
52 pencoder
.attr
= &attr
; /* Set the perf_event_attr pointer. */
53 pencoder
.fstr
= NULL
; /* Not interested by the fully qualified event string. */
55 ret
= pfm_initialize();
56 if (ret
!= PFM_SUCCESS
) {
57 fprintf(stderr
, "Failed to initialise libpfm: %s",
63 ret
= pfm_get_os_event_encoding(argv
[1],
64 PFM_PLM0
| PFM_PLM1
| PFM_PLM2
| PFM_PLM3
,
65 PFM_OS_PERF_EVENT
, &pencoder
);
66 if (ret
!= PFM_SUCCESS
) {
67 fprintf(stderr
, "libpfm: error pfm_get_os_event_encoding: %s\n",
74 * Query the raw code for later use. Do it now to simplify error
77 ret
= pfm_get_event_info(pencoder
.idx
, PFM_OS_NONE
, &info
);
78 if (ret
!= PFM_SUCCESS
) {
79 fprintf(stderr
, "libpfm: error pfm_get_event_info: %s\n", pfm_strerror(ret
));
85 * Now that the event is found, try to use it to validate that
86 * the current user has access to it and that it can be used on that
90 /* Set the event to disabled to prevent unnecessary side effects. */
91 pencoder
.attr
->disabled
= 1;
93 /* perf_event_open is provided by perfmon/perf_event.h. */
94 fd
= perf_event_open(pencoder
.attr
, 0, -1, -1, 0);
96 fprintf(stderr
, "perf: error perf_event_open: %d: %s\n", errno
,
102 /* We close the fd immediately since the event is actionable. */
105 /* Output the raw code for the event */
106 fprintf(stdout
, "r%" PRIx64
"\n", info
.code
);