tests: perf: UNHALTED_REFERENCE_CYCLES might not be actionable on a host
[lttng-tools.git] / tests / perf / find_event.c
1 /*
2 * Copyright (C) 2016 Julien Desfossez <jdesfossez@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include <errno.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #include <linux/perf_event.h>
13 #include <perfmon/perf_event.h>
14 #include <perfmon/pfmlib_perf_event.h>
15
16 int main(int argc, char **argv)
17 {
18 int ret, fd;
19
20 /* pfm query objects */
21 pfm_perf_encode_arg_t pencoder;
22 pfm_event_info_t info;
23
24 /* Perf event object to be populated by libpfm */
25 struct perf_event_attr attr;
26
27 if (argc != 2) {
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"
31 "return code 0.\n"
32 "If not found returns 1,"
33 "If not actionable return 2,"
34 "on error returns 255\n",
35 argv[0], argv[0]);
36 ret = -1;
37 goto end;
38 }
39
40 /* Initialize perf_event_attr. */
41 memset(&attr, 0, sizeof(struct perf_event_attr));
42
43 /* Initialize libpfm encoder structure. */
44 memset(&pencoder, 0, sizeof(pencoder));
45 pencoder.size = sizeof(pfm_perf_encode_arg_t);
46
47 /* Initialize libpfm event info structure. */
48 memset(&info, 0, sizeof(info));
49 info.size = sizeof(info);
50
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. */
54
55 ret = pfm_initialize();
56 if (ret != PFM_SUCCESS) {
57 fprintf(stderr, "Failed to initialise libpfm: %s",
58 pfm_strerror(ret));
59 ret = 255;
60 goto end;
61 }
62
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",
68 pfm_strerror(ret));
69 ret = 1;
70 goto end;
71 }
72
73 /*
74 * Query the raw code for later use. Do it now to simplify error
75 * management.
76 */
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));
80 ret = 1;
81 goto end;
82 }
83
84 /*
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
87 * host.
88 */
89
90 /* Set the event to disabled to prevent unnecessary side effects. */
91 pencoder.attr->disabled = 1;
92
93 /* perf_event_open is provided by perfmon/perf_event.h. */
94 fd = perf_event_open(pencoder.attr, 0, -1, -1, 0);
95 if (fd == -1) {
96 fprintf(stderr, "perf: error perf_event_open: %d: %s\n", errno,
97 strerror(errno));
98 ret = 2;
99 goto end;
100 }
101
102 /* We close the fd immediately since the event is actionable. */
103 close(fd);
104
105 /* Output the raw code for the event */
106 fprintf(stdout, "r%" PRIx64 "\n", info.code);
107 ret = 0;
108
109 end:
110 return ret;
111 }
This page took 0.032896 seconds and 4 git commands to generate.