On 16.04.20 г. 19:00 ч., Tzvetomir Stoyanov (VMware) wrote:
From: Tzvetomir (VMware) Stoyanov <tz.stoyanov@xxxxxxxxx> 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_pair_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@xxxxxxxxx> --- src/libkshark-tepdata.c | 59 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/libkshark-tepdata.c b/src/libkshark-tepdata.c index 8678e12..f280e57 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)
This function can be defined static.
+{ + struct tracecmd_input *peer_handle = NULL; + struct kshark_data_stream *peer_stream; + unsigned long long trace_id; + int *streamIds = NULL;
Nit: please stick to "snake_case" in the C code and "camelCase in the C++ code.
No need to send new version. I am applying patchs 1-3 from this patch-set. Thanks a lot! Yordan
+ 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_pair_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;