aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-10-10 11:39:03 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-08-07 16:35:22 -0400
commit3c1763115b492afb743daa4e1c8099eca6a70634 (patch)
treeca66a59ca4bc62f8e88dbcefa238405deede2d60 /tools
parente4caec0d1af3d608d52e6b92d09fb862d7691d4b (diff)
perf tools: Add 'S' event/group modifier to read sample value
Adding 'S' event/group modifier to specify that the event value/s are read by PERF_SAMPLE_READ sample type processing, instead of the period value offered by lower layers. There's additional behaviour change for 'S' modifier being specified on event group: Currently all the events within a group makes samples. If user now specifies 'S' within group modifier, only the leader will trigger samples. The rest of events in the group will have sampling disabled. And same as for single events, values of all events within the group (including leader) are read by PERF_SAMPLE_READ sample type processing. Following example will create event group with cycles and cache-misses events, setting the cycles as group leader and the only event to actually sample. Both cycles and cache-misses event period values are read by PERF_SAMPLE_READ sample type processing with PERF_FORMAT_GROUP read format. Example: $ perf record -e '{cycles,cache-misses}:S' ls ... $ perf report --group --show-total-period --stdio ... # Samples: 36 of event 'anon group { cycles, cache-misses }' # Event count (approx.): 12585593 # # Overhead Period Command Shared Object Symbol # .............. .............. ....... ................. .......................... # 19.92% 1.20% 2505936 31 ls [kernel.kallsyms] [k] mark_held_locks 13.74% 0.47% 1729327 12 ls [kernel.kallsyms] [k] sched_clock_local 13.64% 23.72% 1716147 612 ls ld-2.14.90.so [.] check_match.10805 13.12% 23.22% 1650778 599 ls libc-2.14.90.so [.] _nl_intern_locale_data 11.24% 29.19% 1414554 753 ls [kernel.kallsyms] [k] sched_clock_cpu 8.50% 0.35% 1070150 9 ls [kernel.kallsyms] [k] check_chain_key ... Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/n/tip-iyoinu3axi11mymwnh2b7fxj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-list.txt1
-rw-r--r--tools/perf/util/evsel.c29
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/parse-events.c8
-rw-r--r--tools/perf/util/parse-events.l2
5 files changed, 39 insertions, 2 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index 826f3d6d1d28..eb03f063f0a2 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -29,6 +29,7 @@ counted. The following modifiers exist:
29 G - guest counting (in KVM guests) 29 G - guest counting (in KVM guests)
30 H - host counting (not in KVM guests) 30 H - host counting (not in KVM guests)
31 p - precise level 31 p - precise level
32 S - read sample value (PERF_SAMPLE_READ)
32 33
33The 'p' modifier can be used for specifying how precise the instruction 34The 'p' modifier can be used for specifying how precise the instruction
34address should be. The 'p' modifier can be specified multiple times: 35address should be. The 'p' modifier can be specified multiple times:
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 9ab8fff74e30..8f1016186d57 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -490,6 +490,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
490void perf_evsel__config(struct perf_evsel *evsel, 490void perf_evsel__config(struct perf_evsel *evsel,
491 struct perf_record_opts *opts) 491 struct perf_record_opts *opts)
492{ 492{
493 struct perf_evsel *leader = evsel->leader;
493 struct perf_event_attr *attr = &evsel->attr; 494 struct perf_event_attr *attr = &evsel->attr;
494 int track = !evsel->idx; /* only the first counter needs these */ 495 int track = !evsel->idx; /* only the first counter needs these */
495 496
@@ -499,6 +500,25 @@ void perf_evsel__config(struct perf_evsel *evsel,
499 perf_evsel__set_sample_bit(evsel, IP); 500 perf_evsel__set_sample_bit(evsel, IP);
500 perf_evsel__set_sample_bit(evsel, TID); 501 perf_evsel__set_sample_bit(evsel, TID);
501 502
503 if (evsel->sample_read) {
504 perf_evsel__set_sample_bit(evsel, READ);
505
506 /*
507 * We need ID even in case of single event, because
508 * PERF_SAMPLE_READ process ID specific data.
509 */
510 perf_evsel__set_sample_id(evsel);
511
512 /*
513 * Apply group format only if we belong to group
514 * with more than one members.
515 */
516 if (leader->nr_members > 1) {
517 attr->read_format |= PERF_FORMAT_GROUP;
518 attr->inherit = 0;
519 }
520 }
521
502 /* 522 /*
503 * We default some events to a 1 default interval. But keep 523 * We default some events to a 1 default interval. But keep
504 * it a weak assumption overridable by the user. 524 * it a weak assumption overridable by the user.
@@ -514,6 +534,15 @@ void perf_evsel__config(struct perf_evsel *evsel,
514 } 534 }
515 } 535 }
516 536
537 /*
538 * Disable sampling for all group members other
539 * than leader in case leader 'leads' the sampling.
540 */
541 if ((leader != evsel) && leader->sample_read) {
542 attr->sample_freq = 0;
543 attr->sample_period = 0;
544 }
545
517 if (opts->no_samples) 546 if (opts->no_samples)
518 attr->sample_freq = 0; 547 attr->sample_freq = 0;
519 548
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 6a2cf261f38e..5edc625b6ecd 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -79,6 +79,7 @@ struct perf_evsel {
79 /* parse modifier helper */ 79 /* parse modifier helper */
80 int exclude_GH; 80 int exclude_GH;
81 int nr_members; 81 int nr_members;
82 int sample_read;
82 struct perf_evsel *leader; 83 struct perf_evsel *leader;
83 char *group_name; 84 char *group_name;
84}; 85};
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 2c460ede0a69..dba877dc9482 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -687,6 +687,7 @@ struct event_modifier {
687 int eG; 687 int eG;
688 int precise; 688 int precise;
689 int exclude_GH; 689 int exclude_GH;
690 int sample_read;
690}; 691};
691 692
692static int get_event_modifier(struct event_modifier *mod, char *str, 693static int get_event_modifier(struct event_modifier *mod, char *str,
@@ -698,6 +699,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
698 int eH = evsel ? evsel->attr.exclude_host : 0; 699 int eH = evsel ? evsel->attr.exclude_host : 0;
699 int eG = evsel ? evsel->attr.exclude_guest : 0; 700 int eG = evsel ? evsel->attr.exclude_guest : 0;
700 int precise = evsel ? evsel->attr.precise_ip : 0; 701 int precise = evsel ? evsel->attr.precise_ip : 0;
702 int sample_read = 0;
701 703
702 int exclude = eu | ek | eh; 704 int exclude = eu | ek | eh;
703 int exclude_GH = evsel ? evsel->exclude_GH : 0; 705 int exclude_GH = evsel ? evsel->exclude_GH : 0;
@@ -730,6 +732,8 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
730 /* use of precise requires exclude_guest */ 732 /* use of precise requires exclude_guest */
731 if (!exclude_GH) 733 if (!exclude_GH)
732 eG = 1; 734 eG = 1;
735 } else if (*str == 'S') {
736 sample_read = 1;
733 } else 737 } else
734 break; 738 break;
735 739
@@ -756,6 +760,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
756 mod->eG = eG; 760 mod->eG = eG;
757 mod->precise = precise; 761 mod->precise = precise;
758 mod->exclude_GH = exclude_GH; 762 mod->exclude_GH = exclude_GH;
763 mod->sample_read = sample_read;
759 return 0; 764 return 0;
760} 765}
761 766
@@ -768,7 +773,7 @@ static int check_modifier(char *str)
768 char *p = str; 773 char *p = str;
769 774
770 /* The sizeof includes 0 byte as well. */ 775 /* The sizeof includes 0 byte as well. */
771 if (strlen(str) > (sizeof("ukhGHppp") - 1)) 776 if (strlen(str) > (sizeof("ukhGHpppS") - 1))
772 return -1; 777 return -1;
773 778
774 while (*p) { 779 while (*p) {
@@ -806,6 +811,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
806 evsel->attr.exclude_host = mod.eH; 811 evsel->attr.exclude_host = mod.eH;
807 evsel->attr.exclude_guest = mod.eG; 812 evsel->attr.exclude_guest = mod.eG;
808 evsel->exclude_GH = mod.exclude_GH; 813 evsel->exclude_GH = mod.exclude_GH;
814 evsel->sample_read = mod.sample_read;
809 } 815 }
810 816
811 return 0; 817 return 0;
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index e9d1134c2c68..b36115fe416a 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -82,7 +82,7 @@ num_hex 0x[a-fA-F0-9]+
82num_raw_hex [a-fA-F0-9]+ 82num_raw_hex [a-fA-F0-9]+
83name [a-zA-Z_*?][a-zA-Z0-9_*?]* 83name [a-zA-Z_*?][a-zA-Z0-9_*?]*
84name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]* 84name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?]*
85modifier_event [ukhpGH]+ 85modifier_event [ukhpGHS]+
86modifier_bp [rwx]{1,3} 86modifier_bp [rwx]{1,3}
87 87
88%% 88%%