hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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 {
....@@ -307,25 +344,37 @@
307344 return NULL;
308345 }
309346
310
-static struct perf_evsel *
347
+static struct evsel *
311348 __add_event(struct list_head *list, int *idx,
312349 struct perf_event_attr *attr,
350
+ bool init_attr,
313351 char *name, struct perf_pmu *pmu,
314
- struct list_head *config_terms, bool auto_merge_stats)
352
+ struct list_head *config_terms, bool auto_merge_stats,
353
+ const char *cpu_list)
315354 {
316
- struct perf_evsel *evsel;
317
- 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;
318358
319
- event_attr_init(attr);
359
+ if (pmu)
360
+ perf_pmu__warn_invalid_formats(pmu);
320361
321
- evsel = perf_evsel__new_idx(attr, *idx);
322
- 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);
323371 return NULL;
372
+ }
324373
325374 (*idx)++;
326
- evsel->cpus = cpu_map__get(cpus);
327
- evsel->own_cpus = cpu_map__get(cpus);
328
- 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;
329378 evsel->auto_merge_stats = auto_merge_stats;
330379
331380 if (name)
....@@ -334,24 +383,53 @@
334383 if (config_terms)
335384 list_splice(config_terms, &evsel->config_terms);
336385
337
- list_add_tail(&evsel->node, list);
386
+ if (list)
387
+ list_add_tail(&evsel->core.node, list);
388
+
338389 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);
339397 }
340398
341399 static int add_event(struct list_head *list, int *idx,
342400 struct perf_event_attr *attr, char *name,
343401 struct list_head *config_terms)
344402 {
345
- 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;
346405 }
347406
348
-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)
349427 {
350428 int i, j;
351429 int n, longest = -1;
352430
353431 for (i = 0; i < size; i++) {
354
- for (j = 0; j < PERF_EVSEL__MAX_ALIASES && names[i][j]; j++) {
432
+ for (j = 0; j < EVSEL__MAX_ALIASES && names[i][j]; j++) {
355433 n = strlen(names[i][j]);
356434 if (n > longest && !strncasecmp(str, names[i][j], n))
357435 longest = n;
....@@ -390,8 +468,7 @@
390468 * No fallback - if we cannot get a clear cache type
391469 * then bail out:
392470 */
393
- cache_type = parse_aliases(type, perf_evsel__hw_cache,
394
- PERF_COUNT_HW_CACHE_MAX);
471
+ cache_type = parse_aliases(type, evsel__hw_cache, PERF_COUNT_HW_CACHE_MAX);
395472 if (cache_type == -1)
396473 return -EINVAL;
397474
....@@ -404,17 +481,17 @@
404481 n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str);
405482
406483 if (cache_op == -1) {
407
- cache_op = parse_aliases(str, perf_evsel__hw_cache_op,
484
+ cache_op = parse_aliases(str, evsel__hw_cache_op,
408485 PERF_COUNT_HW_CACHE_OP_MAX);
409486 if (cache_op >= 0) {
410
- if (!perf_evsel__is_cache_op_valid(cache_type, cache_op))
487
+ if (!evsel__is_cache_op_valid(cache_type, cache_op))
411488 return -EINVAL;
412489 continue;
413490 }
414491 }
415492
416493 if (cache_result == -1) {
417
- cache_result = parse_aliases(str, perf_evsel__hw_cache_result,
494
+ cache_result = parse_aliases(str, evsel__hw_cache_result,
418495 PERF_COUNT_HW_CACHE_RESULT_MAX);
419496 if (cache_result >= 0)
420497 continue;
....@@ -451,6 +528,7 @@
451528 static void tracepoint_error(struct parse_events_error *e, int err,
452529 const char *sys, const char *name)
453530 {
531
+ const char *str;
454532 char help[BUFSIZ];
455533
456534 if (!e)
....@@ -464,18 +542,18 @@
464542
465543 switch (err) {
466544 case EACCES:
467
- e->str = strdup("can't access trace events");
545
+ str = "can't access trace events";
468546 break;
469547 case ENOENT:
470
- e->str = strdup("unknown tracepoint");
548
+ str = "unknown tracepoint";
471549 break;
472550 default:
473
- e->str = strdup("failed to add tracepoint");
551
+ str = "failed to add tracepoint";
474552 break;
475553 }
476554
477555 tracing_path__strerror_open_tp(err, help, sizeof(help), sys, name);
478
- e->help = strdup(help);
556
+ parse_events__handle_error(e, 0, strdup(str), strdup(help));
479557 }
480558
481559 static int add_tracepoint(struct list_head *list, int *idx,
....@@ -483,9 +561,8 @@
483561 struct parse_events_error *err,
484562 struct list_head *head_config)
485563 {
486
- struct perf_evsel *evsel;
564
+ struct evsel *evsel = evsel__newtp_idx(sys_name, evt_name, (*idx)++);
487565
488
- evsel = perf_evsel__newtp_idx(sys_name, evt_name, (*idx)++);
489566 if (IS_ERR(evsel)) {
490567 tracepoint_error(err, PTR_ERR(evsel), sys_name, evt_name);
491568 return PTR_ERR(evsel);
....@@ -499,7 +576,7 @@
499576 list_splice(&config_terms, &evsel->config_terms);
500577 }
501578
502
- list_add_tail(&evsel->node, list);
579
+ list_add_tail(&evsel->core.node, list);
503580 return 0;
504581 }
505582
....@@ -603,15 +680,24 @@
603680 struct list_head *head_config;
604681 };
605682
606
-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,
607684 void *_param)
608685 {
609686 LIST_HEAD(new_evsels);
610687 struct __add_bpf_event_param *param = _param;
611688 struct parse_events_state *parse_state = param->parse_state;
612689 struct list_head *list = param->list;
613
- struct perf_evsel *pos;
690
+ struct evsel *pos;
614691 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;
615701
616702 pr_debug("add bpf event %s:%s and attach bpf program %d\n",
617703 group, event, fd);
....@@ -620,22 +706,23 @@
620706 event, parse_state->error,
621707 param->head_config);
622708 if (err) {
623
- struct perf_evsel *evsel, *tmp;
709
+ struct evsel *evsel, *tmp;
624710
625711 pr_debug("Failed to add BPF event %s:%s\n",
626712 group, event);
627
- list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
628
- list_del(&evsel->node);
629
- 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);
630716 }
631717 return err;
632718 }
633719 pr_debug("adding %s:%s\n", group, event);
634720
635
- list_for_each_entry(pos, &new_evsels, node) {
721
+ list_for_each_entry(pos, &new_evsels, core.node) {
636722 pr_debug("adding %s:%s to %p\n",
637723 group, event, pos);
638724 pos->bpf_fd = fd;
725
+ pos->bpf_obj = obj;
639726 }
640727 list_splice(&new_evsels, list);
641728 return 0;
....@@ -689,8 +776,8 @@
689776
690777 return 0;
691778 errout:
692
- parse_state->error->help = strdup("(add -v to see detail)");
693
- parse_state->error->str = strdup(errbuf);
779
+ parse_events__handle_error(parse_state->error, 0,
780
+ strdup(errbuf), strdup("(add -v to see detail)"));
694781 return err;
695782 }
696783
....@@ -706,36 +793,38 @@
706793 return 0;
707794
708795 list_for_each_entry(term, head_config, list) {
709
- char errbuf[BUFSIZ];
710796 int err;
711797
712798 if (term->type_term != PARSE_EVENTS__TERM_TYPE_USER) {
713
- snprintf(errbuf, sizeof(errbuf),
714
- "Invalid config term for BPF object");
715
- errbuf[BUFSIZ - 1] = '\0';
716
-
717
- parse_state->error->idx = term->err_term;
718
- 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);
719802 return -EINVAL;
720803 }
721804
722805 err = bpf__config_obj(obj, term, parse_state->evlist, &error_pos);
723806 if (err) {
807
+ char errbuf[BUFSIZ];
808
+ int idx;
809
+
724810 bpf__strerror_config_obj(obj, term, parse_state->evlist,
725811 &error_pos, err, errbuf,
726812 sizeof(errbuf));
727
- 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(
728822 "Hint:\tValid config terms:\n"
729823 " \tmap:[<arraymap>].value<indices>=[value]\n"
730824 " \tmap:[<eventmap>].event<indices>=[event]\n"
731825 "\n"
732826 " \twhere <indices> is something like [0,3...5] or [all]\n"
733
-" \t(add -v to see detail)");
734
- parse_state->error->str = strdup(errbuf);
735
- if (err == -BPF_LOADER_ERRNO__OBJCONF_MAP_VALUE)
736
- parse_state->error->idx = term->err_val;
737
- else
738
- parse_state->error->idx = term->err_term + error_pos;
827
+" \t(add -v to see detail)"));
739828 return err;
740829 }
741830 }
....@@ -799,8 +888,8 @@
799888 -err, errbuf,
800889 sizeof(errbuf));
801890
802
- parse_state->error->help = strdup("(add -v to see detail)");
803
- parse_state->error->str = strdup(errbuf);
891
+ parse_events__handle_error(parse_state->error, 0,
892
+ strdup(errbuf), strdup("(add -v to see detail)"));
804893 return err;
805894 }
806895
....@@ -859,12 +948,12 @@
859948 }
860949
861950 int parse_events_add_breakpoint(struct list_head *list, int *idx,
862
- void *ptr, char *type, u64 len)
951
+ u64 addr, char *type, u64 len)
863952 {
864953 struct perf_event_attr attr;
865954
866955 memset(&attr, 0, sizeof(attr));
867
- attr.bp_addr = (unsigned long) ptr;
956
+ attr.bp_addr = addr;
868957
869958 if (parse_breakpoint_type(type, &attr))
870959 return -EINVAL;
....@@ -893,11 +982,11 @@
893982 return 0;
894983
895984 if (err) {
896
- err->idx = term->err_val;
897
- if (type == PARSE_EVENTS__TERM_TYPE_NUM)
898
- err->str = strdup("expected numeric value");
899
- else
900
- 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);
901990 }
902991 return -EINVAL;
903992 }
....@@ -920,9 +1009,13 @@
9201009 [PARSE_EVENTS__TERM_TYPE_NOINHERIT] = "no-inherit",
9211010 [PARSE_EVENTS__TERM_TYPE_INHERIT] = "inherit",
9221011 [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack",
1012
+ [PARSE_EVENTS__TERM_TYPE_MAX_EVENTS] = "nr",
9231013 [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
9241014 [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
9251015 [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",
9261019 };
9271020
9281021 static bool config_term_shrinked;
....@@ -930,8 +1023,11 @@
9301023 static bool
9311024 config_term_avail(int term_type, struct parse_events_error *err)
9321025 {
1026
+ char *err_str;
1027
+
9331028 if (term_type < 0 || term_type >= __PARSE_EVENTS__TERM_TYPE_NR) {
934
- err->str = strdup("Invalid term_type");
1029
+ parse_events__handle_error(err, -1,
1030
+ strdup("Invalid term_type"), NULL);
9351031 return false;
9361032 }
9371033 if (!config_term_shrinked)
....@@ -943,15 +1039,16 @@
9431039 case PARSE_EVENTS__TERM_TYPE_CONFIG2:
9441040 case PARSE_EVENTS__TERM_TYPE_NAME:
9451041 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
1042
+ case PARSE_EVENTS__TERM_TYPE_PERCORE:
9461043 return true;
9471044 default:
9481045 if (!err)
9491046 return false;
9501047
9511048 /* term_type is validated so indexing is safe */
952
- if (asprintf(&err->str, "'%s' is not usable in 'perf stat'",
953
- config_term_names[term_type]) < 0)
954
- 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);
9551052 return false;
9561053 }
9571054 }
....@@ -993,17 +1090,20 @@
9931090 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
9941091 CHECK_TYPE_VAL(STR);
9951092 if (strcmp(term->val.str, "no") &&
996
- parse_branch_str(term->val.str, &attr->branch_sample_type)) {
997
- err->str = strdup("invalid branch sample type");
998
- 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);
9991098 return -EINVAL;
10001099 }
10011100 break;
10021101 case PARSE_EVENTS__TERM_TYPE_TIME:
10031102 CHECK_TYPE_VAL(NUM);
10041103 if (term->val.num > 1) {
1005
- err->str = strdup("expected 0 or 1");
1006
- err->idx = term->err_val;
1104
+ parse_events__handle_error(err, term->err_val,
1105
+ strdup("expected 0 or 1"),
1106
+ NULL);
10071107 return -EINVAL;
10081108 }
10091109 break;
....@@ -1031,10 +1131,34 @@
10311131 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
10321132 CHECK_TYPE_VAL(NUM);
10331133 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;
10341158 default:
1035
- err->str = strdup("unknown term");
1036
- err->idx = term->err_term;
1037
- 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));
10381162 return -EINVAL;
10391163 }
10401164
....@@ -1078,14 +1202,17 @@
10781202 case PARSE_EVENTS__TERM_TYPE_INHERIT:
10791203 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
10801204 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1205
+ case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
10811206 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
10821207 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1208
+ case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
1209
+ case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
10831210 return config_term_common(attr, term, err);
10841211 default:
10851212 if (err) {
1086
- err->idx = term->err_term;
1087
- err->str = strdup("unknown term");
1088
- 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"));
10891216 }
10901217 return -EINVAL;
10911218 }
....@@ -1110,19 +1237,33 @@
11101237 static int get_config_terms(struct list_head *head_config,
11111238 struct list_head *head_terms __maybe_unused)
11121239 {
1113
-#define ADD_CONFIG_TERM(__type, __name, __val) \
1114
-do { \
1115
- struct perf_evsel_config_term *__t; \
1240
+#define ADD_CONFIG_TERM(__type, __weak) \
1241
+ struct evsel_config_term *__t; \
11161242 \
11171243 __t = zalloc(sizeof(*__t)); \
11181244 if (!__t) \
11191245 return -ENOMEM; \
11201246 \
11211247 INIT_LIST_HEAD(&__t->list); \
1122
- __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); \
11231255 __t->val.__name = __val; \
1124
- __t->weak = term->weak; \
1125
- 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; \
11261267 } while (0)
11271268
11281269 struct parse_events_term *term;
....@@ -1130,46 +1271,101 @@
11301271 list_for_each_entry(term, head_config, list) {
11311272 switch (term->type_term) {
11321273 case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
1133
- ADD_CONFIG_TERM(PERIOD, period, term->val.num);
1274
+ ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num, term->weak);
11341275 break;
11351276 case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
1136
- ADD_CONFIG_TERM(FREQ, freq, term->val.num);
1277
+ ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num, term->weak);
11371278 break;
11381279 case PARSE_EVENTS__TERM_TYPE_TIME:
1139
- ADD_CONFIG_TERM(TIME, time, term->val.num);
1280
+ ADD_CONFIG_TERM_VAL(TIME, time, term->val.num, term->weak);
11401281 break;
11411282 case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
1142
- ADD_CONFIG_TERM(CALLGRAPH, callgraph, term->val.str);
1283
+ ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str, term->weak);
11431284 break;
11441285 case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
1145
- ADD_CONFIG_TERM(BRANCH, branch, term->val.str);
1286
+ ADD_CONFIG_TERM_STR(BRANCH, term->val.str, term->weak);
11461287 break;
11471288 case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
1148
- 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);
11491291 break;
11501292 case PARSE_EVENTS__TERM_TYPE_INHERIT:
1151
- 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);
11521295 break;
11531296 case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
1154
- 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);
11551299 break;
11561300 case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
1157
- 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);
11581307 break;
11591308 case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
1160
- 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);
11611311 break;
11621312 case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
1163
- 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);
11641315 break;
11651316 case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
1166
- 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);
11671330 break;
11681331 default:
11691332 break;
11701333 }
11711334 }
1172
-#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
11731369 return 0;
11741370 }
11751371
....@@ -1219,6 +1415,25 @@
12191415 get_config_name(head_config), &config_terms);
12201416 }
12211417
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
+
12221437 int parse_events_add_pmu(struct parse_events_state *parse_state,
12231438 struct list_head *list, char *name,
12241439 struct list_head *head_config,
....@@ -1228,17 +1443,33 @@
12281443 struct perf_event_attr attr;
12291444 struct perf_pmu_info info;
12301445 struct perf_pmu *pmu;
1231
- struct perf_evsel *evsel;
1446
+ struct evsel *evsel;
12321447 struct parse_events_error *err = parse_state->error;
12331448 bool use_uncore_alias;
12341449 LIST_HEAD(config_terms);
12351450
1236
- 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
+
12371466 if (!pmu) {
1238
- if (asprintf(&err->str,
1467
+ char *err_str;
1468
+
1469
+ if (asprintf(&err_str,
12391470 "Cannot find PMU `%s'. Missing kernel support?",
1240
- name) < 0)
1241
- err->str = NULL;
1471
+ name) >= 0)
1472
+ parse_events__handle_error(err, 0, err_str, NULL);
12421473 return -EINVAL;
12431474 }
12441475
....@@ -1253,7 +1484,8 @@
12531484
12541485 if (!head_config) {
12551486 attr.type = pmu->type;
1256
- 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);
12571489 if (evsel) {
12581490 evsel->pmu_name = name ? strdup(name) : NULL;
12591491 evsel->use_uncore_alias = use_uncore_alias;
....@@ -1263,8 +1495,21 @@
12631495 }
12641496 }
12651497
1266
- if (perf_pmu__check_alias(pmu, head_config, &info))
1498
+ if (!parse_state->fake_pmu && perf_pmu__check_alias(pmu, head_config, &info))
12671499 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
+ }
12681513
12691514 /*
12701515 * Configure hardcoded terms first, no need to check
....@@ -1276,31 +1521,45 @@
12761521 if (get_config_terms(head_config, &config_terms))
12771522 return -ENOMEM;
12781523
1279
- if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) {
1280
- 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;
12811533
12821534 list_for_each_entry_safe(pos, tmp, &config_terms, list) {
12831535 list_del_init(&pos->list);
1536
+ if (pos->free_str)
1537
+ zfree(&pos->val.str);
12841538 free(pos);
12851539 }
12861540 return -EINVAL;
12871541 }
12881542
1289
- evsel = __add_event(list, &parse_state->idx, &attr,
1543
+ evsel = __add_event(list, &parse_state->idx, &attr, true,
12901544 get_config_name(head_config), pmu,
1291
- &config_terms, auto_merge_stats);
1292
- if (evsel) {
1293
- evsel->unit = info.unit;
1294
- evsel->scale = info.scale;
1295
- evsel->per_pkg = info.per_pkg;
1296
- evsel->snapshot = info.snapshot;
1297
- evsel->metric_expr = info.metric_expr;
1298
- evsel->metric_name = info.metric_name;
1299
- evsel->pmu_name = name ? strdup(name) : NULL;
1300
- evsel->use_uncore_alias = use_uncore_alias;
1301
- }
1545
+ &config_terms, auto_merge_stats, NULL);
1546
+ if (!evsel)
1547
+ return -ENOMEM;
13021548
1303
- 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;
13041563 }
13051564
13061565 int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
....@@ -1345,7 +1604,7 @@
13451604 if (!parse_events_add_pmu(parse_state, list,
13461605 pmu->name, head,
13471606 true, true)) {
1348
- pr_debug("%s -> %s/%s/\n", config,
1607
+ pr_debug("%s -> %s/%s/\n", str,
13491608 pmu->name, alias->str);
13501609 ok++;
13511610 }
....@@ -1392,13 +1651,13 @@
13921651 parse_events__set_leader_for_uncore_aliase(char *name, struct list_head *list,
13931652 struct parse_events_state *parse_state)
13941653 {
1395
- struct perf_evsel *evsel, *leader;
1654
+ struct evsel *evsel, *leader;
13961655 uintptr_t *leaders;
13971656 bool is_leader = true;
13981657 int i, nr_pmu = 0, total_members, ret = 0;
13991658
1400
- leader = list_first_entry(list, struct perf_evsel, node);
1401
- 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);
14021661 total_members = evsel->idx - leader->idx + 1;
14031662
14041663 leaders = calloc(total_members, sizeof(uintptr_t));
....@@ -1459,13 +1718,13 @@
14591718 __evlist__for_each_entry(list, evsel) {
14601719 if (i >= nr_pmu)
14611720 i = 0;
1462
- evsel->leader = (struct perf_evsel *) leaders[i++];
1721
+ evsel->leader = (struct evsel *) leaders[i++];
14631722 }
14641723
14651724 /* The number of members and group name are same for each group */
14661725 for (i = 0; i < nr_pmu; i++) {
1467
- evsel = (struct perf_evsel *) leaders[i];
1468
- evsel->nr_members = total_members / nr_pmu;
1726
+ evsel = (struct evsel *) leaders[i];
1727
+ evsel->core.nr_members = total_members / nr_pmu;
14691728 evsel->group_name = name ? strdup(name) : NULL;
14701729 }
14711730
....@@ -1482,7 +1741,7 @@
14821741 void parse_events__set_leader(char *name, struct list_head *list,
14831742 struct parse_events_state *parse_state)
14841743 {
1485
- struct perf_evsel *leader;
1744
+ struct evsel *leader;
14861745
14871746 if (list_empty(list)) {
14881747 WARN_ONCE(true, "WARNING: failed to set leader: empty list");
....@@ -1493,7 +1752,7 @@
14931752 return;
14941753
14951754 __perf_evlist__set_leader(list);
1496
- leader = list_entry(list->next, struct perf_evsel, node);
1755
+ leader = list_entry(list->next, struct evsel, core.node);
14971756 leader->group_name = name ? strdup(name) : NULL;
14981757 }
14991758
....@@ -1523,21 +1782,23 @@
15231782 int sample_read;
15241783 int pinned;
15251784 int weak;
1785
+ int exclusive;
15261786 };
15271787
15281788 static int get_event_modifier(struct event_modifier *mod, char *str,
1529
- struct perf_evsel *evsel)
1789
+ struct evsel *evsel)
15301790 {
1531
- int eu = evsel ? evsel->attr.exclude_user : 0;
1532
- int ek = evsel ? evsel->attr.exclude_kernel : 0;
1533
- int eh = evsel ? evsel->attr.exclude_hv : 0;
1534
- int eH = evsel ? evsel->attr.exclude_host : 0;
1535
- int eG = evsel ? evsel->attr.exclude_guest : 0;
1536
- int eI = evsel ? evsel->attr.exclude_idle : 0;
1537
- 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;
15381798 int precise_max = 0;
15391799 int sample_read = 0;
1540
- 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;
15411802
15421803 int exclude = eu | ek | eh;
15431804 int exclude_GH = evsel ? evsel->exclude_GH : 0;
....@@ -1549,6 +1810,8 @@
15491810 if (*str == 'u') {
15501811 if (!exclude)
15511812 exclude = eu = ek = eh = 1;
1813
+ if (!exclude_GH && !perf_guest)
1814
+ eG = 1;
15521815 eu = 0;
15531816 } else if (*str == 'k') {
15541817 if (!exclude)
....@@ -1579,6 +1842,8 @@
15791842 sample_read = 1;
15801843 } else if (*str == 'D') {
15811844 pinned = 1;
1845
+ } else if (*str == 'e') {
1846
+ exclusive = 1;
15821847 } else if (*str == 'W') {
15831848 weak = 1;
15841849 } else
....@@ -1612,6 +1877,7 @@
16121877 mod->sample_read = sample_read;
16131878 mod->pinned = pinned;
16141879 mod->weak = weak;
1880
+ mod->exclusive = exclusive;
16151881
16161882 return 0;
16171883 }
....@@ -1625,7 +1891,7 @@
16251891 char *p = str;
16261892
16271893 /* The sizeof includes 0 byte as well. */
1628
- if (strlen(str) > (sizeof("ukhGHpppPSDIW") - 1))
1894
+ if (strlen(str) > (sizeof("ukhGHpppPSDIWe") - 1))
16291895 return -1;
16301896
16311897 while (*p) {
....@@ -1639,7 +1905,7 @@
16391905
16401906 int parse_events__modifier_event(struct list_head *list, char *str, bool add)
16411907 {
1642
- struct perf_evsel *evsel;
1908
+ struct evsel *evsel;
16431909 struct event_modifier mod;
16441910
16451911 if (str == NULL)
....@@ -1655,20 +1921,22 @@
16551921 if (add && get_event_modifier(&mod, str, evsel))
16561922 return -EINVAL;
16571923
1658
- evsel->attr.exclude_user = mod.eu;
1659
- evsel->attr.exclude_kernel = mod.ek;
1660
- evsel->attr.exclude_hv = mod.eh;
1661
- evsel->attr.precise_ip = mod.precise;
1662
- evsel->attr.exclude_host = mod.eH;
1663
- evsel->attr.exclude_guest = mod.eG;
1664
- 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;
16651931 evsel->exclude_GH = mod.exclude_GH;
16661932 evsel->sample_read = mod.sample_read;
16671933 evsel->precise_max = mod.precise_max;
16681934 evsel->weak_group = mod.weak;
16691935
1670
- if (perf_evsel__is_group_leader(evsel))
1671
- 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
+ }
16721940 }
16731941
16741942 return 0;
....@@ -1676,7 +1944,7 @@
16761944
16771945 int parse_events_name(struct list_head *list, char *name)
16781946 {
1679
- struct perf_evsel *evsel;
1947
+ struct evsel *evsel;
16801948
16811949 __evlist__for_each_entry(list, evsel) {
16821950 if (!evsel->name)
....@@ -1774,6 +2042,32 @@
17742042 perf_pmu__parse_cleanup();
17752043 }
17762044
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
+
17772071 enum perf_pmu_event_symbol_type
17782072 perf_pmu__parse_check(const char *name)
17792073 {
....@@ -1798,13 +2092,14 @@
17982092 return r ? r->type : PMU_EVENT_SYMBOL_ERR;
17992093 }
18002094
1801
-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)
18022097 {
18032098 YY_BUFFER_STATE buffer;
18042099 void *scanner;
18052100 int ret;
18062101
1807
- ret = parse_events_lex_init_extra(start_token, &scanner);
2102
+ ret = parse_events_lex_init_extra(parse_state, &scanner);
18082103 if (ret)
18092104 return ret;
18102105
....@@ -1812,6 +2107,7 @@
18122107
18132108 #ifdef PARSER_DEBUG
18142109 parse_events_debug = 1;
2110
+ parse_events_set_debug(1, scanner);
18152111 #endif
18162112 ret = parse_events_parse(parse_state, scanner);
18172113
....@@ -1827,11 +2123,14 @@
18272123 int parse_events_terms(struct list_head *terms, const char *str)
18282124 {
18292125 struct parse_events_state parse_state = {
1830
- .terms = NULL,
2126
+ .terms = NULL,
2127
+ .stoken = PE_START_TERMS,
18312128 };
18322129 int ret;
18332130
1834
- ret = parse_events__scanner(str, &parse_state, PE_START_TERMS);
2131
+ ret = parse_events__scanner(str, &parse_state);
2132
+ perf_pmu__parse_cleanup();
2133
+
18352134 if (!ret) {
18362135 list_splice(parse_state.terms, terms);
18372136 zfree(&parse_state.terms);
....@@ -1842,18 +2141,20 @@
18422141 return ret;
18432142 }
18442143
1845
-int parse_events(struct perf_evlist *evlist, const char *str,
1846
- 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)
18472146 {
18482147 struct parse_events_state parse_state = {
1849
- .list = LIST_HEAD_INIT(parse_state.list),
1850
- .idx = evlist->nr_entries,
1851
- .error = err,
1852
- .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,
18532154 };
18542155 int ret;
18552156
1856
- ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS);
2157
+ ret = parse_events__scanner(str, &parse_state);
18572158 perf_pmu__parse_cleanup();
18582159
18592160 if (!ret && list_empty(&parse_state.list)) {
....@@ -1867,10 +2168,10 @@
18672168 perf_evlist__splice_list_tail(evlist, &parse_state.list);
18682169
18692170 if (!ret) {
1870
- struct perf_evsel *last;
2171
+ struct evsel *last;
18712172
18722173 evlist->nr_groups += parse_state.nr_groups;
1873
- last = perf_evlist__last(evlist);
2174
+ last = evlist__last(evlist);
18742175 last->cmdline_group_boundary = true;
18752176
18762177 return 0;
....@@ -1878,7 +2179,7 @@
18782179
18792180 /*
18802181 * There are 2 users - builtin-record and builtin-test objects.
1881
- * Both call perf_evlist__delete in case of error, so we dont
2182
+ * Both call evlist__delete in case of error, so we dont
18822183 * need to bother.
18832184 */
18842185 return ret;
....@@ -1893,15 +2194,14 @@
18932194 return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col;
18942195 }
18952196
1896
-void parse_events_print_error(struct parse_events_error *err,
1897
- 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)
18982199 {
18992200 const char *str = "invalid or unsupported event: ";
19002201 char _buf[MAX_WIDTH];
19012202 char *buf = (char *) event;
19022203 int idx = 0;
1903
-
1904
- if (err->str) {
2204
+ if (err_str) {
19052205 /* -2 for extra '' in the final fprintf */
19062206 int width = get_term_width() - 2;
19072207 int len_event = strlen(event);
....@@ -1924,8 +2224,8 @@
19242224 buf = _buf;
19252225
19262226 /* We're cutting from the beginning. */
1927
- if (err->idx > max_err_idx)
1928
- cut = err->idx - max_err_idx;
2227
+ if (err_idx > max_err_idx)
2228
+ cut = err_idx - max_err_idx;
19292229
19302230 strncpy(buf, event + cut, max_len);
19312231
....@@ -1938,16 +2238,33 @@
19382238 buf[max_len] = 0;
19392239 }
19402240
1941
- idx = len_str + err->idx - cut;
2241
+ idx = len_str + err_idx - cut;
19422242 }
19432243
19442244 fprintf(stderr, "%s'%s'\n", str, buf);
19452245 if (idx) {
1946
- fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str);
1947
- if (err->help)
1948
- fprintf(stderr, "\n%s\n", err->help);
1949
- zfree(&err->str);
1950
- 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);
19512268 }
19522269 }
19532270
....@@ -1956,9 +2273,12 @@
19562273 int parse_events_option(const struct option *opt, const char *str,
19572274 int unset __maybe_unused)
19582275 {
1959
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
1960
- struct parse_events_error err = { .idx = 0, };
1961
- 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);
19622282
19632283 if (ret) {
19642284 parse_events_print_error(&err, str);
....@@ -1968,13 +2288,36 @@
19682288 return ret;
19692289 }
19702290
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
+
19712314 static int
1972
-foreach_evsel_in_last_glob(struct perf_evlist *evlist,
1973
- int (*func)(struct perf_evsel *evsel,
2315
+foreach_evsel_in_last_glob(struct evlist *evlist,
2316
+ int (*func)(struct evsel *evsel,
19742317 const void *arg),
19752318 const void *arg)
19762319 {
1977
- struct perf_evsel *last = NULL;
2320
+ struct evsel *last = NULL;
19782321 int err;
19792322
19802323 /*
....@@ -1983,8 +2326,8 @@
19832326 *
19842327 * So no need to WARN here, let *func do this.
19852328 */
1986
- if (evlist->nr_entries > 0)
1987
- last = perf_evlist__last(evlist);
2329
+ if (evlist->core.nr_entries > 0)
2330
+ last = evlist__last(evlist);
19882331
19892332 do {
19902333 err = (*func)(last, arg);
....@@ -1993,15 +2336,15 @@
19932336 if (!last)
19942337 return 0;
19952338
1996
- if (last->node.prev == &evlist->entries)
2339
+ if (last->core.node.prev == &evlist->core.entries)
19972340 return 0;
1998
- last = list_entry(last->node.prev, struct perf_evsel, node);
2341
+ last = list_entry(last->core.node.prev, struct evsel, core.node);
19992342 } while (!last->cmdline_group_boundary);
20002343
20012344 return 0;
20022345 }
20032346
2004
-static int set_filter(struct perf_evsel *evsel, const void *arg)
2347
+static int set_filter(struct evsel *evsel, const void *arg)
20052348 {
20062349 const char *str = arg;
20072350 bool found = false;
....@@ -2014,8 +2357,8 @@
20142357 return -1;
20152358 }
20162359
2017
- if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
2018
- 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) {
20192362 fprintf(stderr,
20202363 "not enough memory to hold filter string\n");
20212364 return -1;
....@@ -2025,7 +2368,7 @@
20252368 }
20262369
20272370 while ((pmu = perf_pmu__scan(pmu)) != NULL)
2028
- if (pmu->type == evsel->attr.type) {
2371
+ if (pmu->type == evsel->core.attr.type) {
20292372 found = true;
20302373 break;
20312374 }
....@@ -2040,7 +2383,7 @@
20402383 return -1;
20412384 }
20422385
2043
- if (perf_evsel__append_addr_filter(evsel, str) < 0) {
2386
+ if (evsel__append_addr_filter(evsel, str) < 0) {
20442387 fprintf(stderr,
20452388 "not enough memory to hold filter string\n");
20462389 return -1;
....@@ -2052,18 +2395,18 @@
20522395 int parse_filter(const struct option *opt, const char *str,
20532396 int unset __maybe_unused)
20542397 {
2055
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
2398
+ struct evlist *evlist = *(struct evlist **)opt->value;
20562399
20572400 return foreach_evsel_in_last_glob(evlist, set_filter,
20582401 (const void *)str);
20592402 }
20602403
2061
-static int add_exclude_perf_filter(struct perf_evsel *evsel,
2404
+static int add_exclude_perf_filter(struct evsel *evsel,
20622405 const void *arg __maybe_unused)
20632406 {
20642407 char new_filter[64];
20652408
2066
- if (evsel == NULL || evsel->attr.type != PERF_TYPE_TRACEPOINT) {
2409
+ if (evsel == NULL || evsel->core.attr.type != PERF_TYPE_TRACEPOINT) {
20672410 fprintf(stderr,
20682411 "--exclude-perf option should follow a -e tracepoint option\n");
20692412 return -1;
....@@ -2071,7 +2414,7 @@
20712414
20722415 snprintf(new_filter, sizeof(new_filter), "common_pid != %d", getpid());
20732416
2074
- if (perf_evsel__append_tp_filter(evsel, new_filter) < 0) {
2417
+ if (evsel__append_tp_filter(evsel, new_filter) < 0) {
20752418 fprintf(stderr,
20762419 "not enough memory to hold filter string\n");
20772420 return -1;
....@@ -2084,7 +2427,7 @@
20842427 const char *arg __maybe_unused,
20852428 int unset __maybe_unused)
20862429 {
2087
- struct perf_evlist *evlist = *(struct perf_evlist **)opt->value;
2430
+ struct evlist *evlist = *(struct evlist **)opt->value;
20882431
20892432 return foreach_evsel_in_last_glob(evlist, add_exclude_perf_filter,
20902433 NULL);
....@@ -2250,20 +2593,20 @@
22502593 {
22512594 bool ret = true;
22522595 int open_return;
2253
- struct perf_evsel *evsel;
2596
+ struct evsel *evsel;
22542597 struct perf_event_attr attr = {
22552598 .type = type,
22562599 .config = config,
22572600 .disabled = 1,
22582601 };
2259
- struct thread_map *tmap = thread_map__new_by_tid(0);
2602
+ struct perf_thread_map *tmap = thread_map__new_by_tid(0);
22602603
22612604 if (tmap == NULL)
22622605 return false;
22632606
2264
- evsel = perf_evsel__new(&attr);
2607
+ evsel = evsel__new(&attr);
22652608 if (evsel) {
2266
- open_return = perf_evsel__open(evsel, NULL, tmap);
2609
+ open_return = evsel__open(evsel, NULL, tmap);
22672610 ret = open_return >= 0;
22682611
22692612 if (open_return == -EACCES) {
....@@ -2274,13 +2617,13 @@
22742617 * by default as some ARM machines do not support it.
22752618 *
22762619 */
2277
- evsel->attr.exclude_kernel = 1;
2278
- ret = perf_evsel__open(evsel, NULL, tmap) >= 0;
2620
+ evsel->core.attr.exclude_kernel = 1;
2621
+ ret = evsel__open(evsel, NULL, tmap) >= 0;
22792622 }
2280
- perf_evsel__delete(evsel);
2623
+ evsel__delete(evsel);
22812624 }
22822625
2283
- thread_map__put(tmap);
2626
+ perf_thread_map__put(tmap);
22842627 return ret;
22852628 }
22862629
....@@ -2381,12 +2724,11 @@
23812724 for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) {
23822725 for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) {
23832726 /* skip invalid cache type */
2384
- if (!perf_evsel__is_cache_op_valid(type, op))
2727
+ if (!evsel__is_cache_op_valid(type, op))
23852728 continue;
23862729
23872730 for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) {
2388
- __perf_evsel__hw_cache_type_op_res_name(type, op, i,
2389
- name, sizeof(name));
2731
+ __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name));
23902732 if (event_glob != NULL && !strglobmatch(name, event_glob))
23912733 continue;
23922734
....@@ -2436,6 +2778,25 @@
24362778 if (evt_list)
24372779 goto out_free;
24382780 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");
24392800 }
24402801
24412802 void print_symbol_events(const char *event_glob, unsigned type,
....@@ -2514,18 +2875,19 @@
25142875 * Print the help text for the event symbols:
25152876 */
25162877 void print_events(const char *event_glob, bool name_only, bool quiet_flag,
2517
- bool long_desc, bool details_flag)
2878
+ bool long_desc, bool details_flag, bool deprecated)
25182879 {
25192880 print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
25202881 event_symbols_hw, PERF_COUNT_HW_MAX, name_only);
25212882
25222883 print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
25232884 event_symbols_sw, PERF_COUNT_SW_MAX, name_only);
2885
+ print_tool_events(event_glob, name_only);
25242886
25252887 print_hwcache_events(event_glob, name_only);
25262888
25272889 print_pmu_events(event_glob, name_only, quiet_flag, long_desc,
2528
- details_flag);
2890
+ details_flag, deprecated);
25292891
25302892 if (event_glob != NULL)
25312893 return;
....@@ -2551,7 +2913,9 @@
25512913
25522914 print_sdt_events(NULL, NULL, name_only);
25532915
2554
- 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);
25552919 }
25562920
25572921 int parse_events__is_hardcoded_term(struct parse_events_term *term)
....@@ -2678,6 +3042,18 @@
26783042 return new_term(new, &temp, str, 0);
26793043 }
26803044
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);
3055
+}
3056
+
26813057 int parse_events_copy_term_list(struct list_head *old,
26823058 struct list_head **new)
26833059 {
....@@ -2708,10 +3084,8 @@
27083084 struct parse_events_term *term, *h;
27093085
27103086 list_for_each_entry_safe(term, h, terms, list) {
2711
- if (term->array.nr_ranges)
2712
- zfree(&term->array.ranges);
27133087 list_del_init(&term->list);
2714
- free(term);
3088
+ parse_events_term__delete(term);
27153089 }
27163090 }
27173091
....@@ -2731,13 +3105,10 @@
27313105 void parse_events_evlist_error(struct parse_events_state *parse_state,
27323106 int idx, const char *str)
27333107 {
2734
- struct parse_events_error *err = parse_state->error;
2735
-
2736
- if (!err)
3108
+ if (!parse_state->error)
27373109 return;
2738
- err->idx = idx;
2739
- err->str = strdup(str);
2740
- WARN_ONCE(!err->str, "WARNING: failed to allocate error string");
3110
+
3111
+ parse_events__handle_error(parse_state->error, idx, strdup(str), NULL);
27413112 }
27423113
27433114 static void config_terms_list(char *buf, size_t buf_sz)