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

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.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 2a525f6a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -68,6 +68,16 @@ include::itrace.txt[]
--force::
	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
--------
linkperf:perf-record[1], linkperf:perf-report[1], linkperf:perf-archive[1],
+44 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */

#include <linux/list.h>
#include <linux/string.h>
#include <errno.h>
#include <signal.h>

@@ -698,6 +699,36 @@ static void strip_init(struct perf_inject *inject)
		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)
{
	int ret = -EINVAL;
@@ -739,6 +770,15 @@ static int __cmd_inject(struct perf_inject *inject)
			else if (!strncmp(name, "sched:sched_stat_", 17))
				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) {
		session->itrace_synth_opts = &inject->itrace_synth_opts;
		inject->itrace_synth_opts.inject = true;
@@ -880,6 +920,9 @@ int cmd_inject(int argc, const char **argv)
				    itrace_parse_synth_opts),
		OPT_BOOLEAN(0, "strip", &inject.strip,
			    "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()
	};
	const char * const inject_usage[] = {
@@ -968,5 +1011,6 @@ int cmd_inject(int argc, const char **argv)
out_delete:
	zstd_fini(&(inject.session->zstd_data));
	perf_session__delete(inject.session);
	free(inject.itrace_synth_opts.vm_tm_corr_args);
	return ret;
}
+6 −0
Original line number Diff line number Diff line
@@ -90,6 +90,9 @@ enum itrace_period_type {
 * @remote_access: whether to synthesize remote access events
 * @mem: whether to synthesize memory events
 * @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
 * @last_branch_sz: branch context size
 * @period: 'instructions' events period
@@ -130,6 +133,9 @@ struct itrace_synth_opts {
	bool			remote_access;
	bool			mem;
	bool			timeless_decoding;
	bool			vm_time_correlation;
	bool			vm_tm_corr_dry_run;
	char			*vm_tm_corr_args;
	unsigned int		callchain_sz;
	unsigned int		last_branch_sz;
	unsigned long long	period;