aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-08-08 06:21:54 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-08-14 16:03:47 -0400
commitf5b1135bf79557563a814e53ecd610cce663c1e3 (patch)
treee19c6c85ba20e22dd43303d14774c534209aadd0
parent89efb029502d7f2d0993ed2aa9280c414336939c (diff)
perf tools: Add support to update event modifier
Adding support to update already defined event's attribute with event modifier. This change will allow to use group modifier as an update to the existing event modifiers. Adding 'add' parameter to the parse_events__modifier_event function. Calling it with 'add' = false/true, the event modifier is initialized/updated respectively. Added exclude_GH flag to evsel struct, because we need to remember if one of 'GH' modifiers was used for event. The reason is that the default settings for exclude_guest is 1 and during the group modifier processing we have no other way of knowing if it was set by default or by event modifier. Keeping the current behaviour, that any event/group modifier reset the defaults for exclude_host (0) and exclude_guest (1). Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Cc: Andi Kleen <andi@firstfloor.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ulrich Drepper <drepper@gmail.com> Link: http://lkml.kernel.org/n/tip-8peaey3e2qc9dwtkvzbi4wmx@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/evsel.h2
-rw-r--r--tools/perf/util/parse-events.c74
-rw-r--r--tools/perf/util/parse-events.h2
-rw-r--r--tools/perf/util/parse-events.y2
4 files changed, 66 insertions, 14 deletions
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a56c4574b3fe..6a258c90e7ce 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -68,6 +68,8 @@ struct perf_evsel {
68 } handler; 68 } handler;
69 unsigned int sample_size; 69 unsigned int sample_size;
70 bool supported; 70 bool supported;
71 /* parse modifier helper */
72 int exclude_GH;
71}; 73};
72 74
73struct cpu_map; 75struct cpu_map;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 57d5809f2860..4364575ce6ac 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -633,14 +633,38 @@ void parse_events_update_lists(struct list_head *list_event,
633 free(list_event); 633 free(list_event);
634} 634}
635 635
636int parse_events__modifier_event(struct list_head *list, char *str) 636struct event_modifier {
637 int eu;
638 int ek;
639 int eh;
640 int eH;
641 int eG;
642 int precise;
643 int exclude_GH;
644};
645
646static int get_event_modifier(struct event_modifier *mod, char *str,
647 struct perf_evsel *evsel)
637{ 648{
638 struct perf_evsel *evsel; 649 int eu = evsel ? evsel->attr.exclude_user : 0;
639 int exclude = 0, exclude_GH = 0; 650 int ek = evsel ? evsel->attr.exclude_kernel : 0;
640 int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; 651 int eh = evsel ? evsel->attr.exclude_hv : 0;
652 int eH = evsel ? evsel->attr.exclude_host : 0;
653 int eG = evsel ? evsel->attr.exclude_guest : 0;
654 int precise = evsel ? evsel->attr.precise_ip : 0;
641 655
642 if (str == NULL) 656 int exclude = eu | ek | eh;
643 return 0; 657 int exclude_GH = evsel ? evsel->exclude_GH : 0;
658
659 /*
660 * We are here for group and 'GH' was not set as event
661 * modifier and whatever event/group modifier override
662 * default 'GH' setup.
663 */
664 if (evsel && !exclude_GH)
665 eH = eG = 0;
666
667 memset(mod, 0, sizeof(*mod));
644 668
645 while (*str) { 669 while (*str) {
646 if (*str == 'u') { 670 if (*str == 'u') {
@@ -684,13 +708,39 @@ int parse_events__modifier_event(struct list_head *list, char *str)
684 if (precise > 3) 708 if (precise > 3)
685 return -EINVAL; 709 return -EINVAL;
686 710
711 mod->eu = eu;
712 mod->ek = ek;
713 mod->eh = eh;
714 mod->eH = eH;
715 mod->eG = eG;
716 mod->precise = precise;
717 mod->exclude_GH = exclude_GH;
718 return 0;
719}
720
721int parse_events__modifier_event(struct list_head *list, char *str, bool add)
722{
723 struct perf_evsel *evsel;
724 struct event_modifier mod;
725
726 if (str == NULL)
727 return 0;
728
729 if (!add && get_event_modifier(&mod, str, NULL))
730 return -EINVAL;
731
687 list_for_each_entry(evsel, list, node) { 732 list_for_each_entry(evsel, list, node) {
688 evsel->attr.exclude_user = eu; 733
689 evsel->attr.exclude_kernel = ek; 734 if (add && get_event_modifier(&mod, str, evsel))
690 evsel->attr.exclude_hv = eh; 735 return -EINVAL;
691 evsel->attr.precise_ip = precise; 736
692 evsel->attr.exclude_host = eH; 737 evsel->attr.exclude_user = mod.eu;
693 evsel->attr.exclude_guest = eG; 738 evsel->attr.exclude_kernel = mod.ek;
739 evsel->attr.exclude_hv = mod.eh;
740 evsel->attr.precise_ip = mod.precise;
741 evsel->attr.exclude_host = mod.eH;
742 evsel->attr.exclude_guest = mod.eG;
743 evsel->exclude_GH = mod.exclude_GH;
694 } 744 }
695 745
696 return 0; 746 return 0;
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c3bb04c6f025..75a6800082a1 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -79,7 +79,7 @@ int parse_events__term_str(struct parse_events__term **_term,
79int parse_events__term_clone(struct parse_events__term **new, 79int parse_events__term_clone(struct parse_events__term **new,
80 struct parse_events__term *term); 80 struct parse_events__term *term);
81void parse_events__free_terms(struct list_head *terms); 81void parse_events__free_terms(struct list_head *terms);
82int parse_events__modifier_event(struct list_head *list, char *str); 82int parse_events__modifier_event(struct list_head *list, char *str, bool add);
83int parse_events__modifier_group(struct list_head *list, char *event_mod); 83int parse_events__modifier_group(struct list_head *list, char *event_mod);
84int parse_events_add_tracepoint(struct list_head **list, int *idx, 84int parse_events_add_tracepoint(struct list_head **list, int *idx,
85 char *sys, char *event); 85 char *sys, char *event);
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index 15e6e97e5b34..084c35fc2d26 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -153,7 +153,7 @@ event_def PE_MODIFIER_EVENT
153 * (there could be more events added for multiple tracepoint 153 * (there could be more events added for multiple tracepoint
154 * definitions via '*?'. 154 * definitions via '*?'.
155 */ 155 */
156 ABORT_ON(parse_events__modifier_event(list, $2)); 156 ABORT_ON(parse_events__modifier_event(list, $2, false));
157 $$ = list; 157 $$ = list;
158} 158}
159| 159|