Linux-Trace-Devel Archive on lore.kernel.org
 help / color / Atom feed
From: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org
Subject: [PATCH v4 20/23] trace-cmd: Use tsc clock for host-guest tracing, if available
Date: Thu, 25 Mar 2021 08:40:52 +0200
Message-ID: <20210325064055.539554-21-tz.stoyanov@gmail.com> (raw)
In-Reply-To: <20210325064055.539554-1-tz.stoyanov@gmail.com>

In a host-guest tracing session, if there is no user configured tracing
clock, use TSC by default if following conditions are met:
  - tsc-x86 trace clock is available on the host
  - params for tsc to nanosecond conversion can be retrieved using
    perf interface of the Liunx kernel - miltiplier and shift

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 tracecmd/trace-record.c | 97 ++++++++++++++++++++++++++++-------------
 1 file changed, 67 insertions(+), 30 deletions(-)

diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index 4e4ad127..d794f1af 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -198,8 +198,10 @@ struct common_record_context {
 	const char *output;
 	char *date2ts;
 	char *user;
+	const char *clock;
 	struct tsc_nsec tsc2nsec;
 	int data_flags;
+	int tsync_loop_interval;
 
 	int record_all;
 	int total_disable;
@@ -3708,7 +3710,8 @@ static int open_guest_fifos(const char *guest, int **fds)
 	return i;
 }
 
-static int host_tsync(struct buffer_instance *instance,
+static int host_tsync(struct common_record_context *ctx,
+		      struct buffer_instance *instance,
 		      unsigned int tsync_port, char *proto)
 {
 	struct trace_guest *guest;
@@ -3723,14 +3726,15 @@ static int host_tsync(struct buffer_instance *instance,
 						    instance->tsync_loop_interval,
 						    instance->cid, tsync_port,
 						    guest->pid, guest->cpu_max,
-						    proto, top_instance.clock);
+						    proto, ctx->clock);
 	if (!instance->tsync)
 		return -1;
 
 	return 0;
 }
 
-static void connect_to_agent(struct buffer_instance *instance)
+static void connect_to_agent(struct common_record_context *ctx,
+			     struct buffer_instance *instance)
 {
 	struct tracecmd_tsync_protos *protos = NULL;
 	int sd, ret, nr_fifos, nr_cpus, page_size;
@@ -3783,7 +3787,7 @@ static void connect_to_agent(struct buffer_instance *instance)
 			printf("Negotiated %s time sync protocol with guest %s\n",
 				tsync_protos_reply,
 				instance->name);
-			host_tsync(instance, tsync_port, tsync_protos_reply);
+			host_tsync(ctx, instance, tsync_port, tsync_protos_reply);
 		} else
 			warning("Failed to negotiate timestamps synchronization with the guest");
 	}
@@ -3862,7 +3866,7 @@ void start_threads(enum trace_type type, struct common_record_context *ctx)
 	for_all_instances(instance) {
 		/* Start the connection now to find out how many CPUs we need */
 		if (is_guest(instance))
-			connect_to_agent(instance);
+			connect_to_agent(ctx, instance);
 		total_cpu_count += instance->cpu_count;
 	}
 
@@ -4128,6 +4132,7 @@ enum {
 	DATA_FL_NONE		= 0,
 	DATA_FL_DATE		= 1,
 	DATA_FL_OFFSET		= 2,
+	DATA_FL_GUEST		= 4,
 };
 
 static void add_options(struct tracecmd_output *handle, struct common_record_context *ctx)
@@ -5812,7 +5817,6 @@ static void parse_record_options(int argc,
 	int name_counter = 0;
 	int negative = 0;
 	struct buffer_instance *instance, *del_list = NULL;
-	bool guest_sync_set = false;
 	int do_children = 0;
 	int fpids_count = 0;
 
@@ -5947,6 +5951,7 @@ static void parse_record_options(int argc,
 			ctx->instance->port = port;
 			ctx->instance->name = name;
 			add_instance(ctx->instance, 0);
+			ctx->data_flags |= DATA_FL_GUEST;
 			break;
 		}
 		case 'F':
@@ -6008,8 +6013,8 @@ static void parse_record_options(int argc,
 			if (!ctx->instance->clock)
 				die("Failed allocation");
 			ctx->instance->flags |= BUFFER_FL_HAS_CLOCK;
-			if (is_top_instance(ctx->instance))
-				guest_sync_set = true;
+			if (!ctx->clock && !is_guest(ctx->instance))
+				ctx->clock = ctx->instance->clock;
 			break;
 		case 'v':
 			negative = 1;
@@ -6253,8 +6258,7 @@ static void parse_record_options(int argc,
 			break;
 		case OPT_tsyncinterval:
 			cmd_check_die(ctx, CMD_set, *(argv+1), "--tsync-interval");
-			top_instance.tsync_loop_interval = atoi(optarg);
-			guest_sync_set = true;
+			ctx->tsync_loop_interval = atoi(optarg);
 			break;
 		case OPT_fork:
 			if (!IS_START(ctx))
@@ -6288,26 +6292,6 @@ static void parse_record_options(int argc,
 				add_argv(instance, "--date", true);
 		}
 	}
-	if (guest_sync_set) {
-	/* If -C is specified, prepend clock to all guest VM flags */
-		for_all_instances(instance) {
-			if (top_instance.clock) {
-				if (is_guest(instance) &&
-				    !(instance->flags & BUFFER_FL_HAS_CLOCK)) {
-					add_argv(instance,
-						 (char *)top_instance.clock,
-						 true);
-					add_argv(instance, "-C", true);
-					if (!instance->clock) {
-						instance->clock = strdup((char *)top_instance.clock);
-						if (!instance->clock)
-							die("Could not allocate instance clock");
-					}
-				}
-			}
-			instance->tsync_loop_interval = top_instance.tsync_loop_interval;
-		}
-	}
 
 	if (!ctx->filtered && ctx->instance->filter_mod)
 		add_func(&ctx->instance->filter_funcs,
@@ -6474,6 +6458,56 @@ static void get_tsc_offset(struct common_record_context *ctx)
 	ctx->tsc2nsec.offset = get_clock_now(NULL);
 }
 
+static void set_tsync_params(struct common_record_context *ctx)
+{
+	const char *clock = ctx->clock;
+	struct buffer_instance *instance;
+	int shift, mult;
+	bool force_tsc = false;
+
+	/*
+	 * If no clock is configured &&
+	 * KVM time sync protocol is available &&
+	 * tsc-x86 clock is supported &&
+	 * TSC to nsec multiplier and shift are available:
+	 * force using the x86-tsc clock for this host-guest tracing session
+	 * and store TSC to nsec multiplier and shift.
+	 */
+	if (!clock && tsync_proto_is_supported("kvm") &&
+	    clock_is_supported(NULL, TSC_CLOCK) &&
+	    !get_tsc_nsec(&shift, &mult) && mult) {
+		clock = TSC_CLOCK;
+		ctx->tsc2nsec.mult = mult;
+		ctx->tsc2nsec.shift = shift;
+		ctx->tsc2nsec.offset = get_clock_now(TSC_CLOCK);
+		force_tsc = true;
+	}
+
+	if (!clock && !ctx->tsync_loop_interval)
+		return;
+	for_all_instances(instance) {
+		if (clock && !(instance->flags & BUFFER_FL_HAS_CLOCK)) {
+			/* use the same clock in all tracing peers */
+			if (is_guest(instance)) {
+				if (!instance->clock) {
+					instance->clock = strdup(clock);
+					if (!instance->clock)
+						die("Can not allocate instance clock");
+				}
+				add_argv(instance, (char *)instance->clock, true);
+				add_argv(instance, "-C", true);
+				if (ctx->tsc2nsec.mult)
+					instance->flags |= BUFFER_FL_TSC2NSEC;
+			} else if (force_tsc && !instance->clock) {
+				instance->clock = strdup(clock);
+				if (!instance->clock)
+					die("Can not allocate instance clock");
+			}
+		}
+		instance->tsync_loop_interval = ctx->tsync_loop_interval;
+	}
+}
+
 /*
  * This function contains common code for the following commands:
  * record, start, stream, profile.
@@ -6503,6 +6537,9 @@ static void record_trace(int argc, char **argv,
 	if (!ctx->output)
 		ctx->output = DEFAULT_INPUT_FILE;
 
+	if (ctx->data_flags & DATA_FL_GUEST)
+		set_tsync_params(ctx);
+
 	make_instances();
 
 	/* Save the state of tracing_on before starting */
-- 
2.30.2


  parent reply index

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-25  6:40 [PATCH v4 00/23] TSC trace clock to nanosecond conversion Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 01/23] trace-cmd: Add initial perf interface in trace-cmd library Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 02/23] trace-cmd: Extend trace-cmd dump subcommand to display the clock Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 03/23] trace-cmd: Save only the selected clock in the trace.dat file Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 04/23] trace-cmd: Internal refactoring, move logic for local tep handler in its own function Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 05/23] trace-cmd: Add new local function to check if a trace clock is supported Tzvetomir Stoyanov (VMware)
2021-03-26 21:21   ` Steven Rostedt
2021-03-25  6:40 ` [PATCH v4 06/23] trace-cmd: Add new trace-cmd clock tsc2nsec Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 07/23] trace-cmd: Define a new option for tsc2nsec conversion Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 08/23] trace-cmd: Save information for tsc to nanoseconds conversion in trace file Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 09/23] trace-cmd: Read information for tsc to nanoseconds conversion from " Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 10/23] trace-cmd: Save tsc2nsec clock in trace.dat file Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 11/23] trace-cmd: Append new options into guest trace file at the end of the tracing session Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 12/23] trace-cmd: Remove unneeded multiply in events timestamp reading Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 13/23] trace-cmd: Perform all timestamp corrections in a single function Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 14/23] trace-cmd: Convert tsc timestamps to nanosecods when reading trace data from a file Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 15/23] trace-cmd: Set order and priorities when applying timestamp corrections Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 16/23] trace-cmd: Add a new flag to disable any " Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 17/23] trace-cmd: Change "--nodate" option to affect "--date" option only Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 18/23] trace-cmd: Add new parameter "--raw-ts" to "trace-cmd report" command Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 19/23] trace-cmd: Print times in TimeShift options as unsigned in trace-cmd dump Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` Tzvetomir Stoyanov (VMware) [this message]
2021-03-25  6:40 ` [PATCH v4 21/23] trace-cmd: Get current clock for host-guest tracing session Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 22/23] trace-cmd: Save the trace clocks in TRACECLOCK option Tzvetomir Stoyanov (VMware)
2021-03-25  6:40 ` [PATCH v4 23/23] trace-cmd: Read at least 8 bytes trace-id option Tzvetomir Stoyanov (VMware)
2021-03-26 21:18   ` Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210325064055.539554-21-tz.stoyanov@gmail.com \
    --to=tz.stoyanov@gmail.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Trace-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-trace-devel/0 linux-trace-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-trace-devel linux-trace-devel/ https://lore.kernel.org/linux-trace-devel \
		linux-trace-devel@vger.kernel.org
	public-inbox-index linux-trace-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-trace-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git