aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-12-13 11:13:07 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-24 14:40:08 -0500
commit594ac61ad3be9c80c738a9fe3bb95c05d8d1bae1 (patch)
tree3fb2c1395bafd1799e34443d58adef6c4b65c7fe /tools
parentce90e3856ba55af4d3d9c9c1168cc624607f6c7c (diff)
perf evsel: Do missing feature fallbacks in just one place
Instead of doing it in stat, top, record or any other tool that opens event descriptors. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-vr8hzph83d5t2mdlkf565h84@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-record.c36
-rw-r--r--tools/perf/builtin-stat.c30
-rw-r--r--tools/perf/builtin-top.c20
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/util/evsel.c31
-rw-r--r--tools/perf/util/top.h2
6 files changed, 31 insertions, 90 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 028de726b832..a4b97269cfc6 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -234,25 +234,6 @@ static int perf_record__open(struct perf_record *rec)
234 234
235 list_for_each_entry(pos, &evlist->entries, node) { 235 list_for_each_entry(pos, &evlist->entries, node) {
236 struct perf_event_attr *attr = &pos->attr; 236 struct perf_event_attr *attr = &pos->attr;
237 /*
238 * Check if parse_single_tracepoint_event has already asked for
239 * PERF_SAMPLE_TIME.
240 *
241 * XXX this is kludgy but short term fix for problems introduced by
242 * eac23d1c that broke 'perf script' by having different sample_types
243 * when using multiple tracepoint events when we use a perf binary
244 * that tries to use sample_id_all on an older kernel.
245 *
246 * We need to move counter creation to perf_session, support
247 * different sample_types, etc.
248 */
249 bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
250
251fallback_missing_features:
252 if (opts->exclude_guest_missing)
253 attr->exclude_guest = attr->exclude_host = 0;
254retry_sample_id:
255 attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
256try_again: 237try_again:
257 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) { 238 if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
258 int err = errno; 239 int err = errno;
@@ -266,23 +247,6 @@ try_again:
266 " an out-of-range profile CPU?\n"); 247 " an out-of-range profile CPU?\n");
267 rc = -err; 248 rc = -err;
268 goto out; 249 goto out;
269 } else if (err == EINVAL) {
270 if (!opts->exclude_guest_missing &&
271 (attr->exclude_guest || attr->exclude_host)) {
272 pr_debug("Old kernel, cannot exclude "
273 "guest or host samples.\n");
274 opts->exclude_guest_missing = true;
275 goto fallback_missing_features;
276 } else if (!opts->sample_id_all_missing) {
277 /*
278 * Old kernel, no attr->sample_id_type_all field
279 */
280 opts->sample_id_all_missing = true;
281 if (!opts->sample_time && !opts->raw_samples && !time_needed)
282 perf_evsel__reset_sample_bit(pos, TIME);
283
284 goto retry_sample_id;
285 }
286 } 250 }
287 251
288 /* 252 /*
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c12655af2b88..ef067c193f93 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -132,8 +132,6 @@ static struct stats walltime_nsecs_stats;
132static int create_perf_stat_counter(struct perf_evsel *evsel) 132static int create_perf_stat_counter(struct perf_evsel *evsel)
133{ 133{
134 struct perf_event_attr *attr = &evsel->attr; 134 struct perf_event_attr *attr = &evsel->attr;
135 bool exclude_guest_missing = false;
136 int ret;
137 135
138 if (scale) 136 if (scale)
139 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 137 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
@@ -141,16 +139,8 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
141 139
142 attr->inherit = !no_inherit; 140 attr->inherit = !no_inherit;
143 141
144retry: 142 if (perf_target__has_cpu(&target))
145 if (exclude_guest_missing) 143 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
146 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
147
148 if (perf_target__has_cpu(&target)) {
149 ret = perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
150 if (ret)
151 goto check_ret;
152 return 0;
153 }
154 144
155 if (!perf_target__has_task(&target) && 145 if (!perf_target__has_task(&target) &&
156 perf_evsel__is_group_leader(evsel)) { 146 perf_evsel__is_group_leader(evsel)) {
@@ -158,21 +148,7 @@ retry:
158 attr->enable_on_exec = 1; 148 attr->enable_on_exec = 1;
159 } 149 }
160 150
161 ret = perf_evsel__open_per_thread(evsel, evsel_list->threads); 151 return perf_evsel__open_per_thread(evsel, evsel_list->threads);
162 if (!ret)
163 return 0;
164 /* fall through */
165check_ret:
166 if (ret && errno == EINVAL) {
167 if (!exclude_guest_missing &&
168 (evsel->attr.exclude_guest || evsel->attr.exclude_host)) {
169 pr_debug("Old kernel, cannot exclude "
170 "guest or host samples.\n");
171 exclude_guest_missing = true;
172 goto retry;
173 }
174 }
175 return ret;
176} 152}
177 153
178/* 154/*
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index b7d2ea62dbc6..74fca619fc4e 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -900,12 +900,6 @@ static void perf_top__start_counters(struct perf_top *top)
900 900
901 list_for_each_entry(counter, &evlist->entries, node) { 901 list_for_each_entry(counter, &evlist->entries, node) {
902 struct perf_event_attr *attr = &counter->attr; 902 struct perf_event_attr *attr = &counter->attr;
903
904fallback_missing_features:
905 if (top->exclude_guest_missing)
906 attr->exclude_guest = attr->exclude_host = 0;
907retry_sample_id:
908 attr->sample_id_all = top->sample_id_all_missing ? 0 : 1;
909try_again: 903try_again:
910 if (perf_evsel__open(counter, top->evlist->cpus, 904 if (perf_evsel__open(counter, top->evlist->cpus,
911 top->evlist->threads) < 0) { 905 top->evlist->threads) < 0) {
@@ -914,20 +908,6 @@ try_again:
914 if (err == EPERM || err == EACCES) { 908 if (err == EPERM || err == EACCES) {
915 ui__error_paranoid(); 909 ui__error_paranoid();
916 goto out_err; 910 goto out_err;
917 } else if (err == EINVAL) {
918 if (!top->exclude_guest_missing &&
919 (attr->exclude_guest || attr->exclude_host)) {
920 pr_debug("Old kernel, cannot exclude "
921 "guest or host samples.\n");
922 top->exclude_guest_missing = true;
923 goto fallback_missing_features;
924 } else if (!top->sample_id_all_missing) {
925 /*
926 * Old kernel, no attr->sample_id_type_all field
927 */
928 top->sample_id_all_missing = true;
929 goto retry_sample_id;
930 }
931 } 911 }
932 /* 912 /*
933 * If it's cycles then fall back to hrtimer 913 * If it's cycles then fall back to hrtimer
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 2c340e7da458..7622f15bcfb7 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -237,8 +237,6 @@ struct perf_record_opts {
237 bool raw_samples; 237 bool raw_samples;
238 bool sample_address; 238 bool sample_address;
239 bool sample_time; 239 bool sample_time;
240 bool sample_id_all_missing;
241 bool exclude_guest_missing;
242 bool period; 240 bool period;
243 unsigned int freq; 241 unsigned int freq;
244 unsigned int mmap_pages; 242 unsigned int mmap_pages;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7a2a3dc3ff03..ee6ee3f45c2a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -22,6 +22,11 @@
22#include <linux/perf_event.h> 22#include <linux/perf_event.h>
23#include "perf_regs.h" 23#include "perf_regs.h"
24 24
25static struct {
26 bool sample_id_all;
27 bool exclude_guest;
28} perf_missing_features;
29
25#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 30#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
26 31
27static int __perf_evsel__sample_size(u64 sample_type) 32static int __perf_evsel__sample_size(u64 sample_type)
@@ -463,7 +468,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
463 struct perf_event_attr *attr = &evsel->attr; 468 struct perf_event_attr *attr = &evsel->attr;
464 int track = !evsel->idx; /* only the first counter needs these */ 469 int track = !evsel->idx; /* only the first counter needs these */
465 470
466 attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; 471 attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
467 attr->inherit = !opts->no_inherit; 472 attr->inherit = !opts->no_inherit;
468 473
469 perf_evsel__set_sample_bit(evsel, IP); 474 perf_evsel__set_sample_bit(evsel, IP);
@@ -513,7 +518,7 @@ void perf_evsel__config(struct perf_evsel *evsel,
513 if (opts->period) 518 if (opts->period)
514 perf_evsel__set_sample_bit(evsel, PERIOD); 519 perf_evsel__set_sample_bit(evsel, PERIOD);
515 520
516 if (!opts->sample_id_all_missing && 521 if (!perf_missing_features.sample_id_all &&
517 (opts->sample_time || !opts->no_inherit || 522 (opts->sample_time || !opts->no_inherit ||
518 perf_target__has_cpu(&opts->target))) 523 perf_target__has_cpu(&opts->target)))
519 perf_evsel__set_sample_bit(evsel, TIME); 524 perf_evsel__set_sample_bit(evsel, TIME);
@@ -761,6 +766,13 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
761 pid = evsel->cgrp->fd; 766 pid = evsel->cgrp->fd;
762 } 767 }
763 768
769fallback_missing_features:
770 if (perf_missing_features.exclude_guest)
771 evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
772retry_sample_id:
773 if (perf_missing_features.sample_id_all)
774 evsel->attr.sample_id_all = 0;
775
764 for (cpu = 0; cpu < cpus->nr; cpu++) { 776 for (cpu = 0; cpu < cpus->nr; cpu++) {
765 777
766 for (thread = 0; thread < threads->nr; thread++) { 778 for (thread = 0; thread < threads->nr; thread++) {
@@ -777,13 +789,26 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
777 group_fd, flags); 789 group_fd, flags);
778 if (FD(evsel, cpu, thread) < 0) { 790 if (FD(evsel, cpu, thread) < 0) {
779 err = -errno; 791 err = -errno;
780 goto out_close; 792 goto try_fallback;
781 } 793 }
782 } 794 }
783 } 795 }
784 796
785 return 0; 797 return 0;
786 798
799try_fallback:
800 if (err != -EINVAL || cpu > 0 || thread > 0)
801 goto out_close;
802
803 if (!perf_missing_features.exclude_guest &&
804 (evsel->attr.exclude_guest || evsel->attr.exclude_host)) {
805 perf_missing_features.exclude_guest = true;
806 goto fallback_missing_features;
807 } else if (!perf_missing_features.sample_id_all) {
808 perf_missing_features.sample_id_all = true;
809 goto retry_sample_id;
810 }
811
787out_close: 812out_close:
788 do { 813 do {
789 while (--thread >= 0) { 814 while (--thread >= 0) {
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 927c229c2d9a..7ebf357dc9e1 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -29,8 +29,6 @@ struct perf_top {
29 bool sort_has_symbols; 29 bool sort_has_symbols;
30 bool kptr_restrict_warned; 30 bool kptr_restrict_warned;
31 bool vmlinux_warned; 31 bool vmlinux_warned;
32 bool sample_id_all_missing;
33 bool exclude_guest_missing;
34 bool dump_symtab; 32 bool dump_symtab;
35 struct hist_entry *sym_filter_entry; 33 struct hist_entry *sym_filter_entry;
36 struct perf_evsel *sym_evsel; 34 struct perf_evsel *sym_evsel;