hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/tools/perf/util/parse-events.c
....@@ -1,6 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0
22 #include <linux/hw_breakpoint.h>
33 #include <linux/err.h>
4
+#include <linux/zalloc.h>
45 #include <dirent.h>
56 #include <errno.h>
67 #include <sys/ioctl.h>
....@@ -9,30 +10,34 @@
910 #include <fcntl.h>
1011 #include <sys/param.h>
1112 #include "term.h"
12
-#include "../perf.h"
13
+#include "build-id.h"
1314 #include "evlist.h"
1415 #include "evsel.h"
16
+#include <subcmd/pager.h>
1517 #include <subcmd/parse-options.h>
1618 #include "parse-events.h"
1719 #include <subcmd/exec-cmd.h>
1820 #include "string2.h"
1921 #include "strlist.h"
2022 #include "symbol.h"
21
-#include "cache.h"
2223 #include "header.h"
2324 #include "bpf-loader.h"
2425 #include "debug.h"
2526 #include <api/fs/tracing_path.h>
27
+#include <perf/cpumap.h>
2628 #include "parse-events-bison.h"
27
-#define YY_EXTRA_TYPE int
29
+#define YY_EXTRA_TYPE void*
2830 #include "parse-events-flex.h"
2931 #include "pmu.h"
3032 #include "thread_map.h"
31
-#include "cpumap.h"
3233 #include "probe-file.h"
3334 #include "asm/bug.h"
3435 #include "util/parse-branch-options.h"
3536 #include "metricgroup.h"
37
+#include "util/evsel_config.h"
38
+#include "util/event.h"
39
+#include "util/pfm.h"
40
+#include "perf.h"
3641
3742 #define MAX_NAME_LEN 100
3843
....@@ -179,6 +184,38 @@
179184
180185 #define MAX_EVENT_LENGTH 512
181186
187
+void parse_events__handle_error(struct parse_events_error *err, int idx,
188
+ char *str, char *help)
189
+{
190
+ if (WARN(!str, "WARNING: failed to provide error string\n")) {
191
+ free(help);
192
+ return;
193
+ }
194
+ switch (err->num_errors) {
195
+ case 0:
196
+ err->idx = idx;
197
+ err->str = str;
198
+ err->help = help;
199
+ break;
200
+ case 1:
201
+ err->first_idx = err->idx;
202
+ err->idx = idx;
203
+ err->first_str = err->str;
204
+ err->str = str;
205
+ err->first_help = err->help;
206
+ err->help = help;
207
+ break;
208
+ default:
209
+ pr_debug("Multiple errors dropping message: %s (%s)\n",
210
+ err->str, err->help);
211
+ free(err->str);
212
+ err->str = str;
213
+ free(err->help);
214
+ err->help = help;
215
+ break;
216
+ }
217
+ err->num_errors++;
218
+}
182219
183220 struct tracepoint_path *tracepoint_id_to_path(u64 config)
184221 {
....@@ -223,21 +260,15 @@
223260 path = zalloc(sizeof(*path));
224261 if (!path)
225262 return NULL;
226
- path->system = malloc(MAX_EVENT_LENGTH);
227
- if (!path->system) {
263
+ if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) {
228264 free(path);
229265 return NULL;
230266 }
231
- path->name = malloc(MAX_EVENT_LENGTH);
232
- if (!path->name) {
267
+ if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) {
233268 zfree(&path->system);
234269 free(path);
235270 return NULL;
236271 }
237
- strncpy(path->system, sys_dirent->d_name,
238
- MAX_EVENT_LENGTH);
239
- strncpy(path->name, evt_dirent->d_name,
240
- MAX_EVENT_LENGTH);
241272 return path;
242273 }
243274 }
....@@ -313,25 +344,37 @@
313344 return NULL;
314345 }
315346
316
-static struct perf_evsel *
347
+static struct evsel *
317348 __add_event(struct list_head *list, int *idx,
318349 struct perf_event_attr *attr,
350
+ bool init_attr,
319351 char *name, struct perf_pmu *pmu,
320
- struct list_head *config_terms, bool auto_merge_stats)
352
+ struct list_head *config_terms, bool auto_merge_stats,
353
+ const char *cpu_list)
321354 {
322
- struct perf_evsel *evsel;
323
- struct cpu_map *cpus = pmu ? pmu->cpus : NULL;
355
+ struct evsel *evsel;
356
+ struct perf_cpu_map *cpus = pmu ? perf_cpu_map__get(pmu->cpus) :
357
+ cpu_list ? perf_cpu_map__new(cpu_list) : NULL;
324358
325
- event_attr_init(attr);
359
+ if (pmu)
360
+ perf_pmu__warn_invalid_formats(pmu);
326361
327
- evsel = perf_evsel__new_idx(attr, *idx);
328
- if (!evsel)
362
+ if (pmu && attr->type == PERF_TYPE_RAW)
363
+ perf_pmu__warn_invalid_config(pmu, attr->config, name);
364
+
365
+ if (init_attr)
366
+ event_attr_init(attr);
367
+
368
+ evsel = evsel__new_idx(attr, *idx);
369
+ if (!evsel) {
370
+ perf_cpu_map__put(cpus);
329371 return NULL;
372
+ }
330373
331374 (*idx)++;
332
- evsel->cpus = cpu_map__get(cpus);
333
- evsel->own_cpus = cpu_map__get(cpus);
334
- evsel->system_wide = pmu ? pmu->is_uncore : false;
375
+ evsel->core.cpus = cpus;
376
+ evsel->core.own_cpus = perf_cpu_map__get(cpus);
377
+ evsel->core.system_wide = pmu ? pmu->is_uncore : false;
335378 evsel->auto_merge_stats = auto_merge_stats;
336379
337380 if (name)
....@@ -340,24 +383,53 @@
340383 if (config_terms)
341384 list_splice(config_terms, &evsel->config_terms);
342385
343
- list_add_tail(&evsel->node, list);
386
+ if (list)
387
+ list_add_tail(&evsel->core.node, list);
388
+
344389 return evsel;
390
+}
391
+
392
+struct evsel *parse_events__add_event(int idx, struct perf_event_attr *attr,
393
+ char *name, struct perf_pmu *pmu)
394
+{
395
+ return __add_event(NULL, &idx, attr, false, name, pmu, NULL, false,
396
+ NULL);
345397 }
346398
347399 static int add_event(struct list_head *list, int *idx,
348400 struct perf_event_attr *attr, char *name,
349401 struct list_head *config_terms)
350402 {
351
- return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM;
403
+ return __add_event(list, idx, attr, true, name, NULL, config_terms,
404
+ false, NULL) ? 0 : -ENOMEM;
352405 }
353406
354
-static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
407
+static int add_event_tool(struct list_head *list, int *idx,
408
+ enum perf_tool_event tool_event)
409
+{
410
+ struct evsel *evsel;
411
+ struct perf_event_attr attr = {
412
+ .type = PERF_TYPE_SOFTWARE,
413
+ .config = PERF_COUNT_SW_DUMMY,
414
+ };
415
+
416
+ evsel = __add_event(list, idx, &attr, true, NULL, NULL, NULL, false,
417
+ "0");
418
+ if (!evsel)
419
+ return -ENOMEM;
420
+ evsel->tool_event = tool_event;
421
+ if (tool_event == PERF_TOOL_DURATION_TIME)
422
+ evsel->unit = "ns";
423
+ return 0;
424
+}
425
+
426
+static int parse_aliases(char *str, const char *names[][EVSEL__MAX_ALIASES], int size)
355427 {
356428 int i, j;
357429 int n, longest = -1;
358430
359431 for (i = 0; i < size; i++) {
360
- for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) {
432
+ for (j = 0; j < EVSEL__MAX_ALIASES && names[i][j]; j++) {
361433 n = strlen(names[i][j]);
362434 if (n > longest && !strncasecmp(str, names[i][j], n))
363435 longest = n;
....@@ -396,8 +468,7 @@
396468 * No fallback - if we cannot get a clear cache type
397469 * then bail out:
398470 */
399
- cache_type = parse_aliases(type, perf_evsel__hw_cache,
400
- PERF_COUNT_HW_CACHE_MAX);
471
+ cache_type = parse_aliases(type, evsel__hw_cache, PERF_COUNT_HW_CACHE_MAX);
401472 if (cache_type == -1)
402473 return -EINVAL;
403474
....@@ -410,17 +481,17 @@
410481 n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str);
411482
412483 if (cache_op == -1) {
413
- cache_op = parse_aliases(str, perf_evsel__hw_cache_op,
484
+ cache_op = parse_aliases(str, evsel__hw_cache_op,
414485 PERF_COUNT_HW_CACHE_OP_MAX);
415486 if (cache_op >= 0) {
416
- if (!perf_evsel__is_cache_op_valid(cache_type, cache_op))
487
+ if (!evsel__is_cache_op_valid(cache_type, cache_op))
417488 return -EINVAL;
418489 continue;
419490 }
420491 }
421492
422493 if (cache_result == -1) {
423
- cache_result = parse_aliases(str, perf_evsel__hw_cache_result,
494
+ cache_result = parse_aliases(str, evsel__hw_cache_result,
424495 PERF_COUNT_HW_CACHE_RESULT_MAX);
425496 if (cache_result >= 0)
426497 continue;
....@@ -457,6 +528,7 @@
457528 static void tracepoint_error(struct parse_events_error *e, int err,
458529 const char *sys, const char *name)
459530 {
531
+ const char *str;
460532 char help[BUFSIZ];
461533
462534 if (!e)
....@@ -470,18 +542,18 @@
470542
471543 switch (err) {
472544 case EACCES:
473
- e->str = strdup("can't access trace events");
545
+ str = "can't access trace events";
474546 break;
475547 case ENOENT:
476
- e->str = strdup("unknown tracepoint");
548
+ str = "unknown tracepoint";
477549 break;
478550 default:
479
- e->str = strdup("failed to add tracepoint");
551
+ str = "failed to add tracepoint";
480552 break;
481553 }
482554
483555 tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name);
484
- e->help = strdup(help);
556
+ parse_events__handle_error(e, 0, strdup(str), strdup(help));
485557 }
486558
487559 static int add_tracepoint(struct list_head *list, int *idx,
....@@ -489,9 +561,8 @@
489561 struct parse_events_error *err,
490562 struct list_head *head_config)
491563 {
492
- struct perf_evsel *evsel;
564
+ struct evsel *evsel = evsel__newtp_idx(sys_name, evt_name, (*idx)++);
493565
494
- evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
495566 if (IS_ERR(evsel)) {
496567 tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name);
497568 return PTR_ERR(evsel);
....@@ -505,7 +576,7 @@
505576 list_splice(&config_terms, &evsel->config_terms);
506577 }
507578
508
- list_add_tail(&evsel->node, list);
579
+ list_add_tail(&evsel->core.node, list);
509580 return 0;
510581 }
511582
....@@ -609,15 +680,24 @@
609680 struct list_head *head_config;
610681 };
611682
612
-static int add_bpf_event(const char *group, const char *event, int fd,
683
+static int add_bpf_event(const char *group, const char *event, int fd, struct bpf_object *obj,
613684 void *_param)
614685 {
615686 LIST_HEAD(new_evsels);
616687 struct __add_bpf_event_param *param = _param;
617688 struct parse_events_state *parse_state = param->parse_state;
618689 struct list_head *list = param->list;
619
- struct perf_evsel *pos;
690
+ struct evsel *pos;
620691 int err;
692
+ /*
693
+ * Check if we should add the event, i.e. if it is a TP but starts with a '!',
694
+ * then don't add the tracepoint, this will be used for something else, like
695
+ * adding to a BPF_MAP_TYPE_PROG_ARRAY.
696
+ *
697
+ * See tools/perf/examples/bpf/augmented_raw_syscalls.c
698
+ */
699
+ if (group[0] == '!')
700
+ return 0;
621701
622702 pr_debug("add bpf event %s:%s and attach bpf program %d\n",
623703 group, event, fd);
....@@ -626,22 +706,23 @@
626706 event, parse_state->error,
627707 param->head_config);
628708 if (err) {
629
- struct perf_evsel *evsel, *tmp;
709
+ struct evsel *evsel, *tmp;
630710
631711 pr_debug("Failed to add BPF event %s:%s\n",
632712 group, event);
633
- list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
634
- list_del(&evsel->node);
635
- perf_evsel__delete(evsel);
713
+ list_for_each_entry_safe(evsel, tmp, &new_evsels, core.node) {
714
+ list_del_init(&evsel->core.node);
715
+ evsel__delete(evsel);
636716 }
637717 return err;
638718 }
639719 pr_debug("adding %s:%s\n", group, event);
640720
641
- list_for_each_entry(pos, &new_evsels, node) {
721
+ list_for_each_entry(pos, &new_evsels, core.node) {
642722 pr_debug("adding %s:%s to %p\n",
643723 group, event, pos);
644724 pos->bpf_fd = fd;
725
+ pos->bpf_obj = obj;
645726 }
646727 list_splice(&new_evsels, list);
647728 return 0;
....@@ -695,8 +776,8 @@
695776
696777 return 0;
697778 errout:
698
- parse_state->error->help = strdup("(add -v to see detail)");
699
- parse_state->error->str = strdup(errbuf);
779
+ parse_events__handle_error(parse_state->error, 0,
780
+ strdup(errbuf), strdup("(add -v to see detail)"));
700781 return err;
701782 }
702783
....@@ -712,36 +793,38 @@
712793 return 0;
713794
714795 list_for_each_entry(term, head_config, list) {
715
- char errbuf[BUFSIZ];
716796 int err;
717797
718798 if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) {
719
- snprintf(errbuf, sizeof(errbuf),
720
- "Invalid config term for BPF object");
721
- errbuf[BUFSIZ - 1] = '\0';
722
-
723
- parse_state->error->idx = term->err_term;
724
- parse_state->error->str = strdup(errbuf);
799
+ parse_events__handle_error(parse_state->error, term->err_term,
800
+ strdup("Invalid config term for BPF object"),
801
+ NULL);
725802 return -EINVAL;
726803 }
727804
728805 err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos);
729806 if (err) {
807
+ char errbuf[BUFSIZ];
808
+ int idx;
809
+
730810 bpf__strerror_config_obj(obj, term, parse_state->evlist,
731811 &error_pos, err, errbuf,
732812 sizeof(errbuf));
733
- parse_state->error->help = strdup(
813
+
814
+ if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
815
+ idx = term->err_val;
816
+ else
817
+ idx = term->err_term + error_pos;
818
+
819
+ parse_events__handle_error(parse_state->error, idx,
820
+ strdup(errbuf),
821
+ strdup(
734822 "Hint:\tValid config terms:\n"
735823 " \tmap:[<arraymap>].value<indices>=[value]\n"
736824 " \tmap:[<eventmap>].event<indices>=[event]\n"
737825 "\n"
738826 " \twhere <indices> is something like [0,3...5] or [all]\n"
739
-" \t(add -v to see detail)");
740
- parse_state->error->str = strdup(errbuf);
741
- if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
742
- parse_state->error->idx = term->err_val;
743
- else
744
- parse_state->error->idx = term->err_term + error_pos;
827
+" \t(add -v to see detail)"));
745828 return err;
746829 }
747830 }
....@@ -805,8 +888,8 @@
805888 -err, errbuf,
806889 sizeof(errbuf));
807890
808
- parse_state->error->help = strdup("(add -v to see detail)");
809
- parse_state->error->str = strdup(errbuf);
891
+ parse_events__handle_error(parse_state->error, 0,
892
+ strdup(errbuf), strdup("(add -v to see detail)"));
810893 return err;
811894 }
812895
....@@ -865,12 +948,12 @@
865948 }
866949
867950 int parse_events_add_breakpoint(struct list_head *list, int *idx,
868
- void *ptr, char *type, u64 len)
951
+ u64 addr, char *type, u64 len)
869952 {
870953 struct perf_event_attr attr;
871954
872955 memset(&attr, 0, sizeof(attr));
873
- attr.bp_addr = (unsigned long) ptr;
956
+ attr.bp_addr = addr;
874957
875958 if (parse_breakpoint_type(type, &attr))
876959 return -EINVAL;
....@@ -899,11 +982,11 @@
899982 return 0;
900983
901984 if (err) {
902
- err->idx = term->err_val;
903
- if (type == PARSE_EVENTS__TERM_TYPE_NUM)
904
- err->str = strdup("expected numeric value");
905
- else
906
- err->str = strdup("expected string value");
985
+ parse_events__handle_error(err, term->err_val,
986
+ type == PARSE_EVENTS__TERM_TYPE_NUM
987
+ ? strdup("expected numeric value")
988
+ : strdup("expected string value"),
989
+ NULL);
907990 }
908991 return -EINVAL;
909992 }
....@@ -926,9 +1009,13 @@
9261009 [PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit",
9271010 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
9281011 [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack",
1012
+ [PARSE_EVENTS__TERM_TYPE_MAX_EVENTS] = "nr",
9291013 [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
9301014 [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
9311015 [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config",
1016
+ [PARSE_EVENTS__TERM_TYPE_PERCORE] = "percore",
1017
+ [PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT] = "aux-output",
1018
+ [PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE] = "aux-sample-size",
9321019 };
9331020
9341021 static bool config_term_shrinked;
....@@ -936,8 +1023,11 @@
9361023 static bool
9371024 config_term_avail(int term_type, struct parse_events_error *err)
9381025 {
1026
+ char *err_str;
1027
+
9391028 if (term_type < 0 || term_type >= __PARSE_EVENTS__TERM_TYPE_NR) {
940
- err->str = strdup("Invalid term_type");
1029
+ parse_events__handle_error(err, -1,
1030
+ strdup("Invalid term_type"), NULL);
9411031 return false;
9421032 }
9431033 if (!config_term_shrinked)
....@@ -949,15 +1039,16 @@
9491039 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
9501040 case PARSE_EVENTS__TERM_TYPE_NAME:
9511041 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
1042
+ case PARSE_EVENTS__TERM_TYPE_PERCORE:
9521043 return true;
9531044 default:
9541045 if (!err)
9551046 return false;
9561047
9571048 /* term_type is validated so indexing is safe */
958
- if (asprintf(&err->str, "'%s' is not usable in 'perf stat'",
959
- config_term_names[term_type]) < 0)
960
- err->str = NULL;
1049
+ if (asprintf(&err_str, "'%s' is not usable in 'perf stat'",
1050
+ config_term_names[term_type]) >= 0)
1051
+ parse_events__handle_error(err, -1, err_str, NULL);
9611052 return false;
9621053 }
9631054 }
....@@ -999,17 +1090,20 @@
9991090 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
10001091 CHECK_TYPE_VAL(STR);
10011092 if (strcmp(term->val.str, "no") &&
1002
- parse_branch_str(term->val.str, &attr->branch_sample_type)) {
1003
- err->str = strdup("invalid branch sample type");
1004
- err->idx = term->err_val;
1093
+ parse_branch_str(term->val.str,
1094
+ &attr->branch_sample_type)) {
1095
+ parse_events__handle_error(err, term->err_val,
1096
+ strdup("invalid branch sample type"),
1097
+ NULL);
10051098 return -EINVAL;
10061099 }
10071100 break;
10081101 case PARSE_EVENTS__TERM_TYPE_TIME:
10091102 CHECK_TYPE_VAL(NUM);
10101103 if (term->val.num > 1) {
1011
- err->str = strdup("expected 0 or 1");
1012
- err->idx = term->err_val;
1104
+ parse_events__handle_error(err, term->err_val,
1105
+ strdup("expected 0 or 1"),
1106
+ NULL);
10131107 return -EINVAL;
10141108 }
10151109 break;
....@@ -1037,10 +1131,34 @@
10371131 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
10381132 CHECK_TYPE_VAL(NUM);
10391133 break;
1134
+ case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
1135
+ CHECK_TYPE_VAL(NUM);
1136
+ break;
1137
+ case PARSE_EVENTS__TERM_TYPE_PERCORE:
1138
+ CHECK_TYPE_VAL(NUM);
1139
+ if ((unsigned int)term->val.num > 1) {
1140
+ parse_events__handle_error(err, term->err_val,
1141
+ strdup("expected 0 or 1"),
1142
+ NULL);
1143
+ return -EINVAL;
1144
+ }
1145
+ break;
1146
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
1147
+ CHECK_TYPE_VAL(NUM);
1148
+ break;
1149
+ case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
1150
+ CHECK_TYPE_VAL(NUM);
1151
+ if (term->val.num > UINT_MAX) {
1152
+ parse_events__handle_error(err, term->err_val,
1153
+ strdup("too big"),
1154
+ NULL);
1155
+ return -EINVAL;
1156
+ }
1157
+ break;
10401158 default:
1041
- err->str = strdup("unknown term");
1042
- err->idx = term->err_term;
1043
- err->help = parse_events_formats_error_string(NULL);
1159
+ parse_events__handle_error(err, term->err_term,
1160
+ strdup("unknown term"),
1161
+ parse_events_formats_error_string(NULL));
10441162 return -EINVAL;
10451163 }
10461164
....@@ -1084,14 +1202,17 @@
10841202 case PARSE_EVENTS__TERM_TYPE_INHERIT:
10851203 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
10861204 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1205
+ case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
10871206 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
10881207 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1208
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
1209
+ case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
10891210 return config_term_common(attr, term, err);
10901211 default:
10911212 if (err) {
1092
- err->idx = term->err_term;
1093
- err->str = strdup("unknown term");
1094
- err->help = strdup("valid terms: call-graph,stack-size\n");
1213
+ parse_events__handle_error(err, term->err_term,
1214
+ strdup("unknown term"),
1215
+ strdup("valid terms: call-graph,stack-size\n"));
10951216 }
10961217 return -EINVAL;
10971218 }
....@@ -1116,19 +1237,33 @@
11161237 static int get_config_terms(struct list_head *head_config,
11171238 struct list_head *head_terms __maybe_unused)
11181239 {
1119
-#define ADD_CONFIG_TERM(__type, __name, __val) \
1120
-do { \
1121
- struct perf_evsel_config_term *__t; \
1240
+#define ADD_CONFIG_TERM(__type, __weak) \
1241
+ struct evsel_config_term *__t; \
11221242 \
11231243 __t = zalloc(sizeof(*__t)); \
11241244 if (!__t) \
11251245 return -ENOMEM; \
11261246 \
11271247 INIT_LIST_HEAD(&__t->list); \
1128
- __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \
1248
+ __t->type = EVSEL__CONFIG_TERM_ ## __type; \
1249
+ __t->weak = __weak; \
1250
+ list_add_tail(&__t->list, head_terms)
1251
+
1252
+#define ADD_CONFIG_TERM_VAL(__type, __name, __val, __weak) \
1253
+do { \
1254
+ ADD_CONFIG_TERM(__type, __weak); \
11291255 __t->val.__name = __val; \
1130
- __t->weak = term->weak; \
1131
- list_add_tail(&__t->list, head_terms); \
1256
+} while (0)
1257
+
1258
+#define ADD_CONFIG_TERM_STR(__type, __val, __weak) \
1259
+do { \
1260
+ ADD_CONFIG_TERM(__type, __weak); \
1261
+ __t->val.str = strdup(__val); \
1262
+ if (!__t->val.str) { \
1263
+ zfree(&__t); \
1264
+ return -ENOMEM; \
1265
+ } \
1266
+ __t->free_str = true; \
11321267 } while (0)
11331268
11341269 struct parse_events_term *term;
....@@ -1136,46 +1271,101 @@
11361271 list_for_each_entry(term, head_config, list) {
11371272 switch (term->type_term) {
11381273 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
1139
- ADD_CONFIG_TERM(PERIOD, period, term->val.num);
1274
+ ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num, term->weak);
11401275 break;
11411276 case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
1142
- ADD_CONFIG_TERM(FREQ, freq, term->val.num);
1277
+ ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num, term->weak);
11431278 break;
11441279 case PARSE_EVENTS__TERM_TYPE_TIME:
1145
- ADD_CONFIG_TERM(TIME, time, term->val.num);
1280
+ ADD_CONFIG_TERM_VAL(TIME, time, term->val.num, term->weak);
11461281 break;
11471282 case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
1148
- ADD_CONFIG_TERM(CALLGRAPH, callgraph, term->val.str);
1283
+ ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str, term->weak);
11491284 break;
11501285 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
1151
- ADD_CONFIG_TERM(BRANCH, branch, term->val.str);
1286
+ ADD_CONFIG_TERM_STR(BRANCH, term->val.str, term->weak);
11521287 break;
11531288 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
1154
- ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num);
1289
+ ADD_CONFIG_TERM_VAL(STACK_USER, stack_user,
1290
+ term->val.num, term->weak);
11551291 break;
11561292 case PARSE_EVENTS__TERM_TYPE_INHERIT:
1157
- ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 1 : 0);
1293
+ ADD_CONFIG_TERM_VAL(INHERIT, inherit,
1294
+ term->val.num ? 1 : 0, term->weak);
11581295 break;
11591296 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
1160
- ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
1297
+ ADD_CONFIG_TERM_VAL(INHERIT, inherit,
1298
+ term->val.num ? 0 : 1, term->weak);
11611299 break;
11621300 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1163
- ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
1301
+ ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack,
1302
+ term->val.num, term->weak);
1303
+ break;
1304
+ case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
1305
+ ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events,
1306
+ term->val.num, term->weak);
11641307 break;
11651308 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
1166
- ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 1 : 0);
1309
+ ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
1310
+ term->val.num ? 1 : 0, term->weak);
11671311 break;
11681312 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1169
- ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
1313
+ ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
1314
+ term->val.num ? 0 : 1, term->weak);
11701315 break;
11711316 case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
1172
- ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
1317
+ ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str, term->weak);
1318
+ break;
1319
+ case PARSE_EVENTS__TERM_TYPE_PERCORE:
1320
+ ADD_CONFIG_TERM_VAL(PERCORE, percore,
1321
+ term->val.num ? true : false, term->weak);
1322
+ break;
1323
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
1324
+ ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output,
1325
+ term->val.num ? 1 : 0, term->weak);
1326
+ break;
1327
+ case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
1328
+ ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size,
1329
+ term->val.num, term->weak);
11731330 break;
11741331 default:
11751332 break;
11761333 }
11771334 }
1178
-#undef ADD_EVSEL_CONFIG
1335
+ return 0;
1336
+}
1337
+
1338
+/*
1339
+ * Add EVSEL__CONFIG_TERM_CFG_CHG where cfg_chg will have a bit set for
1340
+ * each bit of attr->config that the user has changed.
1341
+ */
1342
+static int get_config_chgs(struct perf_pmu *pmu, struct list_head *head_config,
1343
+ struct list_head *head_terms)
1344
+{
1345
+ struct parse_events_term *term;
1346
+ u64 bits = 0;
1347
+ int type;
1348
+
1349
+ list_for_each_entry(term, head_config, list) {
1350
+ switch (term->type_term) {
1351
+ case PARSE_EVENTS__TERM_TYPE_USER:
1352
+ type = perf_pmu__format_type(&pmu->format, term->config);
1353
+ if (type != PERF_PMU_FORMAT_VALUE_CONFIG)
1354
+ continue;
1355
+ bits |= perf_pmu__format_bits(&pmu->format, term->config);
1356
+ break;
1357
+ case PARSE_EVENTS__TERM_TYPE_CONFIG:
1358
+ bits = ~(u64)0;
1359
+ break;
1360
+ default:
1361
+ break;
1362
+ }
1363
+ }
1364
+
1365
+ if (bits)
1366
+ ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits, false);
1367
+
1368
+#undef ADD_CONFIG_TERM
11791369 return 0;
11801370 }
11811371
....@@ -1225,6 +1415,25 @@
12251415 get_config_name(head_config), &config_terms);
12261416 }
12271417
1418
+int parse_events_add_tool(struct parse_events_state *parse_state,
1419
+ struct list_head *list,
1420
+ enum perf_tool_event tool_event)
1421
+{
1422
+ return add_event_tool(list, &parse_state->idx, tool_event);
1423
+}
1424
+
1425
+static bool config_term_percore(struct list_head *config_terms)
1426
+{
1427
+ struct evsel_config_term *term;
1428
+
1429
+ list_for_each_entry(term, config_terms, list) {
1430
+ if (term->type == EVSEL__CONFIG_TERM_PERCORE)
1431
+ return term->val.percore;
1432
+ }
1433
+
1434
+ return false;
1435
+}
1436
+
12281437 int parse_events_add_pmu(struct parse_events_state *parse_state,
12291438 struct list_head *list, char *name,
12301439 struct list_head *head_config,
....@@ -1234,17 +1443,33 @@
12341443 struct perf_event_attr attr;
12351444 struct perf_pmu_info info;
12361445 struct perf_pmu *pmu;
1237
- struct perf_evsel *evsel;
1446
+ struct evsel *evsel;
12381447 struct parse_events_error *err = parse_state->error;
12391448 bool use_uncore_alias;
12401449 LIST_HEAD(config_terms);
12411450
1242
- pmu = perf_pmu__find(name);
1451
+ pmu = parse_state->fake_pmu ?: perf_pmu__find(name);
1452
+
1453
+ if (verbose > 1 && !(pmu && pmu->selectable)) {
1454
+ fprintf(stderr, "Attempting to add event pmu '%s' with '",
1455
+ name);
1456
+ if (head_config) {
1457
+ struct parse_events_term *term;
1458
+
1459
+ list_for_each_entry(term, head_config, list) {
1460
+ fprintf(stderr, "%s,", term->config);
1461
+ }
1462
+ }
1463
+ fprintf(stderr, "' that may result in non-fatal errors\n");
1464
+ }
1465
+
12431466 if (!pmu) {
1244
- if (asprintf(&err->str,
1467
+ char *err_str;
1468
+
1469
+ if (asprintf(&err_str,
12451470 "Cannot find PMU `%s'. Missing kernel support?",
1246
- name) < 0)
1247
- err->str = NULL;
1471
+ name) >= 0)
1472
+ parse_events__handle_error(err, 0, err_str, NULL);
12481473 return -EINVAL;
12491474 }
12501475
....@@ -1259,7 +1484,8 @@
12591484
12601485 if (!head_config) {
12611486 attr.type = pmu->type;
1262
- evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats);
1487
+ evsel = __add_event(list, &parse_state->idx, &attr, true, NULL,
1488
+ pmu, NULL, auto_merge_stats, NULL);
12631489 if (evsel) {
12641490 evsel->pmu_name = name ? strdup(name) : NULL;
12651491 evsel->use_uncore_alias = use_uncore_alias;
....@@ -1269,8 +1495,21 @@
12691495 }
12701496 }
12711497
1272
- if (perf_pmu__check_alias(pmu, head_config, &info))
1498
+ if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
12731499 return -EINVAL;
1500
+
1501
+ if (verbose > 1) {
1502
+ fprintf(stderr, "After aliases, add event pmu '%s' with '",
1503
+ name);
1504
+ if (head_config) {
1505
+ struct parse_events_term *term;
1506
+
1507
+ list_for_each_entry(term, head_config, list) {
1508
+ fprintf(stderr, "%s,", term->config);
1509
+ }
1510
+ }
1511
+ fprintf(stderr, "' that may result in non-fatal errors\n");
1512
+ }
12741513
12751514 /*
12761515 * Configure hardcoded terms first, no need to check
....@@ -1282,37 +1521,50 @@
12821521 if (get_config_terms(head_config, &config_terms))
12831522 return -ENOMEM;
12841523
1285
- if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
1286
- struct perf_evsel_config_term *pos, *tmp;
1524
+ /*
1525
+ * When using default config, record which bits of attr->config were
1526
+ * changed by the user.
1527
+ */
1528
+ if (pmu->default_config && get_config_chgs(pmu, head_config, &config_terms))
1529
+ return -ENOMEM;
1530
+
1531
+ if (!parse_state->fake_pmu && perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
1532
+ struct evsel_config_term *pos, *tmp;
12871533
12881534 list_for_each_entry_safe(pos, tmp, &config_terms, list) {
12891535 list_del_init(&pos->list);
1536
+ if (pos->free_str)
1537
+ zfree(&pos->val.str);
12901538 free(pos);
12911539 }
12921540 return -EINVAL;
12931541 }
12941542
1295
- evsel = __add_event(list, &parse_state->idx, &attr,
1543
+ evsel = __add_event(list, &parse_state->idx, &attr, true,
12961544 get_config_name(head_config), pmu,
1297
- &config_terms, auto_merge_stats);
1298
- if (evsel) {
1299
- evsel->unit = info.unit;
1300
- evsel->scale = info.scale;
1301
- evsel->per_pkg = info.per_pkg;
1302
- evsel->snapshot = info.snapshot;
1303
- evsel->metric_expr = info.metric_expr;
1304
- evsel->metric_name = info.metric_name;
1305
- evsel->pmu_name = name ? strdup(name) : NULL;
1306
- evsel->use_uncore_alias = use_uncore_alias;
1307
- }
1545
+ &config_terms, auto_merge_stats, NULL);
1546
+ if (!evsel)
1547
+ return -ENOMEM;
13081548
1309
- return evsel ? 0 : -ENOMEM;
1549
+ evsel->pmu_name = name ? strdup(name) : NULL;
1550
+ evsel->use_uncore_alias = use_uncore_alias;
1551
+ evsel->percore = config_term_percore(&evsel->config_terms);
1552
+
1553
+ if (parse_state->fake_pmu)
1554
+ return 0;
1555
+
1556
+ evsel->unit = info.unit;
1557
+ evsel->scale = info.scale;
1558
+ evsel->per_pkg = info.per_pkg;
1559
+ evsel->snapshot = info.snapshot;
1560
+ evsel->metric_expr = info.metric_expr;
1561
+ evsel->metric_name = info.metric_name;
1562
+ return 0;
13101563 }
13111564
13121565 int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
13131566 char *str, struct list_head **listp)
13141567 {
1315
- struct list_head *head;
13161568 struct parse_events_term *term;
13171569 struct list_head *list;
13181570 struct perf_pmu *pmu = NULL;
....@@ -1329,13 +1581,24 @@
13291581
13301582 list_for_each_entry(alias, &pmu->aliases, list) {
13311583 if (!strcasecmp(alias->name, str)) {
1584
+ struct list_head *head;
1585
+ char *config;
1586
+
13321587 head = malloc(sizeof(struct list_head));
13331588 if (!head)
13341589 return -1;
13351590 INIT_LIST_HEAD(head);
1336
- if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
1337
- str, 1, false, &str, NULL) < 0)
1591
+ config = strdup(str);
1592
+ if (!config)
13381593 return -1;
1594
+ if (parse_events_term__num(&term,
1595
+ PARSE_EVENTS__TERM_TYPE_USER,
1596
+ config, 1, false, &config,
1597
+ NULL) < 0) {
1598
+ free(list);
1599
+ free(config);
1600
+ return -1;
1601
+ }
13391602 list_add_tail(&term->list, head);
13401603
13411604 if (!parse_events_add_pmu(parse_state, list,
....@@ -1350,8 +1613,10 @@
13501613 }
13511614 }
13521615 }
1353
- if (!ok)
1616
+ if (!ok) {
1617
+ free(list);
13541618 return -1;
1619
+ }
13551620 *listp = list;
13561621 return 0;
13571622 }
....@@ -1386,13 +1651,13 @@
13861651 parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
13871652 struct parse_events_state *parse_state)
13881653 {
1389
- struct perf_evsel *evsel, *leader;
1654
+ struct evsel *evsel, *leader;
13901655 uintptr_t *leaders;
13911656 bool is_leader = true;
13921657 int i, nr_pmu = 0, total_members, ret = 0;
13931658
1394
- leader = list_first_entry(list, struct perf_evsel, node);
1395
- evsel = list_last_entry(list, struct perf_evsel, node);
1659
+ leader = list_first_entry(list, struct evsel, core.node);
1660
+ evsel = list_last_entry(list, struct evsel, core.node);
13961661 total_members = evsel->idx - leader->idx + 1;
13971662
13981663 leaders = calloc(total_members, sizeof(uintptr_t));
....@@ -1453,13 +1718,13 @@
14531718 __evlist__for_each_entry(list, evsel) {
14541719 if (i >= nr_pmu)
14551720 i = 0;
1456
- evsel->leader = (struct perf_evsel *) leaders[i++];
1721
+ evsel->leader = (struct evsel *) leaders[i++];
14571722 }
14581723
14591724 /* The number of members and group name are same for each group */
14601725 for (i = 0; i < nr_pmu; i++) {
1461
- evsel = (struct perf_evsel *) leaders[i];
1462
- evsel->nr_members = total_members / nr_pmu;
1726
+ evsel = (struct evsel *) leaders[i];
1727
+ evsel->core.nr_members = total_members / nr_pmu;
14631728 evsel->group_name = name ? strdup(name) : NULL;
14641729 }
14651730
....@@ -1476,7 +1741,7 @@
14761741 void parse_events__set_leader(char *name, struct list_head *list,
14771742 struct parse_events_state *parse_state)
14781743 {
1479
- struct perf_evsel *leader;
1744
+ struct evsel *leader;
14801745
14811746 if (list_empty(list)) {
14821747 WARN_ONCE(true, "WARNING: failed to set leader: empty list");
....@@ -1487,7 +1752,7 @@
14871752 return;
14881753
14891754 __perf_evlist__set_leader(list);
1490
- leader = list_entry(list->next, struct perf_evsel, node);
1755
+ leader = list_entry(list->next, struct evsel, core.node);
14911756 leader->group_name = name ? strdup(name) : NULL;
14921757 }
14931758
....@@ -1517,21 +1782,23 @@
15171782 int sample_read;
15181783 int pinned;
15191784 int weak;
1785
+ int exclusive;
15201786 };
15211787
15221788 static int get_event_modifier(struct event_modifier *mod, char *str,
1523
- struct perf_evsel *evsel)
1789
+ struct evsel *evsel)
15241790 {
1525
- int eu = evsel ? evsel->attr.exclude_user : 0;
1526
- int ek = evsel ? evsel->attr.exclude_kernel : 0;
1527
- int eh = evsel ? evsel->attr.exclude_hv : 0;
1528
- int eH = evsel ? evsel->attr.exclude_host : 0;
1529
- int eG = evsel ? evsel->attr.exclude_guest : 0;
1530
- int eI = evsel ? evsel->attr.exclude_idle : 0;
1531
- int precise = evsel ? evsel->attr.precise_ip : 0;
1791
+ int eu = evsel ? evsel->core.attr.exclude_user : 0;
1792
+ int ek = evsel ? evsel->core.attr.exclude_kernel : 0;
1793
+ int eh = evsel ? evsel->core.attr.exclude_hv : 0;
1794
+ int eH = evsel ? evsel->core.attr.exclude_host : 0;
1795
+ int eG = evsel ? evsel->core.attr.exclude_guest : 0;
1796
+ int eI = evsel ? evsel->core.attr.exclude_idle : 0;
1797
+ int precise = evsel ? evsel->core.attr.precise_ip : 0;
15321798 int precise_max = 0;
15331799 int sample_read = 0;
1534
- int pinned = evsel ? evsel->attr.pinned : 0;
1800
+ int pinned = evsel ? evsel->core.attr.pinned : 0;
1801
+ int exclusive = evsel ? evsel->core.attr.exclusive : 0;
15351802
15361803 int exclude = eu | ek | eh;
15371804 int exclude_GH = evsel ? evsel->exclude_GH : 0;
....@@ -1543,6 +1810,8 @@
15431810 if (*str == 'u') {
15441811 if (!exclude)
15451812 exclude = eu = ek = eh = 1;
1813
+ if (!exclude_GH && !perf_guest)
1814
+ eG = 1;
15461815 eu = 0;
15471816 } else if (*str == 'k') {
15481817 if (!exclude)
....@@ -1573,6 +1842,8 @@
15731842 sample_read = 1;
15741843 } else if (*str == 'D') {
15751844 pinned = 1;
1845
+ } else if (*str == 'e') {
1846
+ exclusive = 1;
15761847 } else if (*str == 'W') {
15771848 weak = 1;
15781849 } else
....@@ -1606,6 +1877,7 @@
16061877 mod->sample_read = sample_read;
16071878 mod->pinned = pinned;
16081879 mod->weak = weak;
1880
+ mod->exclusive = exclusive;
16091881
16101882 return 0;
16111883 }
....@@ -1619,7 +1891,7 @@
16191891 char *p = str;
16201892
16211893 /* The sizeof includes 0 byte as well. */
1622
- if (strlen(str) > (sizeof("ukhGHpppPSDIW") - 1))
1894
+ if (strlen(str) > (sizeof("ukhGHpppPSDIWe") - 1))
16231895 return -1;
16241896
16251897 while (*p) {
....@@ -1633,7 +1905,7 @@
16331905
16341906 int parse_events__modifier_event(struct list_head *list, char *str, bool add)
16351907 {
1636
- struct perf_evsel *evsel;
1908
+ struct evsel *evsel;
16371909 struct event_modifier mod;
16381910
16391911 if (str == NULL)
....@@ -1649,20 +1921,22 @@
16491921 if (add && get_event_modifier(&mod, str, evsel))
16501922 return -EINVAL;
16511923
1652
- evsel->attr.exclude_user = mod.eu;
1653
- evsel->attr.exclude_kernel = mod.ek;
1654
- evsel->attr.exclude_hv = mod.eh;
1655
- evsel->attr.precise_ip = mod.precise;
1656
- evsel->attr.exclude_host = mod.eH;
1657
- evsel->attr.exclude_guest = mod.eG;
1658
- evsel->attr.exclude_idle = mod.eI;
1924
+ evsel->core.attr.exclude_user = mod.eu;
1925
+ evsel->core.attr.exclude_kernel = mod.ek;
1926
+ evsel->core.attr.exclude_hv = mod.eh;
1927
+ evsel->core.attr.precise_ip = mod.precise;
1928
+ evsel->core.attr.exclude_host = mod.eH;
1929
+ evsel->core.attr.exclude_guest = mod.eG;
1930
+ evsel->core.attr.exclude_idle = mod.eI;
16591931 evsel->exclude_GH = mod.exclude_GH;
16601932 evsel->sample_read = mod.sample_read;
16611933 evsel->precise_max = mod.precise_max;
16621934 evsel->weak_group = mod.weak;
16631935
1664
- if (perf_evsel__is_group_leader(evsel))
1665
- evsel->attr.pinned = mod.pinned;
1936
+ if (evsel__is_group_leader(evsel)) {
1937
+ evsel->core.attr.pinned = mod.pinned;
1938
+ evsel->core.attr.exclusive = mod.exclusive;
1939
+ }
16661940 }
16671941
16681942 return 0;
....@@ -1670,7 +1944,7 @@
16701944
16711945 int parse_events_name(struct list_head *list, char *name)
16721946 {
1673
- struct perf_evsel *evsel;
1947
+ struct evsel *evsel;
16741948
16751949 __evlist__for_each_entry(list, evsel) {
16761950 if (!evsel->name)
....@@ -1768,6 +2042,32 @@
17682042 perf_pmu__parse_cleanup();
17692043 }
17702044
2045
+/*
2046
+ * This function injects special term in
2047
+ * perf_pmu_events_list so the test code
2048
+ * can check on this functionality.
2049
+ */
2050
+int perf_pmu__test_parse_init(void)
2051
+{
2052
+ struct perf_pmu_event_symbol *list;
2053
+
2054
+ list = malloc(sizeof(*list) * 1);
2055
+ if (!list)
2056
+ return -ENOMEM;
2057
+
2058
+ list->type = PMU_EVENT_SYMBOL;
2059
+ list->symbol = strdup("read");
2060
+
2061
+ if (!list->symbol) {
2062
+ free(list);
2063
+ return -ENOMEM;
2064
+ }
2065
+
2066
+ perf_pmu_events_list = list;
2067
+ perf_pmu_events_list_num = 1;
2068
+ return 0;
2069
+}
2070
+
17712071 enum perf_pmu_event_symbol_type
17722072 perf_pmu__parse_check(const char *name)
17732073 {
....@@ -1792,13 +2092,14 @@
17922092 return r ? r->type : PMU_EVENT_SYMBOL_ERR;
17932093 }
17942094
1795
-static int parse_events__scanner(const char *str, void *parse_state, int start_token)
2095
+static int parse_events__scanner(const char *str,
2096
+ struct parse_events_state *parse_state)
17962097 {
17972098 YY_BUFFER_STATE buffer;
17982099 void *scanner;
17992100 int ret;
18002101
1801
- ret = parse_events_lex_init_extra(start_token, &scanner);
2102
+ ret = parse_events_lex_init_extra(parse_state, &scanner);
18022103 if (ret)
18032104 return ret;
18042105
....@@ -1806,6 +2107,7 @@
18062107
18072108 #ifdef PARSER_DEBUG
18082109 parse_events_debug = 1;
2110
+ parse_events_set_debug(1, scanner);
18092111 #endif
18102112 ret = parse_events_parse(parse_state, scanner);
18112113
....@@ -1821,11 +2123,14 @@
18212123 int parse_events_terms(struct list_head *terms, const char *str)
18222124 {
18232125 struct parse_events_state parse_state = {
1824
- .terms = NULL,
2126
+ .terms = NULL,
2127
+ .stoken = PE_START_TERMS,
18252128 };
18262129 int ret;
18272130
1828
- ret = parse_events__scanner(str, &parse_state, PE_START_TERMS);
2131
+ ret = parse_events__scanner(str, &parse_state);
2132
+ perf_pmu__parse_cleanup();
2133
+
18292134 if (!ret) {
18302135 list_splice(parse_state.terms, terms);
18312136 zfree(&parse_state.terms);
....@@ -1836,18 +2141,20 @@
18362141 return ret;
18372142 }
18382143
1839
-int parse_events(struct perf_evlist *evlist, const char *str,
1840
- struct parse_events_error *err)
2144
+int __parse_events(struct evlist *evlist, const char *str,
2145
+ struct parse_events_error *err, struct perf_pmu *fake_pmu)
18412146 {
18422147 struct parse_events_state parse_state = {
1843
- .list = LIST_HEAD_INIT(parse_state.list),
1844
- .idx = evlist->nr_entries,
1845
- .error = err,
1846
- .evlist = evlist,
2148
+ .list = LIST_HEAD_INIT(parse_state.list),
2149
+ .idx = evlist->core.nr_entries,
2150
+ .error = err,
2151
+ .evlist = evlist,
2152
+ .stoken = PE_START_EVENTS,
2153
+ .fake_pmu = fake_pmu,
18472154 };
18482155 int ret;
18492156
1850
- ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS);
2157
+ ret = parse_events__scanner(str, &parse_state);
18512158 perf_pmu__parse_cleanup();
18522159
18532160 if (!ret && list_empty(&parse_state.list)) {
....@@ -1861,10 +2168,10 @@
18612168 perf_evlist__splice_list_tail(evlist, &parse_state.list);
18622169
18632170 if (!ret) {
1864
- struct perf_evsel *last;
2171
+ struct evsel *last;
18652172
18662173 evlist->nr_groups += parse_state.nr_groups;
1867
- last = perf_evlist__last(evlist);
2174
+ last = evlist__last(evlist);
18682175 last->cmdline_group_boundary = true;
18692176
18702177 return 0;
....@@ -1872,7 +2179,7 @@
18722179
18732180 /*
18742181 * There are 2 users - builtin-record and builtin-test objects.
1875
- * Both call perf_evlist__delete in case of error, so we dont
2182
+ * Both call evlist__delete in case of error, so we dont
18762183 * need to bother.
18772184 */
18782185 return ret;
....@@ -1887,15 +2194,14 @@
18872194 return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col;
18882195 }
18892196
1890
-void parse_events_print_error(struct parse_events_error *err,
1891
- const char *event)
2197
+static void __parse_events_print_error(int err_idx, const char *err_str,
2198
+ const char *err_help, const char *event)
18922199 {
18932200 const char *str = "invalid or unsupported event: ";
18942201 char _buf[MAX_WIDTH];
18952202 char *buf = (char *) event;
18962203 int idx = 0;
1897
-
1898
- if (err->str) {
2204
+ if (err_str) {
18992205 /* -2 for extra '' in the final fprintf */
19002206 int width = get_term_width() - 2;
19012207 int len_event = strlen(event);
....@@ -1918,8 +2224,8 @@
19182224 buf = _buf;
19192225
19202226 /* We're cutting from the beginning. */
1921
- if (err->idx > max_err_idx)
1922
- cut = err->idx - max_err_idx;
2227
+ if (err_idx > max_err_idx)
2228
+ cut = err_idx - max_err_idx;
19232229
19242230 strncpy(buf, event + cut, max_len);
19252231
....@@ -1932,16 +2238,33 @@
19322238 buf[max_len] = 0;
19332239 }
19342240
1935
- idx = len_str + err->idx - cut;
2241
+ idx = len_str + err_idx - cut;
19362242 }
19372243
19382244 fprintf(stderr, "%s'%s'\n", str, buf);
19392245 if (idx) {
1940
- fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str);
1941
- if (err->help)
1942
- fprintf(stderr, "\n%s\n", err->help);
1943
- zfree(&err->str);
1944
- zfree(&err->help);
2246
+ fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err_str);
2247
+ if (err_help)
2248
+ fprintf(stderr, "\n%s\n", err_help);
2249
+ }
2250
+}
2251
+
2252
+void parse_events_print_error(struct parse_events_error *err,
2253
+ const char *event)
2254
+{
2255
+ if (!err->num_errors)
2256
+ return;
2257
+
2258
+ __parse_events_print_error(err->idx, err->str, err->help, event);
2259
+ zfree(&err->str);
2260
+ zfree(&err->help);
2261
+
2262
+ if (err->num_errors > 1) {
2263
+ fputs("\nInitial error:\n", stderr);
2264
+ __parse_events_print_error(err->first_idx, err->first_str,
2265
+ err->first_help, event);
2266
+ zfree(&err->first_str);
2267
+ zfree(&err->first_help);
19452268 }
19462269 }
19472270
....@@ -1950,9 +2273,12 @@
19502273 int parse_events_option(const struct option *opt, const char *str,
19512274 int unset __maybe_unused)
19522275 {
1953
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
1954
- struct parse_events_error err = { .idx = 0, };
1955
- int ret = parse_events(evlist, str, &err);
2276
+ struct evlist *evlist = *(struct evlist **)opt->value;
2277
+ struct parse_events_error err;
2278
+ int ret;
2279
+
2280
+ bzero(&err, sizeof(err));
2281
+ ret = parse_events(evlist, str, &err);
19562282
19572283 if (ret) {
19582284 parse_events_print_error(&err, str);
....@@ -1962,13 +2288,36 @@
19622288 return ret;
19632289 }
19642290
2291
+int parse_events_option_new_evlist(const struct option *opt, const char *str, int unset)
2292
+{
2293
+ struct evlist **evlistp = opt->value;
2294
+ int ret;
2295
+
2296
+ if (*evlistp == NULL) {
2297
+ *evlistp = evlist__new();
2298
+
2299
+ if (*evlistp == NULL) {
2300
+ fprintf(stderr, "Not enough memory to create evlist\n");
2301
+ return -1;
2302
+ }
2303
+ }
2304
+
2305
+ ret = parse_events_option(opt, str, unset);
2306
+ if (ret) {
2307
+ evlist__delete(*evlistp);
2308
+ *evlistp = NULL;
2309
+ }
2310
+
2311
+ return ret;
2312
+}
2313
+
19652314 static int
1966
-foreach_evsel_in_last_glob(struct perf_evlist *evlist,
1967
- int (*func)(struct perf_evsel *evsel,
2315
+foreach_evsel_in_last_glob(struct evlist *evlist,
2316
+ int (*func)(struct evsel *evsel,
19682317 const void *arg),
19692318 const void *arg)
19702319 {
1971
- struct perf_evsel *last = NULL;
2320
+ struct evsel *last = NULL;
19722321 int err;
19732322
19742323 /*
....@@ -1977,8 +2326,8 @@
19772326 *
19782327 * So no need to WARN here, let *func do this.
19792328 */
1980
- if (evlist->nr_entries > 0)
1981
- last = perf_evlist__last(evlist);
2329
+ if (evlist->core.nr_entries > 0)
2330
+ last = evlist__last(evlist);
19822331
19832332 do {
19842333 err = (*func)(last, arg);
....@@ -1987,15 +2336,15 @@
19872336 if (!last)
19882337 return 0;
19892338
1990
- if (last->node.prev == &evlist->entries)
2339
+ if (last->core.node.prev == &evlist->core.entries)
19912340 return 0;
1992
- last = list_entry(last->node.prev, struct perf_evsel, node);
2341
+ last = list_entry(last->core.node.prev, struct evsel, core.node);
19932342 } while (!last->cmdline_group_boundary);
19942343
19952344 return 0;
19962345 }
19972346
1998
-static int set_filter(struct perf_evsel *evsel, const void *arg)
2347
+static int set_filter(struct evsel *evsel, const void *arg)
19992348 {
20002349 const char *str = arg;
20012350 bool found = false;
....@@ -2008,8 +2357,8 @@
20082357 return -1;
20092358 }
20102359
2011
- if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
2012
- if (perf_evsel__append_tp_filter(evsel, str) < 0) {
2360
+ if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
2361
+ if (evsel__append_tp_filter(evsel, str) < 0) {
20132362 fprintf(stderr,
20142363 "not enough memory to hold filter string\n");
20152364 return -1;
....@@ -2019,7 +2368,7 @@
20192368 }
20202369
20212370 while ((pmu = perf_pmu__scan(pmu)) != NULL)
2022
- if (pmu->type == evsel->attr.type) {
2371
+ if (pmu->type == evsel->core.attr.type) {
20232372 found = true;
20242373 break;
20252374 }
....@@ -2034,7 +2383,7 @@
20342383 return -1;
20352384 }
20362385
2037
- if (perf_evsel__append_addr_filter(evsel, str) < 0) {
2386
+ if (evsel__append_addr_filter(evsel, str) < 0) {
20382387 fprintf(stderr,
20392388 "not enough memory to hold filter string\n");
20402389 return -1;
....@@ -2046,18 +2395,18 @@
20462395 int parse_filter(const struct option *opt, const char *str,
20472396 int unset __maybe_unused)
20482397 {
2049
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
2398
+ struct evlist *evlist = *(struct evlist **)opt->value;
20502399
20512400 return foreach_evsel_in_last_glob(evlist, set_filter,
20522401 (const void *)str);
20532402 }
20542403
2055
-static int add_exclude_perf_filter(struct perf_evsel *evsel,
2404
+static int add_exclude_perf_filter(struct evsel *evsel,
20562405 const void *arg __maybe_unused)
20572406 {
20582407 char new_filter[64];
20592408
2060
- if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2409
+ if (evsel == NULL || evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
20612410 fprintf(stderr,
20622411 "--exclude-perf option should follow a -e tracepoint option\n");
20632412 return -1;
....@@ -2065,7 +2414,7 @@
20652414
20662415 snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid());
20672416
2068
- if (perf_evsel__append_tp_filter(evsel, new_filter) < 0) {
2417
+ if (evsel__append_tp_filter(evsel, new_filter) < 0) {
20692418 fprintf(stderr,
20702419 "not enough memory to hold filter string\n");
20712420 return -1;
....@@ -2078,7 +2427,7 @@
20782427 const char *arg __maybe_unused,
20792428 int unset __maybe_unused)
20802429 {
2081
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
2430
+ struct evlist *evlist = *(struct evlist **)opt->value;
20822431
20832432 return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter,
20842433 NULL);
....@@ -2244,20 +2593,20 @@
22442593 {
22452594 bool ret = true;
22462595 int open_return;
2247
- struct perf_evsel *evsel;
2596
+ struct evsel *evsel;
22482597 struct perf_event_attr attr = {
22492598 .type = type,
22502599 .config = config,
22512600 .disabled = 1,
22522601 };
2253
- struct thread_map *tmap = thread_map__new_by_tid(0);
2602
+ struct perf_thread_map *tmap = thread_map__new_by_tid(0);
22542603
22552604 if (tmap == NULL)
22562605 return false;
22572606
2258
- evsel = perf_evsel__new(&attr);
2607
+ evsel = evsel__new(&attr);
22592608 if (evsel) {
2260
- open_return = perf_evsel__open(evsel, NULL, tmap);
2609
+ open_return = evsel__open(evsel, NULL, tmap);
22612610 ret = open_return >= 0;
22622611
22632612 if (open_return == -EACCES) {
....@@ -2268,13 +2617,13 @@
22682617 * by default as some ARM machines do not support it.
22692618 *
22702619 */
2271
- evsel->attr.exclude_kernel = 1;
2272
- ret = perf_evsel__open(evsel, NULL, tmap) >= 0;
2620
+ evsel->core.attr.exclude_kernel = 1;
2621
+ ret = evsel__open(evsel, NULL, tmap) >= 0;
22732622 }
2274
- perf_evsel__delete(evsel);
2623
+ evsel__delete(evsel);
22752624 }
22762625
2277
- thread_map__put(tmap);
2626
+ perf_thread_map__put(tmap);
22782627 return ret;
22792628 }
22802629
....@@ -2375,12 +2724,11 @@
23752724 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
23762725 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
23772726 /* skip invalid cache type */
2378
- if (!perf_evsel__is_cache_op_valid(type, op))
2727
+ if (!evsel__is_cache_op_valid(type, op))
23792728 continue;
23802729
23812730 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
2382
- __perf_evsel__hw_cache_type_op_res_name(type, op, i,
2383
- name, sizeof(name));
2731
+ __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
23842732 if (event_glob != NULL && !strglobmatch(name, event_glob))
23852733 continue;
23862734
....@@ -2430,6 +2778,25 @@
24302778 if (evt_list)
24312779 goto out_free;
24322780 return evt_num;
2781
+}
2782
+
2783
+static void print_tool_event(const char *name, const char *event_glob,
2784
+ bool name_only)
2785
+{
2786
+ if (event_glob && !strglobmatch(name, event_glob))
2787
+ return;
2788
+ if (name_only)
2789
+ printf("%s ", name);
2790
+ else
2791
+ printf(" %-50s [%s]\n", name, "Tool event");
2792
+
2793
+}
2794
+
2795
+void print_tool_events(const char *event_glob, bool name_only)
2796
+{
2797
+ print_tool_event("duration_time", event_glob, name_only);
2798
+ if (pager_in_use())
2799
+ printf("\n");
24332800 }
24342801
24352802 void print_symbol_events(const char *event_glob, unsigned type,
....@@ -2508,18 +2875,19 @@
25082875 * Print the help text for the event symbols:
25092876 */
25102877 void print_events(const char *event_glob, bool name_only, bool quiet_flag,
2511
- bool long_desc, bool details_flag)
2878
+ bool long_desc, bool details_flag, bool deprecated)
25122879 {
25132880 print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
25142881 event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
25152882
25162883 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
25172884 event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
2885
+ print_tool_events(event_glob, name_only);
25182886
25192887 print_hwcache_events(event_glob, name_only);
25202888
25212889 print_pmu_events(event_glob, name_only, quiet_flag, long_desc,
2522
- details_flag);
2890
+ details_flag, deprecated);
25232891
25242892 if (event_glob != NULL)
25252893 return;
....@@ -2545,7 +2913,9 @@
25452913
25462914 print_sdt_events(NULL, NULL, name_only);
25472915
2548
- metricgroup__print(true, true, NULL, name_only);
2916
+ metricgroup__print(true, true, NULL, name_only, details_flag);
2917
+
2918
+ print_libpfm_events(name_only, long_desc);
25492919 }
25502920
25512921 int parse_events__is_hardcoded_term(struct parse_events_term *term)
....@@ -2625,30 +2995,63 @@
26252995 char *config, unsigned idx)
26262996 {
26272997 struct event_symbol *sym;
2998
+ char *str;
26282999 struct parse_events_term temp = {
26293000 .type_val = PARSE_EVENTS__TERM_TYPE_STR,
26303001 .type_term = PARSE_EVENTS__TERM_TYPE_USER,
2631
- .config = config ?: (char *) "event",
3002
+ .config = config,
26323003 };
26333004
3005
+ if (!temp.config) {
3006
+ temp.config = strdup("event");
3007
+ if (!temp.config)
3008
+ return -ENOMEM;
3009
+ }
26343010 BUG_ON(idx >= PERF_COUNT_HW_MAX);
26353011 sym = &event_symbols_hw[idx];
26363012
2637
- return new_term(term, &temp, (char *) sym->symbol, 0);
3013
+ str = strdup(sym->symbol);
3014
+ if (!str)
3015
+ return -ENOMEM;
3016
+ return new_term(term, &temp, str, 0);
26383017 }
26393018
26403019 int parse_events_term__clone(struct parse_events_term **new,
26413020 struct parse_events_term *term)
26423021 {
3022
+ char *str;
26433023 struct parse_events_term temp = {
26443024 .type_val = term->type_val,
26453025 .type_term = term->type_term,
2646
- .config = term->config,
3026
+ .config = NULL,
26473027 .err_term = term->err_term,
26483028 .err_val = term->err_val,
26493029 };
26503030
2651
- return new_term(new, &temp, term->val.str, term->val.num);
3031
+ if (term->config) {
3032
+ temp.config = strdup(term->config);
3033
+ if (!temp.config)
3034
+ return -ENOMEM;
3035
+ }
3036
+ if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM)
3037
+ return new_term(new, &temp, NULL, term->val.num);
3038
+
3039
+ str = strdup(term->val.str);
3040
+ if (!str)
3041
+ return -ENOMEM;
3042
+ return new_term(new, &temp, str, 0);
3043
+}
3044
+
3045
+void parse_events_term__delete(struct parse_events_term *term)
3046
+{
3047
+ if (term->array.nr_ranges)
3048
+ zfree(&term->array.ranges);
3049
+
3050
+ if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM)
3051
+ zfree(&term->val.str);
3052
+
3053
+ zfree(&term->config);
3054
+ free(term);
26523055 }
26533056
26543057 int parse_events_copy_term_list(struct list_head *old,
....@@ -2681,10 +3084,8 @@
26813084 struct parse_events_term *term, *h;
26823085
26833086 list_for_each_entry_safe(term, h, terms, list) {
2684
- if (term->array.nr_ranges)
2685
- zfree(&term->array.ranges);
26863087 list_del_init(&term->list);
2687
- free(term);
3088
+ parse_events_term__delete(term);
26883089 }
26893090 }
26903091
....@@ -2704,13 +3105,10 @@
27043105 void parse_events_evlist_error(struct parse_events_state *parse_state,
27053106 int idx, const char *str)
27063107 {
2707
- struct parse_events_error *err = parse_state->error;
2708
-
2709
- if (!err)
3108
+ if (!parse_state->error)
27103109 return;
2711
- err->idx = idx;
2712
- err->str = strdup(str);
2713
- WARN_ONCE(!err->str, "WARNING: failed to allocate error string");
3110
+
3111
+ parse_events__handle_error(parse_state->error, idx, strdup(str), NULL);
27143112 }
27153113
27163114 static void config_terms_list(char *buf, size_t buf_sz)