aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/parse-events.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2015-07-29 05:42:10 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-07-29 15:15:57 -0400
commit930a2e29758f865e3a7b34b8b3b37c08d40f0254 (patch)
treeb5e21e669dbf884b9549971322f171ef3baa53e7 /tools/perf/util/parse-events.c
parent4c7de49a2977aa2a0f556c803afbb24848372e7a (diff)
perf tools: Add support for event post configuration
Add support to overload any global settings for event and force user specified term value. It will be useful for new time and backtrace terms. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Andi Kleen <ak@linux.intel.com> Cc: Kan Liang <kan.liang@intel.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/1438162936-59698-2-git-send-email-kan.liang@intel.com Signed-off-by: Kan Liang <kan.liang@intel.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/parse-events.c')
-rw-r--r--tools/perf/util/parse-events.c67
1 files changed, 56 insertions, 11 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4f807fc1b14a..3271d134e8c1 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -276,7 +276,8 @@ const char *event_type(int type)
276static struct perf_evsel * 276static struct perf_evsel *
277__add_event(struct list_head *list, int *idx, 277__add_event(struct list_head *list, int *idx,
278 struct perf_event_attr *attr, 278 struct perf_event_attr *attr,
279 char *name, struct cpu_map *cpus) 279 char *name, struct cpu_map *cpus,
280 struct list_head *config_terms)
280{ 281{
281 struct perf_evsel *evsel; 282 struct perf_evsel *evsel;
282 283
@@ -291,14 +292,19 @@ __add_event(struct list_head *list, int *idx,
291 292
292 if (name) 293 if (name)
293 evsel->name = strdup(name); 294 evsel->name = strdup(name);
295
296 if (config_terms)
297 list_splice(config_terms, &evsel->config_terms);
298
294 list_add_tail(&evsel->node, list); 299 list_add_tail(&evsel->node, list);
295 return evsel; 300 return evsel;
296} 301}
297 302
298static int add_event(struct list_head *list, int *idx, 303static int add_event(struct list_head *list, int *idx,
299 struct perf_event_attr *attr, char *name) 304 struct perf_event_attr *attr, char *name,
305 struct list_head *config_terms)
300{ 306{
301 return __add_event(list, idx, attr, name, NULL) ? 0 : -ENOMEM; 307 return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM;
302} 308}
303 309
304static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 310static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -377,7 +383,7 @@ int parse_events_add_cache(struct list_head *list, int *idx,
377 memset(&attr, 0, sizeof(attr)); 383 memset(&attr, 0, sizeof(attr));
378 attr.config = cache_type | (cache_op << 8) | (cache_result << 16); 384 attr.config = cache_type | (cache_op << 8) | (cache_result << 16);
379 attr.type = PERF_TYPE_HW_CACHE; 385 attr.type = PERF_TYPE_HW_CACHE;
380 return add_event(list, idx, &attr, name); 386 return add_event(list, idx, &attr, name, NULL);
381} 387}
382 388
383static int add_tracepoint(struct list_head *list, int *idx, 389static int add_tracepoint(struct list_head *list, int *idx,
@@ -539,7 +545,7 @@ int parse_events_add_breakpoint(struct list_head *list, int *idx,
539 attr.type = PERF_TYPE_BREAKPOINT; 545 attr.type = PERF_TYPE_BREAKPOINT;
540 attr.sample_period = 1; 546 attr.sample_period = 1;
541 547
542 return add_event(list, idx, &attr, NULL); 548 return add_event(list, idx, &attr, NULL, NULL);
543} 549}
544 550
545static int check_type_val(struct parse_events_term *term, 551static int check_type_val(struct parse_events_term *term,
@@ -622,22 +628,56 @@ static int config_attr(struct perf_event_attr *attr,
622 return 0; 628 return 0;
623} 629}
624 630
631static int get_config_terms(struct list_head *head_config,
632 struct list_head *head_terms __maybe_unused)
633{
634#define ADD_CONFIG_TERM(__type, __name, __val) \
635do { \
636 struct perf_evsel_config_term *__t; \
637 \
638 __t = zalloc(sizeof(*__t)); \
639 if (!__t) \
640 return -ENOMEM; \
641 \
642 INIT_LIST_HEAD(&__t->list); \
643 __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \
644 __t->val.__name = __val; \
645 list_add_tail(&__t->list, head_terms); \
646} while (0)
647
648 struct parse_events_term *term;
649
650 list_for_each_entry(term, head_config, list) {
651 switch (term->type_term) {
652 default:
653 break;
654 }
655 }
656#undef ADD_EVSEL_CONFIG
657 return 0;
658}
659
625int parse_events_add_numeric(struct parse_events_evlist *data, 660int parse_events_add_numeric(struct parse_events_evlist *data,
626 struct list_head *list, 661 struct list_head *list,
627 u32 type, u64 config, 662 u32 type, u64 config,
628 struct list_head *head_config) 663 struct list_head *head_config)
629{ 664{
630 struct perf_event_attr attr; 665 struct perf_event_attr attr;
666 LIST_HEAD(config_terms);
631 667
632 memset(&attr, 0, sizeof(attr)); 668 memset(&attr, 0, sizeof(attr));
633 attr.type = type; 669 attr.type = type;
634 attr.config = config; 670 attr.config = config;
635 671
636 if (head_config && 672 if (head_config) {
637 config_attr(&attr, head_config, data->error)) 673 if (config_attr(&attr, head_config, data->error))
638 return -EINVAL; 674 return -EINVAL;
675
676 if (get_config_terms(head_config, &config_terms))
677 return -ENOMEM;
678 }
639 679
640 return add_event(list, &data->idx, &attr, NULL); 680 return add_event(list, &data->idx, &attr, NULL, &config_terms);
641} 681}
642 682
643static int parse_events__is_name_term(struct parse_events_term *term) 683static int parse_events__is_name_term(struct parse_events_term *term)
@@ -664,6 +704,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
664 struct perf_pmu_info info; 704 struct perf_pmu_info info;
665 struct perf_pmu *pmu; 705 struct perf_pmu *pmu;
666 struct perf_evsel *evsel; 706 struct perf_evsel *evsel;
707 LIST_HEAD(config_terms);
667 708
668 pmu = perf_pmu__find(name); 709 pmu = perf_pmu__find(name);
669 if (!pmu) 710 if (!pmu)
@@ -678,7 +719,7 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
678 719
679 if (!head_config) { 720 if (!head_config) {
680 attr.type = pmu->type; 721 attr.type = pmu->type;
681 evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus); 722 evsel = __add_event(list, &data->idx, &attr, NULL, pmu->cpus, NULL);
682 return evsel ? 0 : -ENOMEM; 723 return evsel ? 0 : -ENOMEM;
683 } 724 }
684 725
@@ -692,11 +733,15 @@ int parse_events_add_pmu(struct parse_events_evlist *data,
692 if (config_attr(&attr, head_config, data->error)) 733 if (config_attr(&attr, head_config, data->error))
693 return -EINVAL; 734 return -EINVAL;
694 735
736 if (get_config_terms(head_config, &config_terms))
737 return -ENOMEM;
738
695 if (perf_pmu__config(pmu, &attr, head_config, data->error)) 739 if (perf_pmu__config(pmu, &attr, head_config, data->error))
696 return -EINVAL; 740 return -EINVAL;
697 741
698 evsel = __add_event(list, &data->idx, &attr, 742 evsel = __add_event(list, &data->idx, &attr,
699 pmu_event_name(head_config), pmu->cpus); 743 pmu_event_name(head_config), pmu->cpus,
744 &config_terms);
700 if (evsel) { 745 if (evsel) {
701 evsel->unit = info.unit; 746 evsel->unit = info.unit;
702 evsel->scale = info.scale; 747 evsel->scale = info.scale;