|
1 | 1 | // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
2 | 2 | #include "tp_pmu.h"
|
| 3 | +#include "pmus.h" |
3 | 4 | #include <api/fs/fs.h>
|
4 | 5 | #include <api/fs/tracing_path.h>
|
5 | 6 | #include <api/io_dir.h>
|
@@ -93,3 +94,117 @@ int tp_pmu__for_each_tp_sys(void *state, tp_sys_callback cb)
|
93 | 94 | close(events_dir.dirfd);
|
94 | 95 | return ret;
|
95 | 96 | }
|
| 97 | + |
| 98 | +bool perf_pmu__is_tracepoint(const struct perf_pmu *pmu) |
| 99 | +{ |
| 100 | + return pmu->type == PERF_TYPE_TRACEPOINT; |
| 101 | +} |
| 102 | + |
| 103 | +struct for_each_event_args { |
| 104 | + void *state; |
| 105 | + pmu_event_callback cb; |
| 106 | + const struct perf_pmu *pmu; |
| 107 | +}; |
| 108 | + |
| 109 | +static int for_each_event_cb(void *state, const char *sys_name, const char *evt_name) |
| 110 | +{ |
| 111 | + struct for_each_event_args *args = state; |
| 112 | + char name[2 * FILENAME_MAX + 2]; |
| 113 | + /* 16 possible hex digits and 22 other characters and \0. */ |
| 114 | + char encoding[16 + 22]; |
| 115 | + char *format = NULL; |
| 116 | + size_t format_size; |
| 117 | + struct pmu_event_info info = { |
| 118 | + .pmu = args->pmu, |
| 119 | + .pmu_name = args->pmu->name, |
| 120 | + .event_type_desc = "Tracepoint event", |
| 121 | + }; |
| 122 | + char *tp_dir = get_events_file(sys_name); |
| 123 | + char path[PATH_MAX]; |
| 124 | + int id, err; |
| 125 | + |
| 126 | + if (!tp_dir) |
| 127 | + return -1; |
| 128 | + |
| 129 | + scnprintf(path, sizeof(path), "%s/%s/id", tp_dir, evt_name); |
| 130 | + err = filename__read_int(path, &id); |
| 131 | + if (err == 0) { |
| 132 | + snprintf(encoding, sizeof(encoding), "tracepoint/config=0x%x/", id); |
| 133 | + info.encoding_desc = encoding; |
| 134 | + } |
| 135 | + |
| 136 | + scnprintf(path, sizeof(path), "%s/%s/format", tp_dir, evt_name); |
| 137 | + put_events_file(tp_dir); |
| 138 | + err = filename__read_str(path, &format, &format_size); |
| 139 | + if (err == 0) { |
| 140 | + info.long_desc = format; |
| 141 | + for (size_t i = 0 ; i < format_size; i++) { |
| 142 | + /* Swap tabs to spaces due to some rendering issues. */ |
| 143 | + if (format[i] == '\t') |
| 144 | + format[i] = ' '; |
| 145 | + } |
| 146 | + } |
| 147 | + snprintf(name, sizeof(name), "%s:%s", sys_name, evt_name); |
| 148 | + info.name = name; |
| 149 | + err = args->cb(args->state, &info); |
| 150 | + free(format); |
| 151 | + return err; |
| 152 | +} |
| 153 | + |
| 154 | +static int for_each_event_sys_cb(void *state, const char *sys_name) |
| 155 | +{ |
| 156 | + return tp_pmu__for_each_tp_event(sys_name, state, for_each_event_cb); |
| 157 | +} |
| 158 | + |
| 159 | +int tp_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_callback cb) |
| 160 | +{ |
| 161 | + struct for_each_event_args args = { |
| 162 | + .state = state, |
| 163 | + .cb = cb, |
| 164 | + .pmu = pmu, |
| 165 | + }; |
| 166 | + |
| 167 | + return tp_pmu__for_each_tp_sys(&args, for_each_event_sys_cb); |
| 168 | +} |
| 169 | + |
| 170 | +static int num_events_cb(void *state, const char *sys_name __maybe_unused, |
| 171 | + const char *evt_name __maybe_unused) |
| 172 | +{ |
| 173 | + size_t *count = state; |
| 174 | + |
| 175 | + (*count)++; |
| 176 | + return 0; |
| 177 | +} |
| 178 | + |
| 179 | +static int num_events_sys_cb(void *state, const char *sys_name) |
| 180 | +{ |
| 181 | + return tp_pmu__for_each_tp_event(sys_name, state, num_events_cb); |
| 182 | +} |
| 183 | + |
| 184 | +size_t tp_pmu__num_events(struct perf_pmu *pmu __maybe_unused) |
| 185 | +{ |
| 186 | + size_t count = 0; |
| 187 | + |
| 188 | + tp_pmu__for_each_tp_sys(&count, num_events_sys_cb); |
| 189 | + return count; |
| 190 | +} |
| 191 | + |
| 192 | +bool tp_pmu__have_event(struct perf_pmu *pmu __maybe_unused, const char *name) |
| 193 | +{ |
| 194 | + char *dup_name, *colon; |
| 195 | + int id; |
| 196 | + |
| 197 | + colon = strchr(name, ':'); |
| 198 | + if (colon == NULL) |
| 199 | + return false; |
| 200 | + |
| 201 | + dup_name = strdup(name); |
| 202 | + if (!dup_name) |
| 203 | + return false; |
| 204 | + |
| 205 | + colon = dup_name + (colon - name); |
| 206 | + *colon = '\0'; |
| 207 | + id = tp_pmu__id(dup_name, colon + 1); |
| 208 | + free(dup_name); |
| 209 | + return id >= 0; |
| 210 | +} |
0 commit comments