linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org,
	"Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH v6 19/27] kernel-shark: Add methods for time calibration
Date: Wed,  9 Dec 2020 15:41:55 +0200	[thread overview]
Message-ID: <20201209134203.428068-20-y.karadz@gmail.com> (raw)
In-Reply-To: <20201209134203.428068-1-y.karadz@gmail.com>

We add an infrastructure for correcting the timestamps of the entries.
This is needed in order to correlate Data streams that have been
recorded using non-synchronized clocks. The infrastructure can handle
an arbitrary timestamps correction formula, however for the moment we
only provide calibration that adds a constant offset.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 src/libkshark-tepdata.c | 13 +++++-
 src/libkshark.c         | 99 +++++++++++++++++++++++++++++++++++++++++
 src/libkshark.h         | 27 +++++++++++
 3 files changed, 138 insertions(+), 1 deletion(-)

diff --git a/src/libkshark-tepdata.c b/src/libkshark-tepdata.c
index 11bf441..0b23912 100644
--- a/src/libkshark-tepdata.c
+++ b/src/libkshark-tepdata.c
@@ -338,6 +338,9 @@ static ssize_t get_records(struct kshark_context *kshark_ctx,
 					entry = &temp_rec->entry;
 					missed_events_action(stream, rec, entry);
 
+					/* Apply time calibration. */
+					kshark_postprocess_entry(stream, rec, entry);
+
 					entry->stream_id = stream->stream_id;
 
 					temp_next = &temp_rec->next;
@@ -360,6 +363,12 @@ static ssize_t get_records(struct kshark_context *kshark_ctx,
 
 				entry->stream_id = stream->stream_id;
 
+				/*
+				 * Post-process the content of the entry. This includes
+				 * time calibration and event-specific plugin actions.
+				 */
+				kshark_postprocess_entry(stream, rec, entry);
+
 				pid = entry->pid;
 
 				/* Apply Id filtering. */
@@ -527,8 +536,10 @@ static ssize_t tepdata_load_matrix(struct kshark_data_stream *stream,
 			if (cpu_array)
 				(*cpu_array)[count] = e->cpu;
 
-			if (ts_array)
+			if (ts_array) {
+				kshark_calib_entry(stream, e);
 				(*ts_array)[count] = e->ts;
+			}
 
 			if (pid_array)
 				(*pid_array)[count] = e->pid;
diff --git a/src/libkshark.c b/src/libkshark.c
index cc8bd93..315c24f 100644
--- a/src/libkshark.c
+++ b/src/libkshark.c
@@ -131,6 +131,7 @@ static void kshark_stream_free(struct kshark_data_stream *stream)
 
 	kshark_hash_id_free(stream->tasks);
 
+	free(stream->calib_array);
 	free(stream->file);
 	free(stream->name);
 	free(stream->interface);
@@ -1367,6 +1368,37 @@ void kshark_plugin_actions(struct kshark_data_stream *stream,
 	}
 }
 
+/**
+ * @brief Time calibration of the timestamp of the entry.
+ *
+ * @param stream: Input location for a Trace data stream pointer.
+ * @param entry: Output location for entry.
+ */
+void kshark_calib_entry(struct kshark_data_stream *stream,
+			struct kshark_entry *entry)
+{
+	if (stream->calib && stream->calib_array) {
+		/* Calibrate the timestamp of the entry. */
+		stream->calib(&entry->ts, stream->calib_array);
+	}
+}
+
+/**
+ * @brief Post-process the content of the entry. This includes time calibration
+ *	  and all registered event-specific plugin actions.
+ *
+ * @param stream: Input location for a Trace data stream pointer.
+ * @param record: Input location for the trace record.
+ * @param entry: Output location for entry.
+ */
+void kshark_postprocess_entry(struct kshark_data_stream *stream,
+			      void *record, struct kshark_entry *entry)
+{
+	kshark_calib_entry(stream, entry);
+
+	kshark_plugin_actions(stream, record, entry);
+}
+
 static inline void free_ptr(void *ptr)
 {
 	if (ptr)
@@ -1764,6 +1796,73 @@ kshark_get_entry_back(const struct kshark_entry_request *req,
 	return get_entry(req, data, index, req->first, end, -1);
 }
 
+static int compare_time(const void* a, const void* b)
+{
+	const struct kshark_entry *entry_a, *entry_b;
+
+	entry_a = *(const struct kshark_entry **) a;
+	entry_b = *(const struct kshark_entry **) b;
+
+	if (entry_a->ts > entry_b->ts)
+		return 1;
+
+	if (entry_a->ts < entry_b->ts)
+		return -1;
+
+	return 0;
+}
+
+static void kshark_data_qsort(struct kshark_entry **entries, size_t size)
+{
+	qsort(entries, size, sizeof(struct kshark_entry *), compare_time);
+}
+
+/**
+ * Add constant offset to the timestamp of the entry. To be used by the sream
+ * object as a System clock calibration callback function.
+ */
+void kshark_offset_calib(int64_t *ts, int64_t *argv)
+{
+	*ts += argv[0];
+}
+
+/**
+ * @brief Apply constant offset to the timestamps of all entries from a given
+ *	  Data stream.
+ *
+ * @param kshark_ctx: Input location for the session context pointer.
+ * @param entries: Input location for the trace data.
+ * @param size: The size of the trace data.
+ * @param sd: Data stream identifier.
+ * @param offset: The constant offset to be added (in nanosecond).
+ */
+void kshark_set_clock_offset(struct kshark_context *kshark_ctx,
+			     struct kshark_entry **entries, size_t size,
+			     int sd, int64_t offset)
+{
+	struct kshark_data_stream *stream;
+	int64_t correction;
+
+	stream = kshark_get_data_stream(kshark_ctx, sd);
+	if (!stream)
+		return;
+
+	if (!stream->calib_array) {
+		stream->calib = kshark_offset_calib;
+		stream->calib_array = calloc(1, sizeof(*stream->calib_array));
+		stream->calib_array_size = 1;
+	}
+
+	correction = offset - stream->calib_array[0];
+	stream->calib_array[0] = offset;
+
+	for (size_t i = 0; i < size; ++i)
+		if (entries[i]->stream_id == sd)
+			entries[i]->ts += correction;
+
+	kshark_data_qsort(entries, size);
+}
+
 static int first_in_time_entry(struct kshark_entry_data_set *buffer, int n_buffers, size_t *count)
 {
 	int64_t t_min = INT64_MAX;
diff --git a/src/libkshark.h b/src/libkshark.h
index edf3dcf..dce3dd2 100644
--- a/src/libkshark.h
+++ b/src/libkshark.h
@@ -129,6 +129,12 @@ static const char top_name[] = { 0x1b, 0x00 }; // Non printable character
  */
 #define KS_UNNAMED	(char *) &top_name
 
+/**
+ * Timestamp calibration function type. To be user for system clock
+ * calibration.
+ */
+typedef void (*time_calib_func) (int64_t *, int64_t *);
+
 struct kshark_data_stream;
 
 /** A function type to be used by the method interface of the data stream. */
@@ -327,6 +333,15 @@ struct kshark_data_stream {
 	/** The number of plugins registered for this stream.*/
 	int			n_plugins;
 
+	/** System clock calibration function. */
+	time_calib_func		calib;
+
+	/** An array of time calibration constants. */
+	int64_t			*calib_array;
+
+	/** The size of the array of time calibration constants. */
+	size_t			calib_array_size;
+
 	/** List of Plugin's Event handlers. */
 	struct kshark_event_proc_handler	*event_handlers;
 
@@ -590,6 +605,12 @@ void kshark_clear_all_filters(struct kshark_context *kshark_ctx,
 void kshark_plugin_actions(struct kshark_data_stream *stream,
 			   void *record, struct kshark_entry *entry);
 
+void kshark_calib_entry(struct kshark_data_stream *stream,
+			struct kshark_entry *entry);
+
+void kshark_postprocess_entry(struct kshark_data_stream *stream,
+			      void *record, struct kshark_entry *entry);
+
 /** Search failed identifiers. */
 enum kshark_search_failed {
 	/** All entries have greater timestamps. */
@@ -980,6 +1001,12 @@ struct kshark_config_doc *kshark_open_config_file(const char *file_name,
 
 struct kshark_config_doc *kshark_json_to_conf(struct json_object *jobj);
 
+void kshark_offset_calib(int64_t *ts, int64_t *atgv);
+
+void kshark_set_clock_offset(struct kshark_context *kshark_ctx,
+			     struct kshark_entry **entries, size_t size,
+			     int sd, int64_t offset);
+
 /** Structure representing a data set made of KernelShark entries. */
 struct kshark_entry_data_set {
 	/** Array of entries pointers. */
-- 
2.25.1


  parent reply	other threads:[~2020-12-09 13:43 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-09 13:41 [PATCH v6 00/27] Start KernelShark v2 transformation Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 01/27] kernel-shark: Use only signed types in kshark_entry Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 02/27] kernel-shark: Add stream_id to kshark_entry Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 03/27] kernel-shark: Introduce libkshark-hash Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 04/27] kernel-shark: Introduce Data streams Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 05/27] kernel-shark: Rename static methods in libkshark Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 06/27] kernel-shark: Add basic methods for Data streams Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 07/27] kernel-shark: Housekeeping before implementing stream interface Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 08/27] kernel-shark: Add stream interface for trace-cmd data Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 09/27] kernel-shark: Start introducing KernelShark 2.0 Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 10/27] kernel-shark: Start using data streams Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 11/27] kernel-shark: Remove dead code Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 12/27] kernel-shark: Redesign the plugin interface Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 13/27] kernel-shark: Complete the stream integration Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 14/27] kernel-shark: Provide merging of multiple data streams Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 15/27] kernel-shark: Integrate the stream definitions with data model Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 16/27] kernel-shark: Use only signed types for model defs Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 17/27] kernel-shark: Add ksmodel_get_bin() Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 18/27] kernel-shark: Protect ksmodel_set_in_range_bining() Yordan Karadzhov (VMware)
2020-12-09 13:41 ` Yordan Karadzhov (VMware) [this message]
2020-12-09 13:41 ` [PATCH v6 20/27] kernel-shark: Integrate streams with libkshark-configio Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 21/27] kernel-shark: Add support for drawing text Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 22/27] kernel-shark: Make GLUT optional dependency Yordan Karadzhov (VMware)
2020-12-09 13:41 ` [PATCH v6 23/27] kernel-shark: Add ksplot_draw_polyline() Yordan Karadzhov (VMware)
2020-12-09 13:42 ` [PATCH v6 24/27] kernel-shark: Optimize ksplot_draw_polygon() Yordan Karadzhov (VMware)
2020-12-09 13:42 ` [PATCH v6 25/27] kernel-shark: Do not use the ARRAY_SIZE macro Yordan Karadzhov (VMware)
2020-12-09 13:42 ` [PATCH v6 26/27] kernel-shark: Add basic infrastructure for testing Yordan Karadzhov (VMware)
2020-12-09 13:42 ` [PATCH v6 27/27] kernel-shark: Add "github Actions" workflow Yordan Karadzhov (VMware)
2020-12-10  2:38 ` [PATCH v6 00/27] Start KernelShark v2 transformation Steven Rostedt
2020-12-10  8:48   ` David Runge
2020-12-10 14:38     ` Yordan Karadzhov (VMware)
2020-12-10 14:42     ` 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=20201209134203.428068-20-y.karadz@gmail.com \
    --to=y.karadz@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).