blob: 5d3ab7c8ceaf00c86a395c03f2a2d8a9f4bb78e5 [file] [log] [blame]
Jiri Olsacd82a322012-03-15 20:09:17 +01001#include <linux/list.h>
2#include <sys/types.h>
Jiri Olsacd82a322012-03-15 20:09:17 +01003#include <unistd.h>
4#include <stdio.h>
Adrian Hunterdc0a6202014-07-31 09:00:49 +03005#include <stdbool.h>
Adrian Hunter7d4bdab2014-07-31 09:00:50 +03006#include <stdarg.h>
Jiri Olsacd82a322012-03-15 20:09:17 +01007#include <dirent.h>
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01008#include <api/fs/fs.h>
Stephane Eranian410136f2013-11-12 17:58:49 +01009#include <locale.h>
Jiri Olsacd82a322012-03-15 20:09:17 +010010#include "util.h"
11#include "pmu.h"
12#include "parse-events.h"
Yan, Zheng7ae92e72012-09-10 15:53:50 +080013#include "cpumap.h"
Jiri Olsacd82a322012-03-15 20:09:17 +010014
Arnaldo Carvalho de Meloab1bf6532013-01-18 17:05:09 -030015struct perf_pmu_format {
16 char *name;
17 int value;
18 DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS);
19 struct list_head list;
20};
21
Robert Richter50a96672012-08-16 21:10:24 +020022#define EVENT_SOURCE_DEVICE_PATH "/bus/event_source/devices/"
23
Jiri Olsacd82a322012-03-15 20:09:17 +010024int perf_pmu_parse(struct list_head *list, char *name);
25extern FILE *perf_pmu_in;
26
27static LIST_HEAD(pmus);
28
29/*
30 * Parse & process all the sysfs attributes located under
31 * the directory specified in 'dir' parameter.
32 */
Jiri Olsacff7f952012-11-10 01:46:50 +010033int perf_pmu__format_parse(char *dir, struct list_head *head)
Jiri Olsacd82a322012-03-15 20:09:17 +010034{
35 struct dirent *evt_ent;
36 DIR *format_dir;
37 int ret = 0;
38
39 format_dir = opendir(dir);
40 if (!format_dir)
41 return -EINVAL;
42
43 while (!ret && (evt_ent = readdir(format_dir))) {
44 char path[PATH_MAX];
45 char *name = evt_ent->d_name;
46 FILE *file;
47
48 if (!strcmp(name, ".") || !strcmp(name, ".."))
49 continue;
50
51 snprintf(path, PATH_MAX, "%s/%s", dir, name);
52
53 ret = -EINVAL;
54 file = fopen(path, "r");
55 if (!file)
56 break;
57
58 perf_pmu_in = file;
59 ret = perf_pmu_parse(head, name);
60 fclose(file);
61 }
62
63 closedir(format_dir);
64 return ret;
65}
66
67/*
68 * Reading/parsing the default pmu format definition, which should be
69 * located at:
70 * /sys/bus/event_source/devices/<dev>/format as sysfs group attributes.
71 */
Adrian Hunterb6b96fb2013-07-04 16:20:25 +030072static int pmu_format(const char *name, struct list_head *format)
Jiri Olsacd82a322012-03-15 20:09:17 +010073{
74 struct stat st;
75 char path[PATH_MAX];
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -030076 const char *sysfs = sysfs__mountpoint();
Jiri Olsacd82a322012-03-15 20:09:17 +010077
Jiri Olsacd82a322012-03-15 20:09:17 +010078 if (!sysfs)
79 return -1;
80
81 snprintf(path, PATH_MAX,
Robert Richter50a96672012-08-16 21:10:24 +020082 "%s" EVENT_SOURCE_DEVICE_PATH "%s/format", sysfs, name);
Jiri Olsacd82a322012-03-15 20:09:17 +010083
84 if (stat(path, &st) < 0)
Robert Richter9bc8f9f2012-06-14 22:38:37 +020085 return 0; /* no error if format does not exist */
Jiri Olsacd82a322012-03-15 20:09:17 +010086
Jiri Olsacff7f952012-11-10 01:46:50 +010087 if (perf_pmu__format_parse(path, format))
Jiri Olsacd82a322012-03-15 20:09:17 +010088 return -1;
89
90 return 0;
91}
92
Stephane Eranian410136f2013-11-12 17:58:49 +010093static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
94{
95 struct stat st;
96 ssize_t sret;
97 char scale[128];
98 int fd, ret = -1;
99 char path[PATH_MAX];
Stephane Eranian8a398892014-01-17 16:34:05 +0100100 const char *lc;
Stephane Eranian410136f2013-11-12 17:58:49 +0100101
102 snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
103
104 fd = open(path, O_RDONLY);
105 if (fd == -1)
106 return -1;
107
108 if (fstat(fd, &st) < 0)
109 goto error;
110
111 sret = read(fd, scale, sizeof(scale)-1);
112 if (sret < 0)
113 goto error;
114
115 scale[sret] = '\0';
116 /*
117 * save current locale
118 */
119 lc = setlocale(LC_NUMERIC, NULL);
120
121 /*
122 * force to C locale to ensure kernel
123 * scale string is converted correctly.
124 * kernel uses default C locale.
125 */
126 setlocale(LC_NUMERIC, "C");
127
128 alias->scale = strtod(scale, NULL);
129
130 /* restore locale */
131 setlocale(LC_NUMERIC, lc);
132
133 ret = 0;
134error:
135 close(fd);
136 return ret;
137}
138
139static int perf_pmu__parse_unit(struct perf_pmu_alias *alias, char *dir, char *name)
140{
141 char path[PATH_MAX];
142 ssize_t sret;
143 int fd;
144
145 snprintf(path, PATH_MAX, "%s/%s.unit", dir, name);
146
147 fd = open(path, O_RDONLY);
148 if (fd == -1)
149 return -1;
150
151 sret = read(fd, alias->unit, UNIT_MAX_LEN);
152 if (sret < 0)
153 goto error;
154
155 close(fd);
156
157 alias->unit[sret] = '\0';
158
159 return 0;
160error:
161 close(fd);
162 alias->unit[0] = '\0';
163 return -1;
164}
165
Matt Fleming044330c2014-11-21 10:31:12 +0100166static int
167perf_pmu__parse_per_pkg(struct perf_pmu_alias *alias, char *dir, char *name)
168{
169 char path[PATH_MAX];
170 int fd;
171
172 snprintf(path, PATH_MAX, "%s/%s.per-pkg", dir, name);
173
174 fd = open(path, O_RDONLY);
175 if (fd == -1)
176 return -1;
177
178 close(fd);
179
180 alias->per_pkg = true;
181 return 0;
182}
183
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100184static int perf_pmu__parse_snapshot(struct perf_pmu_alias *alias,
185 char *dir, char *name)
186{
187 char path[PATH_MAX];
188 int fd;
189
190 snprintf(path, PATH_MAX, "%s/%s.snapshot", dir, name);
191
192 fd = open(path, O_RDONLY);
193 if (fd == -1)
194 return -1;
195
196 alias->snapshot = true;
197 close(fd);
198 return 0;
199}
200
Stephane Eranian410136f2013-11-12 17:58:49 +0100201static int perf_pmu__new_alias(struct list_head *list, char *dir, char *name, FILE *file)
Zheng Yana6146d52012-06-15 14:31:41 +0800202{
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300203 struct perf_pmu_alias *alias;
Zheng Yana6146d52012-06-15 14:31:41 +0800204 char buf[256];
205 int ret;
206
207 ret = fread(buf, 1, sizeof(buf), file);
208 if (ret == 0)
209 return -EINVAL;
210 buf[ret] = 0;
211
212 alias = malloc(sizeof(*alias));
213 if (!alias)
214 return -ENOMEM;
215
216 INIT_LIST_HEAD(&alias->terms);
Stephane Eranian410136f2013-11-12 17:58:49 +0100217 alias->scale = 1.0;
218 alias->unit[0] = '\0';
Matt Fleming044330c2014-11-21 10:31:12 +0100219 alias->per_pkg = false;
Stephane Eranian410136f2013-11-12 17:58:49 +0100220
Zheng Yana6146d52012-06-15 14:31:41 +0800221 ret = parse_events_terms(&alias->terms, buf);
222 if (ret) {
223 free(alias);
224 return ret;
225 }
226
227 alias->name = strdup(name);
Stephane Eranian410136f2013-11-12 17:58:49 +0100228 /*
229 * load unit name and scale if available
230 */
231 perf_pmu__parse_unit(alias, dir, name);
232 perf_pmu__parse_scale(alias, dir, name);
Matt Fleming044330c2014-11-21 10:31:12 +0100233 perf_pmu__parse_per_pkg(alias, dir, name);
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100234 perf_pmu__parse_snapshot(alias, dir, name);
Stephane Eranian410136f2013-11-12 17:58:49 +0100235
Zheng Yana6146d52012-06-15 14:31:41 +0800236 list_add_tail(&alias->list, list);
Stephane Eranian410136f2013-11-12 17:58:49 +0100237
Zheng Yana6146d52012-06-15 14:31:41 +0800238 return 0;
239}
240
Matt Fleming46441bd2014-09-24 15:04:06 +0100241static inline bool pmu_alias_info_file(char *name)
242{
243 size_t len;
244
245 len = strlen(name);
246 if (len > 5 && !strcmp(name + len - 5, ".unit"))
247 return true;
248 if (len > 6 && !strcmp(name + len - 6, ".scale"))
249 return true;
Matt Fleming044330c2014-11-21 10:31:12 +0100250 if (len > 8 && !strcmp(name + len - 8, ".per-pkg"))
251 return true;
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100252 if (len > 9 && !strcmp(name + len - 9, ".snapshot"))
253 return true;
Matt Fleming46441bd2014-09-24 15:04:06 +0100254
255 return false;
256}
257
Zheng Yana6146d52012-06-15 14:31:41 +0800258/*
259 * Process all the sysfs attributes located under the directory
260 * specified in 'dir' parameter.
261 */
262static int pmu_aliases_parse(char *dir, struct list_head *head)
263{
264 struct dirent *evt_ent;
265 DIR *event_dir;
266 int ret = 0;
267
268 event_dir = opendir(dir);
269 if (!event_dir)
270 return -EINVAL;
271
272 while (!ret && (evt_ent = readdir(event_dir))) {
273 char path[PATH_MAX];
274 char *name = evt_ent->d_name;
275 FILE *file;
276
277 if (!strcmp(name, ".") || !strcmp(name, ".."))
278 continue;
279
Stephane Eranian410136f2013-11-12 17:58:49 +0100280 /*
Matt Fleming46441bd2014-09-24 15:04:06 +0100281 * skip info files parsed in perf_pmu__new_alias()
Stephane Eranian410136f2013-11-12 17:58:49 +0100282 */
Matt Fleming46441bd2014-09-24 15:04:06 +0100283 if (pmu_alias_info_file(name))
Stephane Eranian410136f2013-11-12 17:58:49 +0100284 continue;
285
Zheng Yana6146d52012-06-15 14:31:41 +0800286 snprintf(path, PATH_MAX, "%s/%s", dir, name);
287
288 ret = -EINVAL;
289 file = fopen(path, "r");
290 if (!file)
291 break;
Stephane Eranian410136f2013-11-12 17:58:49 +0100292
293 ret = perf_pmu__new_alias(head, dir, name, file);
Zheng Yana6146d52012-06-15 14:31:41 +0800294 fclose(file);
295 }
296
297 closedir(event_dir);
298 return ret;
299}
300
301/*
302 * Reading the pmu event aliases definition, which should be located at:
303 * /sys/bus/event_source/devices/<dev>/events as sysfs group attributes.
304 */
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300305static int pmu_aliases(const char *name, struct list_head *head)
Zheng Yana6146d52012-06-15 14:31:41 +0800306{
307 struct stat st;
308 char path[PATH_MAX];
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300309 const char *sysfs = sysfs__mountpoint();
Zheng Yana6146d52012-06-15 14:31:41 +0800310
Zheng Yana6146d52012-06-15 14:31:41 +0800311 if (!sysfs)
312 return -1;
313
314 snprintf(path, PATH_MAX,
315 "%s/bus/event_source/devices/%s/events", sysfs, name);
316
317 if (stat(path, &st) < 0)
Jiri Olsa3fded962012-10-10 14:53:16 +0200318 return 0; /* no error if 'events' does not exist */
Zheng Yana6146d52012-06-15 14:31:41 +0800319
320 if (pmu_aliases_parse(path, head))
321 return -1;
322
323 return 0;
324}
325
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300326static int pmu_alias_terms(struct perf_pmu_alias *alias,
Zheng Yana6146d52012-06-15 14:31:41 +0800327 struct list_head *terms)
328{
Jiri Olsa7c2f8162014-04-16 20:49:02 +0200329 struct parse_events_term *term, *cloned;
Zheng Yana6146d52012-06-15 14:31:41 +0800330 LIST_HEAD(list);
331 int ret;
332
333 list_for_each_entry(term, &alias->terms, list) {
Jiri Olsa7c2f8162014-04-16 20:49:02 +0200334 ret = parse_events_term__clone(&cloned, term);
Zheng Yana6146d52012-06-15 14:31:41 +0800335 if (ret) {
336 parse_events__free_terms(&list);
337 return ret;
338 }
Jiri Olsa7c2f8162014-04-16 20:49:02 +0200339 list_add_tail(&cloned->list, &list);
Zheng Yana6146d52012-06-15 14:31:41 +0800340 }
341 list_splice(&list, terms);
342 return 0;
343}
344
Jiri Olsacd82a322012-03-15 20:09:17 +0100345/*
346 * Reading/parsing the default pmu type value, which should be
347 * located at:
348 * /sys/bus/event_source/devices/<dev>/type as sysfs attribute.
349 */
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300350static int pmu_type(const char *name, __u32 *type)
Jiri Olsacd82a322012-03-15 20:09:17 +0100351{
352 struct stat st;
353 char path[PATH_MAX];
Jiri Olsacd82a322012-03-15 20:09:17 +0100354 FILE *file;
355 int ret = 0;
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300356 const char *sysfs = sysfs__mountpoint();
Jiri Olsacd82a322012-03-15 20:09:17 +0100357
Jiri Olsacd82a322012-03-15 20:09:17 +0100358 if (!sysfs)
359 return -1;
360
361 snprintf(path, PATH_MAX,
Robert Richter50a96672012-08-16 21:10:24 +0200362 "%s" EVENT_SOURCE_DEVICE_PATH "%s/type", sysfs, name);
Jiri Olsacd82a322012-03-15 20:09:17 +0100363
364 if (stat(path, &st) < 0)
365 return -1;
366
367 file = fopen(path, "r");
368 if (!file)
369 return -EINVAL;
370
371 if (1 != fscanf(file, "%u", type))
372 ret = -1;
373
374 fclose(file);
375 return ret;
376}
377
Robert Richter50a96672012-08-16 21:10:24 +0200378/* Add all pmus in sysfs to pmu list: */
379static void pmu_read_sysfs(void)
380{
381 char path[PATH_MAX];
Robert Richter50a96672012-08-16 21:10:24 +0200382 DIR *dir;
383 struct dirent *dent;
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300384 const char *sysfs = sysfs__mountpoint();
Robert Richter50a96672012-08-16 21:10:24 +0200385
Robert Richter50a96672012-08-16 21:10:24 +0200386 if (!sysfs)
387 return;
388
389 snprintf(path, PATH_MAX,
390 "%s" EVENT_SOURCE_DEVICE_PATH, sysfs);
391
392 dir = opendir(path);
393 if (!dir)
394 return;
395
396 while ((dent = readdir(dir))) {
397 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
398 continue;
399 /* add to static LIST_HEAD(pmus): */
400 perf_pmu__find(dent->d_name);
401 }
402
403 closedir(dir);
404}
405
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300406static struct cpu_map *pmu_cpumask(const char *name)
Yan, Zheng7ae92e72012-09-10 15:53:50 +0800407{
408 struct stat st;
409 char path[PATH_MAX];
Yan, Zheng7ae92e72012-09-10 15:53:50 +0800410 FILE *file;
411 struct cpu_map *cpus;
Arnaldo Carvalho de Melocf38fad2013-11-05 14:48:50 -0300412 const char *sysfs = sysfs__mountpoint();
Yan, Zheng7ae92e72012-09-10 15:53:50 +0800413
Yan, Zheng7ae92e72012-09-10 15:53:50 +0800414 if (!sysfs)
415 return NULL;
416
417 snprintf(path, PATH_MAX,
418 "%s/bus/event_source/devices/%s/cpumask", sysfs, name);
419
420 if (stat(path, &st) < 0)
421 return NULL;
422
423 file = fopen(path, "r");
424 if (!file)
425 return NULL;
426
427 cpus = cpu_map__read(file);
428 fclose(file);
429 return cpus;
430}
431
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300432struct perf_event_attr *__attribute__((weak))
433perf_pmu__get_default_config(struct perf_pmu *pmu __maybe_unused)
434{
435 return NULL;
436}
437
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300438static struct perf_pmu *pmu_lookup(const char *name)
Jiri Olsacd82a322012-03-15 20:09:17 +0100439{
440 struct perf_pmu *pmu;
441 LIST_HEAD(format);
Zheng Yana6146d52012-06-15 14:31:41 +0800442 LIST_HEAD(aliases);
Jiri Olsacd82a322012-03-15 20:09:17 +0100443 __u32 type;
444
Adrian Hunter9b5d1c22015-05-22 14:53:58 +0300445 /* No support for intel_bts or intel_pt so disallow them */
446 if (!strcmp(name, "intel_bts") || !strcmp(name, "intel_pt"))
447 return NULL;
448
Jiri Olsacd82a322012-03-15 20:09:17 +0100449 /*
450 * The pmu data we store & need consists of the pmu
451 * type value and format definitions. Load both right
452 * now.
453 */
454 if (pmu_format(name, &format))
455 return NULL;
456
Jiri Olsa3fded962012-10-10 14:53:16 +0200457 if (pmu_aliases(name, &aliases))
458 return NULL;
459
Jiri Olsacd82a322012-03-15 20:09:17 +0100460 if (pmu_type(name, &type))
461 return NULL;
462
463 pmu = zalloc(sizeof(*pmu));
464 if (!pmu)
465 return NULL;
466
Yan, Zheng7ae92e72012-09-10 15:53:50 +0800467 pmu->cpus = pmu_cpumask(name);
468
Jiri Olsacd82a322012-03-15 20:09:17 +0100469 INIT_LIST_HEAD(&pmu->format);
Zheng Yana6146d52012-06-15 14:31:41 +0800470 INIT_LIST_HEAD(&pmu->aliases);
Jiri Olsacd82a322012-03-15 20:09:17 +0100471 list_splice(&format, &pmu->format);
Zheng Yana6146d52012-06-15 14:31:41 +0800472 list_splice(&aliases, &pmu->aliases);
Jiri Olsacd82a322012-03-15 20:09:17 +0100473 pmu->name = strdup(name);
474 pmu->type = type;
Robert Richter9bc8f9f2012-06-14 22:38:37 +0200475 list_add_tail(&pmu->list, &pmus);
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300476
477 pmu->default_config = perf_pmu__get_default_config(pmu);
478
Jiri Olsacd82a322012-03-15 20:09:17 +0100479 return pmu;
480}
481
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300482static struct perf_pmu *pmu_find(const char *name)
Jiri Olsacd82a322012-03-15 20:09:17 +0100483{
484 struct perf_pmu *pmu;
485
486 list_for_each_entry(pmu, &pmus, list)
487 if (!strcmp(pmu->name, name))
488 return pmu;
489
490 return NULL;
491}
492
Robert Richter50a96672012-08-16 21:10:24 +0200493struct perf_pmu *perf_pmu__scan(struct perf_pmu *pmu)
494{
495 /*
496 * pmu iterator: If pmu is NULL, we start at the begin,
497 * otherwise return the next pmu. Returns NULL on end.
498 */
499 if (!pmu) {
500 pmu_read_sysfs();
501 pmu = list_prepare_entry(pmu, &pmus, list);
502 }
503 list_for_each_entry_continue(pmu, &pmus, list)
504 return pmu;
505 return NULL;
506}
507
Adrian Hunterb6b96fb2013-07-04 16:20:25 +0300508struct perf_pmu *perf_pmu__find(const char *name)
Jiri Olsacd82a322012-03-15 20:09:17 +0100509{
510 struct perf_pmu *pmu;
511
512 /*
513 * Once PMU is loaded it stays in the list,
514 * so we keep us from multiple reading/parsing
515 * the pmu format definitions.
516 */
517 pmu = pmu_find(name);
518 if (pmu)
519 return pmu;
520
521 return pmu_lookup(name);
522}
523
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300524static struct perf_pmu_format *
Jiri Olsacd82a322012-03-15 20:09:17 +0100525pmu_find_format(struct list_head *formats, char *name)
526{
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300527 struct perf_pmu_format *format;
Jiri Olsacd82a322012-03-15 20:09:17 +0100528
529 list_for_each_entry(format, formats, list)
530 if (!strcmp(format->name, name))
531 return format;
532
533 return NULL;
534}
535
536/*
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300537 * Sets value based on the format definition (format parameter)
Jiri Olsacd82a322012-03-15 20:09:17 +0100538 * and unformated value (value parameter).
Jiri Olsacd82a322012-03-15 20:09:17 +0100539 */
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300540static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v,
541 bool zero)
Jiri Olsacd82a322012-03-15 20:09:17 +0100542{
543 unsigned long fbit, vbit;
Jiri Olsacd82a322012-03-15 20:09:17 +0100544
545 for (fbit = 0, vbit = 0; fbit < PERF_PMU_FORMAT_BITS; fbit++) {
546
547 if (!test_bit(fbit, format))
548 continue;
549
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300550 if (value & (1llu << vbit++))
551 *v |= (1llu << fbit);
552 else if (zero)
553 *v &= ~(1llu << fbit);
Jiri Olsacd82a322012-03-15 20:09:17 +0100554 }
Jiri Olsacd82a322012-03-15 20:09:17 +0100555}
556
557/*
Cody P Schafer688d4df2015-01-07 17:13:50 -0800558 * Term is a string term, and might be a param-term. Try to look up it's value
559 * in the remaining terms.
560 * - We have a term like "base-or-format-term=param-term",
561 * - We need to find the value supplied for "param-term" (with param-term named
562 * in a config string) later on in the term list.
563 */
564static int pmu_resolve_param_term(struct parse_events_term *term,
565 struct list_head *head_terms,
566 __u64 *value)
567{
568 struct parse_events_term *t;
569
570 list_for_each_entry(t, head_terms, list) {
571 if (t->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
572 if (!strcmp(t->config, term->config)) {
573 t->used = true;
574 *value = t->val.num;
575 return 0;
576 }
577 }
578 }
579
580 if (verbose)
581 printf("Required parameter '%s' not specified\n", term->config);
582
583 return -1;
584}
585
Jiri Olsae64b0202015-04-22 21:10:21 +0200586static char *formats_error_string(struct list_head *formats)
587{
588 struct perf_pmu_format *format;
589 char *err, *str;
590 static const char *static_terms = "config,config1,config2,name,period,branch_type\n";
591 unsigned i = 0;
592
593 if (!asprintf(&str, "valid terms:"))
594 return NULL;
595
596 /* sysfs exported terms */
597 list_for_each_entry(format, formats, list) {
598 char c = i++ ? ',' : ' ';
599
600 err = str;
601 if (!asprintf(&str, "%s%c%s", err, c, format->name))
602 goto fail;
603 free(err);
604 }
605
606 /* static terms */
607 err = str;
608 if (!asprintf(&str, "%s,%s", err, static_terms))
609 goto fail;
610
611 free(err);
612 return str;
613fail:
614 free(err);
615 return NULL;
616}
617
Cody P Schafer688d4df2015-01-07 17:13:50 -0800618/*
Jiri Olsacd82a322012-03-15 20:09:17 +0100619 * Setup one of config[12] attr members based on the
Cody P Schafer88aca8d2014-01-08 08:43:51 -0800620 * user input data - term parameter.
Jiri Olsacd82a322012-03-15 20:09:17 +0100621 */
622static int pmu_config_term(struct list_head *formats,
623 struct perf_event_attr *attr,
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300624 struct parse_events_term *term,
Cody P Schafer688d4df2015-01-07 17:13:50 -0800625 struct list_head *head_terms,
Jiri Olsae64b0202015-04-22 21:10:21 +0200626 bool zero, struct parse_events_error *err)
Jiri Olsacd82a322012-03-15 20:09:17 +0100627{
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300628 struct perf_pmu_format *format;
Jiri Olsacd82a322012-03-15 20:09:17 +0100629 __u64 *vp;
Cody P Schafer688d4df2015-01-07 17:13:50 -0800630 __u64 val;
Jiri Olsacd82a322012-03-15 20:09:17 +0100631
632 /*
Cody P Schafer688d4df2015-01-07 17:13:50 -0800633 * If this is a parameter we've already used for parameterized-eval,
634 * skip it in normal eval.
635 */
636 if (term->used)
637 return 0;
638
639 /*
Jiri Olsacd82a322012-03-15 20:09:17 +0100640 * Hardcoded terms should be already in, so nothing
641 * to be done for them.
642 */
643 if (parse_events__is_hardcoded_term(term))
644 return 0;
645
Jiri Olsacd82a322012-03-15 20:09:17 +0100646 format = pmu_find_format(formats, term->config);
Cody P Schafer688d4df2015-01-07 17:13:50 -0800647 if (!format) {
648 if (verbose)
649 printf("Invalid event/parameter '%s'\n", term->config);
Jiri Olsae64b0202015-04-22 21:10:21 +0200650 if (err) {
651 err->idx = term->err_term;
652 err->str = strdup("unknown term");
653 err->help = formats_error_string(formats);
654 }
Jiri Olsacd82a322012-03-15 20:09:17 +0100655 return -EINVAL;
Cody P Schafer688d4df2015-01-07 17:13:50 -0800656 }
Jiri Olsacd82a322012-03-15 20:09:17 +0100657
658 switch (format->value) {
659 case PERF_PMU_FORMAT_VALUE_CONFIG:
660 vp = &attr->config;
661 break;
662 case PERF_PMU_FORMAT_VALUE_CONFIG1:
663 vp = &attr->config1;
664 break;
665 case PERF_PMU_FORMAT_VALUE_CONFIG2:
666 vp = &attr->config2;
667 break;
668 default:
669 return -EINVAL;
670 }
671
Jiri Olsa16fa7e82012-04-25 18:24:57 +0200672 /*
Cody P Schafer688d4df2015-01-07 17:13:50 -0800673 * Either directly use a numeric term, or try to translate string terms
674 * using event parameters.
Jiri Olsa16fa7e82012-04-25 18:24:57 +0200675 */
Cody P Schafer688d4df2015-01-07 17:13:50 -0800676 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
677 val = term->val.num;
678 else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
679 if (strcmp(term->val.str, "?")) {
Jiri Olsae64b0202015-04-22 21:10:21 +0200680 if (verbose) {
Cody P Schafer688d4df2015-01-07 17:13:50 -0800681 pr_info("Invalid sysfs entry %s=%s\n",
682 term->config, term->val.str);
Jiri Olsae64b0202015-04-22 21:10:21 +0200683 }
684 if (err) {
685 err->idx = term->err_val;
686 err->str = strdup("expected numeric value");
687 }
Cody P Schafer688d4df2015-01-07 17:13:50 -0800688 return -EINVAL;
689 }
690
691 if (pmu_resolve_param_term(term, head_terms, &val))
692 return -EINVAL;
693 } else
694 return -EINVAL;
695
696 pmu_format_value(format->bits, val, vp, zero);
Jiri Olsacd82a322012-03-15 20:09:17 +0100697 return 0;
698}
699
Jiri Olsacff7f952012-11-10 01:46:50 +0100700int perf_pmu__config_terms(struct list_head *formats,
701 struct perf_event_attr *attr,
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300702 struct list_head *head_terms,
Jiri Olsae64b0202015-04-22 21:10:21 +0200703 bool zero, struct parse_events_error *err)
Jiri Olsacd82a322012-03-15 20:09:17 +0100704{
Arnaldo Carvalho de Melo6cee6cd2013-01-18 16:29:49 -0300705 struct parse_events_term *term;
Jiri Olsacd82a322012-03-15 20:09:17 +0100706
Cody P Schafer688d4df2015-01-07 17:13:50 -0800707 list_for_each_entry(term, head_terms, list) {
Jiri Olsae64b0202015-04-22 21:10:21 +0200708 if (pmu_config_term(formats, attr, term, head_terms,
709 zero, err))
Jiri Olsacd82a322012-03-15 20:09:17 +0100710 return -EINVAL;
Cody P Schafer688d4df2015-01-07 17:13:50 -0800711 }
Jiri Olsacd82a322012-03-15 20:09:17 +0100712
713 return 0;
714}
715
716/*
717 * Configures event's 'attr' parameter based on the:
718 * 1) users input - specified in terms parameter
719 * 2) pmu format definitions - specified by pmu parameter
720 */
721int perf_pmu__config(struct perf_pmu *pmu, struct perf_event_attr *attr,
Jiri Olsae64b0202015-04-22 21:10:21 +0200722 struct list_head *head_terms,
723 struct parse_events_error *err)
Jiri Olsacd82a322012-03-15 20:09:17 +0100724{
Adrian Hunterdc0a6202014-07-31 09:00:49 +0300725 bool zero = !!pmu->default_config;
726
Jiri Olsacd82a322012-03-15 20:09:17 +0100727 attr->type = pmu->type;
Jiri Olsae64b0202015-04-22 21:10:21 +0200728 return perf_pmu__config_terms(&pmu->format, attr, head_terms,
729 zero, err);
Jiri Olsacd82a322012-03-15 20:09:17 +0100730}
731
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300732static struct perf_pmu_alias *pmu_find_alias(struct perf_pmu *pmu,
733 struct parse_events_term *term)
Zheng Yana6146d52012-06-15 14:31:41 +0800734{
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300735 struct perf_pmu_alias *alias;
Zheng Yana6146d52012-06-15 14:31:41 +0800736 char *name;
737
738 if (parse_events__is_hardcoded_term(term))
739 return NULL;
740
741 if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) {
742 if (term->val.num != 1)
743 return NULL;
744 if (pmu_find_format(&pmu->format, term->config))
745 return NULL;
746 name = term->config;
747 } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) {
748 if (strcasecmp(term->config, "event"))
749 return NULL;
750 name = term->val.str;
751 } else {
752 return NULL;
753 }
754
755 list_for_each_entry(alias, &pmu->aliases, list) {
756 if (!strcasecmp(alias->name, name))
757 return alias;
758 }
759 return NULL;
760}
761
Stephane Eranian410136f2013-11-12 17:58:49 +0100762
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100763static int check_info_data(struct perf_pmu_alias *alias,
764 struct perf_pmu_info *info)
Stephane Eranian410136f2013-11-12 17:58:49 +0100765{
766 /*
767 * Only one term in event definition can
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100768 * define unit, scale and snapshot, fail
769 * if there's more than one.
Stephane Eranian410136f2013-11-12 17:58:49 +0100770 */
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100771 if ((info->unit && alias->unit) ||
772 (info->scale && alias->scale) ||
773 (info->snapshot && alias->snapshot))
Stephane Eranian410136f2013-11-12 17:58:49 +0100774 return -EINVAL;
775
776 if (alias->unit)
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100777 info->unit = alias->unit;
Stephane Eranian410136f2013-11-12 17:58:49 +0100778
779 if (alias->scale)
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100780 info->scale = alias->scale;
781
782 if (alias->snapshot)
783 info->snapshot = alias->snapshot;
Stephane Eranian410136f2013-11-12 17:58:49 +0100784
785 return 0;
786}
787
Zheng Yana6146d52012-06-15 14:31:41 +0800788/*
789 * Find alias in the terms list and replace it with the terms
790 * defined for the alias
791 */
Stephane Eranian410136f2013-11-12 17:58:49 +0100792int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
Matt Fleming46441bd2014-09-24 15:04:06 +0100793 struct perf_pmu_info *info)
Zheng Yana6146d52012-06-15 14:31:41 +0800794{
Arnaldo Carvalho de Melo6cee6cd2013-01-18 16:29:49 -0300795 struct parse_events_term *term, *h;
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300796 struct perf_pmu_alias *alias;
Zheng Yana6146d52012-06-15 14:31:41 +0800797 int ret;
798
Matt Fleming044330c2014-11-21 10:31:12 +0100799 info->per_pkg = false;
800
Stephane Eranian8a398892014-01-17 16:34:05 +0100801 /*
802 * Mark unit and scale as not set
803 * (different from default values, see below)
804 */
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100805 info->unit = NULL;
806 info->scale = 0.0;
807 info->snapshot = false;
Stephane Eranian410136f2013-11-12 17:58:49 +0100808
Zheng Yana6146d52012-06-15 14:31:41 +0800809 list_for_each_entry_safe(term, h, head_terms, list) {
810 alias = pmu_find_alias(pmu, term);
811 if (!alias)
812 continue;
813 ret = pmu_alias_terms(alias, &term->list);
814 if (ret)
815 return ret;
Stephane Eranian410136f2013-11-12 17:58:49 +0100816
Jiri Olsa1d9e4462014-11-21 10:31:13 +0100817 ret = check_info_data(alias, info);
Stephane Eranian410136f2013-11-12 17:58:49 +0100818 if (ret)
819 return ret;
820
Matt Fleming044330c2014-11-21 10:31:12 +0100821 if (alias->per_pkg)
822 info->per_pkg = true;
823
Zheng Yana6146d52012-06-15 14:31:41 +0800824 list_del(&term->list);
825 free(term);
826 }
Stephane Eranian8a398892014-01-17 16:34:05 +0100827
828 /*
829 * if no unit or scale foundin aliases, then
830 * set defaults as for evsel
831 * unit cannot left to NULL
832 */
Matt Fleming46441bd2014-09-24 15:04:06 +0100833 if (info->unit == NULL)
834 info->unit = "";
Stephane Eranian8a398892014-01-17 16:34:05 +0100835
Matt Fleming46441bd2014-09-24 15:04:06 +0100836 if (info->scale == 0.0)
837 info->scale = 1.0;
Stephane Eranian8a398892014-01-17 16:34:05 +0100838
Zheng Yana6146d52012-06-15 14:31:41 +0800839 return 0;
840}
841
Jiri Olsacd82a322012-03-15 20:09:17 +0100842int perf_pmu__new_format(struct list_head *list, char *name,
843 int config, unsigned long *bits)
844{
Arnaldo Carvalho de Melo5c6ccc32013-01-18 16:54:00 -0300845 struct perf_pmu_format *format;
Jiri Olsacd82a322012-03-15 20:09:17 +0100846
847 format = zalloc(sizeof(*format));
848 if (!format)
849 return -ENOMEM;
850
851 format->name = strdup(name);
852 format->value = config;
853 memcpy(format->bits, bits, sizeof(format->bits));
854
855 list_add_tail(&format->list, list);
856 return 0;
857}
858
859void perf_pmu__set_format(unsigned long *bits, long from, long to)
860{
861 long b;
862
863 if (!to)
864 to = from;
865
Sukadev Bhattiprolu15268132013-01-17 09:11:30 -0800866 memset(bits, 0, BITS_TO_BYTES(PERF_PMU_FORMAT_BITS));
Jiri Olsacd82a322012-03-15 20:09:17 +0100867 for (b = from; b <= to; b++)
868 set_bit(b, bits);
869}
Andi Kleendc098b32013-04-20 11:02:29 -0700870
Cody P Schaferaaea3612015-01-07 17:13:51 -0800871static int sub_non_neg(int a, int b)
872{
873 if (b > a)
874 return 0;
875 return a - b;
876}
877
Andi Kleendc098b32013-04-20 11:02:29 -0700878static char *format_alias(char *buf, int len, struct perf_pmu *pmu,
879 struct perf_pmu_alias *alias)
880{
Cody P Schaferaaea3612015-01-07 17:13:51 -0800881 struct parse_events_term *term;
882 int used = snprintf(buf, len, "%s/%s", pmu->name, alias->name);
883
884 list_for_each_entry(term, &alias->terms, list) {
885 if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR)
886 used += snprintf(buf + used, sub_non_neg(len, used),
887 ",%s=%s", term->config,
888 term->val.str);
889 }
890
891 if (sub_non_neg(len, used) > 0) {
892 buf[used] = '/';
893 used++;
894 }
895 if (sub_non_neg(len, used) > 0) {
896 buf[used] = '\0';
897 used++;
898 } else
899 buf[len - 1] = '\0';
900
Andi Kleendc098b32013-04-20 11:02:29 -0700901 return buf;
902}
903
904static char *format_alias_or(char *buf, int len, struct perf_pmu *pmu,
905 struct perf_pmu_alias *alias)
906{
907 snprintf(buf, len, "%s OR %s/%s/", alias->name, pmu->name, alias->name);
908 return buf;
909}
910
911static int cmp_string(const void *a, const void *b)
912{
913 const char * const *as = a;
914 const char * const *bs = b;
915 return strcmp(*as, *bs);
916}
917
918void print_pmu_events(const char *event_glob, bool name_only)
919{
920 struct perf_pmu *pmu;
921 struct perf_pmu_alias *alias;
922 char buf[1024];
923 int printed = 0;
924 int len, j;
925 char **aliases;
926
927 pmu = NULL;
928 len = 0;
Adrian Hunter42634bc2014-10-23 13:45:10 +0300929 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
Andi Kleendc098b32013-04-20 11:02:29 -0700930 list_for_each_entry(alias, &pmu->aliases, list)
931 len++;
Adrian Hunter42634bc2014-10-23 13:45:10 +0300932 if (pmu->selectable)
933 len++;
934 }
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300935 aliases = zalloc(sizeof(char *) * len);
Andi Kleendc098b32013-04-20 11:02:29 -0700936 if (!aliases)
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300937 goto out_enomem;
Andi Kleendc098b32013-04-20 11:02:29 -0700938 pmu = NULL;
939 j = 0;
Adrian Hunter42634bc2014-10-23 13:45:10 +0300940 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
Andi Kleendc098b32013-04-20 11:02:29 -0700941 list_for_each_entry(alias, &pmu->aliases, list) {
942 char *name = format_alias(buf, sizeof(buf), pmu, alias);
943 bool is_cpu = !strcmp(pmu->name, "cpu");
944
945 if (event_glob != NULL &&
946 !(strglobmatch(name, event_glob) ||
947 (!is_cpu && strglobmatch(alias->name,
948 event_glob))))
949 continue;
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300950
Andi Kleendc098b32013-04-20 11:02:29 -0700951 if (is_cpu && !name_only)
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300952 name = format_alias_or(buf, sizeof(buf), pmu, alias);
953
954 aliases[j] = strdup(name);
955 if (aliases[j] == NULL)
956 goto out_enomem;
Andi Kleendc098b32013-04-20 11:02:29 -0700957 j++;
958 }
Adrian Hunter42634bc2014-10-23 13:45:10 +0300959 if (pmu->selectable) {
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300960 char *s;
961 if (asprintf(&s, "%s//", pmu->name) < 0)
962 goto out_enomem;
963 aliases[j] = s;
Adrian Hunter42634bc2014-10-23 13:45:10 +0300964 j++;
965 }
966 }
Andi Kleendc098b32013-04-20 11:02:29 -0700967 len = j;
968 qsort(aliases, len, sizeof(char *), cmp_string);
969 for (j = 0; j < len; j++) {
970 if (name_only) {
971 printf("%s ", aliases[j]);
972 continue;
973 }
974 printf(" %-50s [Kernel PMU event]\n", aliases[j]);
Andi Kleendc098b32013-04-20 11:02:29 -0700975 printed++;
976 }
977 if (printed)
978 printf("\n");
Arnaldo Carvalho de Melo7e4772d2014-10-24 10:25:09 -0300979out_free:
980 for (j = 0; j < len; j++)
981 zfree(&aliases[j]);
982 zfree(&aliases);
983 return;
984
985out_enomem:
986 printf("FATAL: not enough memory to print PMU events\n");
987 if (aliases)
988 goto out_free;
Andi Kleendc098b32013-04-20 11:02:29 -0700989}
Andi Kleen4cabc3d2013-08-21 16:47:26 -0700990
991bool pmu_have_event(const char *pname, const char *name)
992{
993 struct perf_pmu *pmu;
994 struct perf_pmu_alias *alias;
995
996 pmu = NULL;
997 while ((pmu = perf_pmu__scan(pmu)) != NULL) {
998 if (strcmp(pname, pmu->name))
999 continue;
1000 list_for_each_entry(alias, &pmu->aliases, list)
1001 if (!strcmp(alias->name, name))
1002 return true;
1003 }
1004 return false;
1005}
Adrian Hunter7d4bdab2014-07-31 09:00:50 +03001006
1007static FILE *perf_pmu__open_file(struct perf_pmu *pmu, const char *name)
1008{
1009 struct stat st;
1010 char path[PATH_MAX];
1011 const char *sysfs;
1012
1013 sysfs = sysfs__mountpoint();
1014 if (!sysfs)
1015 return NULL;
1016
1017 snprintf(path, PATH_MAX,
1018 "%s" EVENT_SOURCE_DEVICE_PATH "%s/%s", sysfs, pmu->name, name);
1019
1020 if (stat(path, &st) < 0)
1021 return NULL;
1022
1023 return fopen(path, "r");
1024}
1025
1026int perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt,
1027 ...)
1028{
1029 va_list args;
1030 FILE *file;
1031 int ret = EOF;
1032
1033 va_start(args, fmt);
1034 file = perf_pmu__open_file(pmu, name);
1035 if (file) {
1036 ret = vfscanf(file, fmt, args);
1037 fclose(file);
1038 }
1039 va_end(args);
1040 return ret;
1041}