linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Tzvetomir Stoyanov (VMware)" <tz.stoyanov@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org, joelaf@google.com
Subject: [PATCH] trace-cmd: Add support for non-qemu VMs
Date: Mon, 26 Apr 2021 13:35:28 +0300	[thread overview]
Message-ID: <20210426103528.634418-1-tz.stoyanov@gmail.com> (raw)

Current host-guest tracing implementation assumes that qemu runs the VMs
and uses qemu specific logic to collect various information:
 - PID of the process, running the guest VM. In case of KVM, this PID
   is used  to get the KVM guest TSC clock parameters, needed for better
   host and guest trace timestamps synchronization.
 - PIDs of each thread, running a guest virtual CPU. This is used for
   better trace visualisation. It helps to map the host task to a vCPU
   and to visualise them together.
In case qemu is not used to run the VMs, host-guest tracing fails. As
that information is not mandatory, we can easily support non-qemu VMs.
Changes, proposed by the patch:
 - if PID of the process, running the guest VM, is not available - fail
   back to a PTP-like algorithm for trace timestamps synchronization.
 - if PIDs of the threads, running guest virtual CPUs, are not available
   write -1 in the trace file metadata.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 tracecmd/include/trace-local.h |  4 +--
 tracecmd/trace-record.c        | 36 ++++++++++++-------------
 tracecmd/trace-vm.c            | 48 ++++++++++++++++++++++++++++++++--
 3 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/tracecmd/include/trace-local.h b/tracecmd/include/trace-local.h
index 1218de12..04d8f32c 100644
--- a/tracecmd/include/trace-local.h
+++ b/tracecmd/include/trace-local.h
@@ -301,8 +301,8 @@ struct trace_guest {
 	int cpu_max;
 	int *cpu_pid;
 };
-struct trace_guest *get_guest_by_cid(unsigned int guest_cid);
-struct trace_guest *get_guest_by_name(char *name);
+struct trace_guest *trace_get_guest(unsigned int cid, const char *name);
+bool trace_have_guests_pid(void);
 void read_qemu_guests(void);
 int get_guest_pid(unsigned int guest_cid);
 int get_guest_vcpu_pid(unsigned int guest_cid, unsigned int guest_vcpu);
diff --git a/tracecmd/trace-record.c b/tracecmd/trace-record.c
index fd03a605..4636475f 100644
--- a/tracecmd/trace-record.c
+++ b/tracecmd/trace-record.c
@@ -3251,10 +3251,7 @@ static char *parse_guest_name(char *gname, int *cid, int *port)
 		*cid = atoi(gname);
 
 	read_qemu_guests();
-	if (*cid > 0)
-		guest = get_guest_by_cid(*cid);
-	else
-		guest = get_guest_by_name(gname);
+	guest = trace_get_guest(*cid, gname);
 	if (guest) {
 		*cid = guest->cid;
 		return guest->name;
@@ -3723,14 +3720,14 @@ static int host_tsync(struct common_record_context *ctx,
 
 	if (!proto)
 		return -1;
-	guest = get_guest_by_cid(instance->cid);
+	guest = trace_get_guest(instance->cid, NULL);
 	if (guest == NULL)
 		return -1;
 
 	instance->tsync = tracecmd_tsync_with_guest(top_instance.trace_id,
 						    instance->tsync_loop_interval,
 						    instance->cid, tsync_port,
-						    guest->pid, guest->cpu_max,
+						    guest->pid, instance->cpu_count,
 						    proto, ctx->clock);
 	if (!instance->tsync)
 		return -1;
@@ -3792,6 +3789,7 @@ static void connect_to_agent(struct common_record_context *ctx,
 			printf("Negotiated %s time sync protocol with guest %s\n",
 				tsync_protos_reply,
 				instance->name);
+			instance->cpu_count = nr_cpus;
 			host_tsync(ctx, instance, tsync_port, tsync_protos_reply);
 		} else
 			warning("Failed to negotiate timestamps synchronization with the guest");
@@ -3975,21 +3973,19 @@ static void append_buffer(struct tracecmd_output *handle,
 static void
 add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance)
 {
-	struct trace_guest *guest = get_guest_by_cid(instance->cid);
+	struct trace_guest *guest = trace_get_guest(instance->cid, NULL);
 	char *buf, *p;
 	int size;
+	int pid;
 	int i;
 
 	if (!guest)
 		return;
-	for (i = 0; i < guest->cpu_max; i++)
-		if (!guest->cpu_pid[i])
-			break;
 
 	size = strlen(guest->name) + 1;
-	size +=  sizeof(long long);	/* trace_id */
-	size +=  sizeof(int);		/* cpu count */
-	size += i * 2 * sizeof(int);	/* cpu,pid pair */
+	size += sizeof(long long);	/* trace_id */
+	size += sizeof(int);		/* cpu count */
+	size += instance->cpu_count * 2 * sizeof(int);	/* cpu,pid pair */
 
 	buf = calloc(1, size);
 	if (!buf)
@@ -4001,14 +3997,16 @@ add_guest_info(struct tracecmd_output *handle, struct buffer_instance *instance)
 	memcpy(p, &instance->trace_id, sizeof(long long));
 	p += sizeof(long long);
 
-	memcpy(p, &i, sizeof(int));
+	memcpy(p, &instance->cpu_count, sizeof(int));
 	p += sizeof(int);
-	for (i = 0; i < guest->cpu_max; i++) {
-		if (!guest->cpu_pid[i])
-			break;
+	for (i = 0; i < instance->cpu_count; i++) {
+		if (i < guest->cpu_max)
+			pid = guest->cpu_pid[i];
+		else
+			pid = -1;
 		memcpy(p, &i, sizeof(int));
 		p += sizeof(int);
-		memcpy(p, &guest->cpu_pid[i], sizeof(int));
+		memcpy(p, &pid, sizeof(int));
 		p += sizeof(int);
 	}
 
@@ -6553,12 +6551,14 @@ static void set_tsync_params(struct common_record_context *ctx)
 	/*
 	 * If no clock is configured &&
 	 * KVM time sync protocol is available &&
+	 * there is information of each guest PID process &&
 	 * 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 (tsync_proto_is_supported("kvm") &&
+		    trace_have_guests_pid() &&
 		    clock_is_supported(NULL, TSC_CLOCK) &&
 		    !get_tsc_nsec(&shift, &mult) && mult) {
 			clock = strdup(TSC_CLOCK);
diff --git a/tracecmd/trace-vm.c b/tracecmd/trace-vm.c
index c8924ece..c0333b67 100644
--- a/tracecmd/trace-vm.c
+++ b/tracecmd/trace-vm.c
@@ -35,7 +35,7 @@ static int set_vcpu_pid_mapping(struct trace_guest *guest, int cpu, int pid)
 	return 0;
 }
 
-struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
+static struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
 {
 	int i;
 
@@ -48,7 +48,7 @@ struct trace_guest *get_guest_by_cid(unsigned int guest_cid)
 	return NULL;
 }
 
-struct trace_guest *get_guest_by_name(char *name)
+static struct trace_guest *get_guest_by_name(const char *name)
 {
 	int i;
 
@@ -61,6 +61,50 @@ struct trace_guest *get_guest_by_name(char *name)
 	return NULL;
 }
 
+bool trace_have_guests_pid(void)
+{
+	for (int i = 0; i < guests_len; i++) {
+		if (guests[i].pid < 0)
+			return false;
+	}
+
+	return true;
+}
+
+static struct trace_guest *add_guest(unsigned int cid, const char *name)
+{
+	guests = realloc(guests, (guests_len + 1) * sizeof(*guests));
+	if (!guests)
+		die("allocating new guest");
+	memset(&guests[guests_len], 0, sizeof(struct trace_guest));
+	guests[guests_len].name = strdup(name);
+	if (!guests[guests_len].name)
+		die("allocating guest name");
+	guests[guests_len].cid = cid;
+	guests[guests_len].pid = -1;
+	guests_len++;
+
+	return &guests[guests_len - 1];
+}
+
+struct trace_guest *trace_get_guest(unsigned int cid, const char *name)
+{
+	struct trace_guest *guest = NULL;
+
+	if (name) {
+		guest = get_guest_by_name(name);
+		if (guest)
+			return guest;
+	}
+
+	if (cid > 0) {
+		guest = get_guest_by_cid(cid);
+		if (!guest && name)
+			guest = add_guest(cid, name);
+	}
+	return guest;
+}
+
 static char *get_qemu_guest_name(char *arg)
 {
 	char *tok, *end = arg;
-- 
2.30.2


             reply	other threads:[~2021-04-26 10:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-26 10:35 Tzvetomir Stoyanov (VMware) [this message]
2021-04-26 18:44 ` [PATCH] trace-cmd: Add support for non-qemu VMs Joel Fernandes
2021-04-27  1:19   ` Joel Fernandes
2021-04-27  8:27   ` Yordan Karadzhov
2021-04-27 15:34     ` Joel Fernandes
2021-05-04 21:23 ` 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=20210426103528.634418-1-tz.stoyanov@gmail.com \
    --to=tz.stoyanov@gmail.com \
    --cc=joelaf@google.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).