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
Subject: [PATCH v2 1/2] trace-cmd: Add new APIs to pair and unpair tracing peers
Date: Mon, 13 Apr 2020 11:23:33 +0300	[thread overview]
Message-ID: <20200413082334.164158-2-tz.stoyanov@gmail.com> (raw)
In-Reply-To: <20200413082334.164158-1-tz.stoyanov@gmail.com>

When tracing host and one or more guest machines at the same time,
guest and host are tracing peers. There is information in both trace
files, related to host PID to guest vCPU mapping, timestamp synchronization
and other. This information is useful when opening files at the same time and
merging the events. When the host is set as a tracing peer to the guest, then
the timestamps of guest's events are recalculated to match the host event's time
Two new APIs are intrduced to control pairing of tracing peers:

int tracecmd_pair_peer(struct tracecmd_input *handle,
		       struct tracecmd_input *peer);
int tracecmd_unpair_peer(struct tracecmd_input *handle);

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 include/trace-cmd/trace-cmd.h |  3 ++
 lib/trace-cmd/trace-input.c   | 95 +++++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 4 deletions(-)

diff --git a/include/trace-cmd/trace-cmd.h b/include/trace-cmd/trace-cmd.h
index e22aa251..76fcffae 100644
--- a/include/trace-cmd/trace-cmd.h
+++ b/include/trace-cmd/trace-cmd.h
@@ -145,6 +145,9 @@ struct tracecmd_input *tracecmd_alloc_fd(int fd);
 struct tracecmd_input *tracecmd_open(const char *file);
 struct tracecmd_input *tracecmd_open_head(const char *file);
 struct tracecmd_input *tracecmd_open_fd(int fd);
+int tracecmd_pair_peer(struct tracecmd_input *handle,
+		       struct tracecmd_input *peer);
+int tracecmd_unpair_peer(struct tracecmd_input *handle);
 void tracecmd_ref(struct tracecmd_input *handle);
 void tracecmd_close(struct tracecmd_input *handle);
 int tracecmd_read_headers(struct tracecmd_input *handle);
diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c
index efc8d4bd..cd909613 100644
--- a/lib/trace-cmd/trace-input.c
+++ b/lib/trace-cmd/trace-input.c
@@ -91,8 +91,9 @@ struct guest_trace_info {
 };
 
 struct host_trace_info {
-	unsigned long long	trace_id;
+	unsigned long long	peer_trace_id;
 	bool			sync_enable;
+	struct tracecmd_input	*peer_data;
 	int			ts_samples_count;
 	struct ts_offset_sample	*ts_samples;
 };
@@ -2194,10 +2195,38 @@ static void tsync_offset_load(struct tracecmd_input *handle, char *buf)
 		host->sync_enable = true;
 }
 
+static void tsync_check_enable(struct tracecmd_input *handle)
+{
+	struct host_trace_info	*host = &handle->host;
+	struct guest_trace_info *guest;
+
+	host->sync_enable = false;
+
+	if (!host->peer_data || !host->peer_data->guest ||
+	    !host->ts_samples_count || !host->ts_samples)
+		return;
+	if (host->peer_trace_id != host->peer_data->trace_id)
+		return;
+	guest = host->peer_data->guest;
+	while (guest) {
+		if (guest->trace_id == handle->trace_id)
+			break;
+		guest = guest->next;
+	}
+	if (!guest)
+		return;
+
+	host->sync_enable = true;
+}
+
 static void trace_tsync_offset_free(struct host_trace_info *host)
 {
 	free(host->ts_samples);
 	host->ts_samples = NULL;
+	if (host->peer_data) {
+		tracecmd_close(host->peer_data);
+		host->peer_data = NULL;
+	}
 }
 
 static int trace_pid_map_cmp(const void *a, const void *b)
@@ -2510,8 +2539,8 @@ static int handle_options(struct tracecmd_input *handle)
 			 */
 			if (size < 12 || handle->flags & TRACECMD_FL_IGNORE_DATE)
 				break;
-			handle->host.trace_id = tep_read_number(handle->pevent,
-								buf, 8);
+			handle->host.peer_trace_id = tep_read_number(handle->pevent,
+								     buf, 8);
 			handle->host.ts_samples_count = tep_read_number(handle->pevent,
 									buf + 8, 4);
 			samples_size = (8 * handle->host.ts_samples_count);
@@ -3203,6 +3232,64 @@ fail:
 	return NULL;
 }
 
+/**
+ * tracecmd_unpair_peer - Link a tracing peer to this handle
+ * @handle: input handle for the trace.dat file
+ * @peer: input handle for the tracing peer
+ *
+ * When tracing host and one or more guest machines at the same time,
+ * guest and host are tracing peers. There is information in both trace
+ * files, related to host PID to guest vCPU mapping, timestamp synchronization
+ * and other. This information is useful when opening files at the same time and
+ * merging the events. When the host is set as a tracing peer to the guest, then
+ * the timestamps of guest's events are recalculated to match the host event's time
+ *
+ * Returns 1, if a peer is already paired, -1 in case of an error or 0 otherwise
+ */
+int tracecmd_unpair_peer(struct tracecmd_input *handle)
+{
+	if (!handle)
+		return -1;
+
+	if (handle->host.peer_data) {
+		tracecmd_close(handle->host.peer_data);
+		handle->host.peer_data = NULL;
+		tsync_check_enable(handle);
+	}
+
+	return 0;
+}
+
+/**
+ * tracecmd_pair_peer - Link a tracing peer to this handle
+ * @handle: input handle for the trace.dat file
+ * @peer: input handle for the tracing peer
+ *
+ * When tracing host and one or more guest machines at the same time,
+ * guest and host are tracing peers. There is information in both trace
+ * files, related to host PID to guest vCPU mapping, timestamp synchronization
+ * and other. This information is useful when opening files at the same time and
+ * merging the events. When the host is set as a tracing peer to the guest, then
+ * the timestamps of guest's events are recalculated to match the host event's time
+ *
+ * Returns 1, if a peer is already paired, -1 in case of an error or 0 otherwise
+ */
+int tracecmd_pair_peer(struct tracecmd_input *handle,
+		       struct tracecmd_input *peer)
+{
+	if (!handle)
+		return -1;
+
+	if (handle->host.peer_data)
+		return 1;
+
+	handle->host.peer_data = peer;
+	tracecmd_ref(peer);
+	tsync_check_enable(handle);
+
+	return 0;
+}
+
 /**
  * tracecmd_ref - add a reference to the handle
  * @handle: input handle for the trace.dat file
@@ -3785,7 +3872,7 @@ int tracecmd_get_guest_cpumap(struct tracecmd_input *handle,
  */
 unsigned long long tracecmd_get_tsync_peer(struct tracecmd_input *handle)
 {
-	return handle->host.trace_id;
+	return handle->host.peer_trace_id;
 }
 
 /**
-- 
2.25.1


  reply	other threads:[~2020-04-13  8:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-13  8:23 [PATCH v2 0/2] Useful APIs for merging tracing files Tzvetomir Stoyanov (VMware)
2020-04-13  8:23 ` Tzvetomir Stoyanov (VMware) [this message]
2020-04-13  8:23 ` [PATCH v2 2/2] trace-cmd: Validate input parameters of tracecmd_get_guest_cpumap() API Tzvetomir Stoyanov (VMware)

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=20200413082334.164158-2-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
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).