diff options
author | Stephane Eranian <eranian@google.com> | 2017-04-12 14:23:01 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-04-13 09:40:36 -0400 |
commit | db49a71798a38f3ddf3f3462703328dca39b1ac7 (patch) | |
tree | c6c7ba37ba155f9e89314f65059f9c3f3a699fcf | |
parent | 7be6b3166ebf2c10c28ef5777d1b31a937ed8f7a (diff) |
perf stat: Fix bug in handling events in error state
(This is a patch has been sitting in the Intel CQM/CMT driver series for
a while, despite not depend on it. Sending it now independently since
the series is being discarded.)
When an event is in error state, read() returns 0 instead of sizeof()
buffer. In certain modes, such as interval printing, ignoring the 0
return value may cause bogus count deltas to be computed and thus
invalid results printed.
This patch fixes this problem by modifying read_counters() to mark the
event as not scaled (scaled = -1) to force the printout routine to show
<NOT COUNTED>.
Signed-off-by: Stephane Eranian <eranian@google.com>
Reviewed-by: David Carrillo-Cisneros <davidcc@google.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Paul Turner <pjt@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/20170412182301.44406-1-davidcc@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-stat.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 4 |
2 files changed, 11 insertions, 5 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 868e086a6b59..610225b6326e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -312,8 +312,12 @@ static int read_counter(struct perf_evsel *counter) | |||
312 | struct perf_counts_values *count; | 312 | struct perf_counts_values *count; |
313 | 313 | ||
314 | count = perf_counts(counter->counts, cpu, thread); | 314 | count = perf_counts(counter->counts, cpu, thread); |
315 | if (perf_evsel__read(counter, cpu, thread, count)) | 315 | if (perf_evsel__read(counter, cpu, thread, count)) { |
316 | counter->counts->scaled = -1; | ||
317 | perf_counts(counter->counts, cpu, thread)->ena = 0; | ||
318 | perf_counts(counter->counts, cpu, thread)->run = 0; | ||
316 | return -1; | 319 | return -1; |
320 | } | ||
317 | 321 | ||
318 | if (STAT_RECORD) { | 322 | if (STAT_RECORD) { |
319 | if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { | 323 | if (perf_evsel__write_stat_event(counter, cpu, thread, count)) { |
@@ -338,12 +342,14 @@ static int read_counter(struct perf_evsel *counter) | |||
338 | static void read_counters(void) | 342 | static void read_counters(void) |
339 | { | 343 | { |
340 | struct perf_evsel *counter; | 344 | struct perf_evsel *counter; |
345 | int ret; | ||
341 | 346 | ||
342 | evlist__for_each_entry(evsel_list, counter) { | 347 | evlist__for_each_entry(evsel_list, counter) { |
343 | if (read_counter(counter)) | 348 | ret = read_counter(counter); |
349 | if (ret) | ||
344 | pr_debug("failed to read counter %s\n", counter->name); | 350 | pr_debug("failed to read counter %s\n", counter->name); |
345 | 351 | ||
346 | if (perf_stat_process_counter(&stat_config, counter)) | 352 | if (ret == 0 && perf_stat_process_counter(&stat_config, counter)) |
347 | pr_warning("failed to process counter %s\n", counter->name); | 353 | pr_warning("failed to process counter %s\n", counter->name); |
348 | } | 354 | } |
349 | } | 355 | } |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8f5d86bd3501..3779b9f3f134 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1239,7 +1239,7 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread, | |||
1239 | if (FD(evsel, cpu, thread) < 0) | 1239 | if (FD(evsel, cpu, thread) < 0) |
1240 | return -EINVAL; | 1240 | return -EINVAL; |
1241 | 1241 | ||
1242 | if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) < 0) | 1242 | if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) <= 0) |
1243 | return -errno; | 1243 | return -errno; |
1244 | 1244 | ||
1245 | return 0; | 1245 | return 0; |
@@ -1257,7 +1257,7 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, | |||
1257 | if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0) | 1257 | if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0) |
1258 | return -ENOMEM; | 1258 | return -ENOMEM; |
1259 | 1259 | ||
1260 | if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0) | 1260 | if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0) |
1261 | return -errno; | 1261 | return -errno; |
1262 | 1262 | ||
1263 | perf_evsel__compute_deltas(evsel, cpu, thread, &count); | 1263 | perf_evsel__compute_deltas(evsel, cpu, thread, &count); |