Commit 05a1f47e authored by Alexander Shishkin's avatar Alexander Shishkin Committed by Arnaldo Carvalho de Melo

perf tools: Handle partial AUX records and print a warning

This patch decodes the 'partial' flag in AUX records and prints
a warning to the user, so that they don't have to guess why their
PT traces contain gaps (or missing altogether):

  Warning:
  AUX data had gaps in it 8 times out of 8!

  Are you running a KVM guest in the background?

Trying to be even more helpful, we will detect if the user's kvm driver sets up
exclusive VMX root mode for the entire lifespan of the kvm process:

  Reloading kvm_intel module with vmm_exclusive=0
  will reduce the gaps to only guest's timeslices.

Note however, that you'll still have gaps in cpu-wide traces even with
vmm_exclusive=0, but the number of gaps will be below 100% (as opposed to the
above example).

Currently this is the only reason for partial records.
Signed-off-by: default avatarAlexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Vince Weaver <vince@deater.net>
Link: http://lkml.kernel.org/r/8760j941ig.fsf@ashishki-desk.ger.corp.intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 38a33f07
...@@ -1288,11 +1288,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused, ...@@ -1288,11 +1288,12 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp) size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp)
{ {
return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s]\n", return fprintf(fp, " offset: %#"PRIx64" size: %#"PRIx64" flags: %#"PRIx64" [%s%s%s]\n",
event->aux.aux_offset, event->aux.aux_size, event->aux.aux_offset, event->aux.aux_size,
event->aux.flags, event->aux.flags,
event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "", event->aux.flags & PERF_AUX_FLAG_TRUNCATED ? "T" : "",
event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : ""); event->aux.flags & PERF_AUX_FLAG_OVERWRITE ? "O" : "",
event->aux.flags & PERF_AUX_FLAG_PARTIAL ? "P" : "");
} }
size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp) size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)
......
...@@ -276,6 +276,7 @@ struct events_stats { ...@@ -276,6 +276,7 @@ struct events_stats {
u64 total_lost; u64 total_lost;
u64 total_lost_samples; u64 total_lost_samples;
u64 total_aux_lost; u64 total_aux_lost;
u64 total_aux_partial;
u64 total_invalid_chains; u64 total_invalid_chains;
u32 nr_events[PERF_RECORD_HEADER_MAX]; u32 nr_events[PERF_RECORD_HEADER_MAX];
u32 nr_non_filtered_samples; u32 nr_non_filtered_samples;
......
#include <linux/kernel.h> #include <linux/kernel.h>
#include <traceevent/event-parse.h> #include <traceevent/event-parse.h>
#include <api/fs/fs.h>
#include <byteswap.h> #include <byteswap.h>
#include <unistd.h> #include <unistd.h>
...@@ -1260,9 +1261,12 @@ static int machines__deliver_event(struct machines *machines, ...@@ -1260,9 +1261,12 @@ static int machines__deliver_event(struct machines *machines,
case PERF_RECORD_UNTHROTTLE: case PERF_RECORD_UNTHROTTLE:
return tool->unthrottle(tool, event, sample, machine); return tool->unthrottle(tool, event, sample, machine);
case PERF_RECORD_AUX: case PERF_RECORD_AUX:
if (tool->aux == perf_event__process_aux && if (tool->aux == perf_event__process_aux) {
(event->aux.flags & PERF_AUX_FLAG_TRUNCATED)) if (event->aux.flags & PERF_AUX_FLAG_TRUNCATED)
evlist->stats.total_aux_lost += 1; evlist->stats.total_aux_lost += 1;
if (event->aux.flags & PERF_AUX_FLAG_PARTIAL)
evlist->stats.total_aux_partial += 1;
}
return tool->aux(tool, event, sample, machine); return tool->aux(tool, event, sample, machine);
case PERF_RECORD_ITRACE_START: case PERF_RECORD_ITRACE_START:
return tool->itrace_start(tool, event, sample, machine); return tool->itrace_start(tool, event, sample, machine);
...@@ -1555,6 +1559,23 @@ static void perf_session__warn_about_errors(const struct perf_session *session) ...@@ -1555,6 +1559,23 @@ static void perf_session__warn_about_errors(const struct perf_session *session)
stats->nr_events[PERF_RECORD_AUX]); stats->nr_events[PERF_RECORD_AUX]);
} }
if (session->tool->aux == perf_event__process_aux &&
stats->total_aux_partial != 0) {
bool vmm_exclusive = false;
(void)sysfs__read_bool("module/kvm_intel/parameters/vmm_exclusive",
&vmm_exclusive);
ui__warning("AUX data had gaps in it %" PRIu64 " times out of %u!\n\n"
"Are you running a KVM guest in the background?%s\n\n",
stats->total_aux_partial,
stats->nr_events[PERF_RECORD_AUX],
vmm_exclusive ?
"\nReloading kvm_intel module with vmm_exclusive=0\n"
"will reduce the gaps to only guest's timeslices." :
"");
}
if (stats->nr_unknown_events != 0) { if (stats->nr_unknown_events != 0) {
ui__warning("Found %u unknown events!\n\n" ui__warning("Found %u unknown events!\n\n"
"Is this an older tool processing a perf.data " "Is this an older tool processing a perf.data "
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment