Commit 83d7f5f1 authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf inject: Add --vm-time-correlation option

Intel PT timestamps are affected by virtualization. Add a new option
that will allow the Intel PT decoder to correlate the timestamps and
translate the virtual machine timestamps to host timestamps.

The advantages of making this a separate step, rather than a part of
normal decoding are that it is simpler to implement, and it needs to
be done only once.

This patch adds only the option. Later patches add Intel PT support.
Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: https://lore.kernel.org/r/20210430070309.17624-6-adrian.hunter@intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 2a525f6a
...@@ -68,6 +68,16 @@ include::itrace.txt[] ...@@ -68,6 +68,16 @@ include::itrace.txt[]
--force:: --force::
Don't complain, do it. Don't complain, do it.
--vm-time-correlation[=OPTIONS]::
Some architectures may capture AUX area data which contains timestamps
affected by virtualization. This option will update those timestamps
in place, to correlate with host timestamps. The in-place update means
that an output file is not specified, and instead the input file is
modified. The options are architecture specific, except that they may
start with "dry-run" which will cause the file to be processed but
without updating it. Currently this option is supported only by
Intel PT, refer linkperf:perf-intel-pt[1]
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1], linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1],
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */ #include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
#include <linux/list.h> #include <linux/list.h>
#include <linux/string.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
...@@ -698,6 +699,36 @@ static void strip_init(struct perf_inject *inject) ...@@ -698,6 +699,36 @@ static void strip_init(struct perf_inject *inject)
evsel->handler = drop_sample; evsel->handler = drop_sample;
} }
static int parse_vm_time_correlation(const struct option *opt, const char *str, int unset)
{
struct perf_inject *inject = opt->value;
const char *args;
char *dry_run;
if (unset)
return 0;
inject->itrace_synth_opts.set = true;
inject->itrace_synth_opts.vm_time_correlation = true;
inject->in_place_update = true;
if (!str)
return 0;
dry_run = skip_spaces(str);
if (!strncmp(dry_run, "dry-run", strlen("dry-run"))) {
inject->itrace_synth_opts.vm_tm_corr_dry_run = true;
inject->in_place_update_dry_run = true;
args = dry_run + strlen("dry-run");
} else {
args = str;
}
inject->itrace_synth_opts.vm_tm_corr_args = strdup(args);
return inject->itrace_synth_opts.vm_tm_corr_args ? 0 : -ENOMEM;
}
static int __cmd_inject(struct perf_inject *inject) static int __cmd_inject(struct perf_inject *inject)
{ {
int ret = -EINVAL; int ret = -EINVAL;
...@@ -739,6 +770,15 @@ static int __cmd_inject(struct perf_inject *inject) ...@@ -739,6 +770,15 @@ static int __cmd_inject(struct perf_inject *inject)
else if (!strncmp(name, "sched:sched_stat_", 17)) else if (!strncmp(name, "sched:sched_stat_", 17))
evsel->handler = perf_inject__sched_stat; evsel->handler = perf_inject__sched_stat;
} }
} else if (inject->itrace_synth_opts.vm_time_correlation) {
session->itrace_synth_opts = &inject->itrace_synth_opts;
memset(&inject->tool, 0, sizeof(inject->tool));
inject->tool.id_index = perf_event__process_id_index;
inject->tool.auxtrace_info = perf_event__process_auxtrace_info;
inject->tool.auxtrace = perf_event__process_auxtrace;
inject->tool.auxtrace_error = perf_event__process_auxtrace_error;
inject->tool.ordered_events = true;
inject->tool.ordering_requires_timestamps = true;
} else if (inject->itrace_synth_opts.set) { } else if (inject->itrace_synth_opts.set) {
session->itrace_synth_opts = &inject->itrace_synth_opts; session->itrace_synth_opts = &inject->itrace_synth_opts;
inject->itrace_synth_opts.inject = true; inject->itrace_synth_opts.inject = true;
...@@ -880,6 +920,9 @@ int cmd_inject(int argc, const char **argv) ...@@ -880,6 +920,9 @@ int cmd_inject(int argc, const char **argv)
itrace_parse_synth_opts), itrace_parse_synth_opts),
OPT_BOOLEAN(0, "strip", &inject.strip, OPT_BOOLEAN(0, "strip", &inject.strip,
"strip non-synthesized events (use with --itrace)"), "strip non-synthesized events (use with --itrace)"),
OPT_CALLBACK_OPTARG(0, "vm-time-correlation", &inject, NULL, "opts",
"correlate time between VM guests and the host",
parse_vm_time_correlation),
OPT_END() OPT_END()
}; };
const char * const inject_usage[] = { const char * const inject_usage[] = {
...@@ -968,5 +1011,6 @@ int cmd_inject(int argc, const char **argv) ...@@ -968,5 +1011,6 @@ int cmd_inject(int argc, const char **argv)
out_delete: out_delete:
zstd_fini(&(inject.session->zstd_data)); zstd_fini(&(inject.session->zstd_data));
perf_session__delete(inject.session); perf_session__delete(inject.session);
free(inject.itrace_synth_opts.vm_tm_corr_args);
return ret; return ret;
} }
...@@ -90,6 +90,9 @@ enum itrace_period_type { ...@@ -90,6 +90,9 @@ enum itrace_period_type {
* @remote_access: whether to synthesize remote access events * @remote_access: whether to synthesize remote access events
* @mem: whether to synthesize memory events * @mem: whether to synthesize memory events
* @timeless_decoding: prefer "timeless" decoding i.e. ignore timestamps * @timeless_decoding: prefer "timeless" decoding i.e. ignore timestamps
* @vm_time_correlation: perform VM Time Correlation
* @vm_tm_corr_dry_run: VM Time Correlation dry-run
* @vm_tm_corr_args: VM Time Correlation implementation-specific arguments
* @callchain_sz: maximum callchain size * @callchain_sz: maximum callchain size
* @last_branch_sz: branch context size * @last_branch_sz: branch context size
* @period: 'instructions' events period * @period: 'instructions' events period
...@@ -130,6 +133,9 @@ struct itrace_synth_opts { ...@@ -130,6 +133,9 @@ struct itrace_synth_opts {
bool remote_access; bool remote_access;
bool mem; bool mem;
bool timeless_decoding; bool timeless_decoding;
bool vm_time_correlation;
bool vm_tm_corr_dry_run;
char *vm_tm_corr_args;
unsigned int callchain_sz; unsigned int callchain_sz;
unsigned int last_branch_sz; unsigned int last_branch_sz;
unsigned long long period; unsigned long long period;
......
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