diff mbox series

[v2] kernel-shark-2.alpha: Use new tracecmd APIs to open guest tracing file

Message ID 20200409142511.82228-5-tz.stoyanov@gmail.com (mailing list archive)
State Superseded
Headers show
Series [v2] kernel-shark-2.alpha: Use new tracecmd APIs to open guest tracing file | expand

Commit Message

Tzvetomir Stoyanov (VMware) April 9, 2020, 2:25 p.m. UTC
From: Tzvetomir (VMware)  Stoyanov <tz.stoyanov@gmail.com>

The new tracecmd API tracecmd_open_head() allows opening a trace.dat
file on stages. First, only the headers from the file are read and parsed,
without reading the tracing data.
The tracecmd_set_merge_peer() API is used to bind a tracing peer to
this file, before parsing the trace data. This affects events timestamps
correction when the tracing data is loaded.
The tracecmd_get_guest_cpumap() API is used to find dependencies between
all files and find a possible tracing peers.

This change depends on these trace-cmd patch sets:
  "Useful APIs for merging tracing files"
https://patchwork.kernel.org/project/linux-trace-devel/list/?series=268745
  "Split reading the trace.dat options from trace data"
https://patchwork.kernel.org/project/linux-trace-devel/list/?series=268743

Signed-off-by: Tzvetomir (VMware)  Stoyanov <tz.stoyanov@gmail.com>
---
 src/libkshark-tepdata.c | 59 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/libkshark-tepdata.c b/src/libkshark-tepdata.c
index 8678e12..c68b52a 100644
--- a/src/libkshark-tepdata.c
+++ b/src/libkshark-tepdata.c
@@ -985,6 +985,45 @@  const char *tep_plugin_names[] = {"sched_events",
 
 #define LINUX_IDLE_TASK_PID	0
 
+/** Find a host stream from the same tracing session, that has guest information */
+struct tracecmd_input *kshark_tep_find_merge_peer(struct kshark_context *kshark_ctx,
+						  struct tracecmd_input *handle)
+{
+	struct tracecmd_input *peer_handle = NULL;
+	struct kshark_data_stream *peer_stream;
+	unsigned long long trace_id;
+	int *streamIds = NULL;
+	int ret;
+	int i;
+
+	trace_id = tracecmd_get_traceid(handle);
+	if (!trace_id)
+		goto out;
+
+	streamIds = kshark_all_streams(kshark_ctx);
+	if (!streamIds)
+		goto out;
+	for (i = 0; i < kshark_ctx->n_streams; i++) {
+		peer_stream = kshark_get_data_stream(kshark_ctx, streamIds[i]);
+		if (!peer_stream || peer_stream->format != KS_TEP_DATA)
+			continue;
+		peer_handle = kshark_get_tep_input(peer_stream);
+		if (!peer_handle)
+			continue;
+		ret = tracecmd_get_guest_cpumap(peer_handle, trace_id,
+						NULL, NULL, NULL);
+		if (!ret)
+			break;
+	}
+
+	if (i == kshark_ctx->n_streams)
+		peer_handle = NULL;
+
+out:
+	free(streamIds);
+	return peer_handle;
+}
+
 /** Initialize the FTRACE data input (from file). */
 int kshark_tep_init_input(struct kshark_data_stream *stream,
 			  const char *file)
@@ -992,8 +1031,10 @@  int kshark_tep_init_input(struct kshark_data_stream *stream,
 	struct kshark_context *kshark_ctx = NULL;
 	struct tepdata_handle *tep_handle;
 	struct kshark_plugin_list *plugin;
+	struct tracecmd_input *merge_peer;
 	struct tep_event *event;
 	int i, n_tep_plugins;
+	int ret;
 
 	if (!kshark_instance(&kshark_ctx) || !init_thread_seq())
 		return -EEXIST;
@@ -1009,13 +1050,29 @@  int kshark_tep_init_input(struct kshark_data_stream *stream,
 	if (!tep_handle)
 		return -EFAULT;
 
-	tep_handle->input = tracecmd_open(file);
+	/** Open the tracing file, parse headers and create trace input context */
+	tep_handle->input = tracecmd_open_head(file);
 	if (!tep_handle->input) {
 		free(tep_handle);
 		stream->interface.handle = NULL;
 		return -EEXIST;
 	}
 
+	/** Find a merge peer from the same tracing session */
+	merge_peer = kshark_tep_find_merge_peer(kshark_ctx, tep_handle->input);
+	if (merge_peer)
+		tracecmd_set_merge_peer(tep_handle->input, merge_peer);
+
+	/** Read the racing data from the file */
+	ret = tracecmd_init_data(tep_handle->input);
+
+	if (ret < 0) {
+		tracecmd_close(tep_handle->input);
+		free(tep_handle);
+		stream->interface.handle = NULL;
+		return -EEXIST;
+	}
+
 	tep_handle->tep = tracecmd_get_pevent(tep_handle->input);
 
 	tep_handle->sched_switch_event_id = -EINVAL;