mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: rostedt@goodmis.org
Cc: jan.kiszka@siemens.com, linux-kernel@vger.kernel.org,
	"Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH v2 4/4] kernelshark: Adding a GUI plugin for xenomai events
Date: Fri, 10 Nov 2017 14:29:15 +0200	[thread overview]
Message-ID: <20171110122915.24929-4-y.karadz@gmail.com> (raw)
In-Reply-To: <20171110122915.24929-1-y.karadz@gmail.com>

A plugin for processing xenomai events "cobalt_switch_context"
and "cobalt_thread_resume" is added.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 Makefile             |   1 +
 kshark-plugin.h      |  10 ++
 plugin_xenomai_gui.c | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 311 insertions(+)
 create mode 100644 plugin_xenomai_gui.c

diff --git a/Makefile b/Makefile
index 992e6b0..e4d280b 100644
--- a/Makefile
+++ b/Makefile
@@ -384,6 +384,7 @@ PLUGIN_OBJS += plugin_tlb.o
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
 GUI_PLUGIN_OBJS =
+GUI_PLUGIN_OBJS += plugin_xenomai_gui.o
 
 GUI_PLUGINS := $(GUI_PLUGIN_OBJS:.o=.so)
 
diff --git a/kshark-plugin.h b/kshark-plugin.h
index 42fb40c..1166781 100644
--- a/kshark-plugin.h
+++ b/kshark-plugin.h
@@ -53,6 +53,16 @@ enum gui_plugin_actions {
 	KSHARK_PLUGIN_GET_COMMAND,
 };
 
+enum gui_plugin_ctx_updates {
+	KSHARK_PLUGIN_UPDATE_SWITCH_EVENT	= (1 << 0),
+	KSHARK_PLUGIN_UPDATE_WAKEUP_EVENT	= (1 << 1),
+	KSHARK_PLUGIN_UPDATE_WAKEUP_PID		= (1 << 2),
+	KSHARK_PLUGIN_UPDATE_SWITCH_PID		= (1 << 3),
+	KSHARK_PLUGIN_UPDATE_PREV_STATE		= (1 << 4),
+	KSHARK_PLUGIN_UPDATE_NEXT_NAME		= (1 << 5),
+	KSHARK_PLUGIN_UPDATE_ALL		= INT_MAX
+};
+
 enum gui_event_types {
 	KSHARK_PLUGIN_SWITCH_EVENT,
 	KSHARK_PLUGIN_WAKEUP_EVENT,
diff --git a/plugin_xenomai_gui.c b/plugin_xenomai_gui.c
new file mode 100644
index 0000000..c786cc8
--- /dev/null
+++ b/plugin_xenomai_gui.c
@@ -0,0 +1,300 @@
+/*
+ *  Copyright (C) 2017 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License (not later!)
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "event-parse.h"
+#include "kernel-shark.h"
+#include "kshark-plugin.h"
+
+struct xenomai_context {
+	struct pevent 		*pevent;
+
+	struct event_format	*cobalt_switch_event;
+	struct format_field     *cobalt_switch_next_pid_field;
+	struct format_field     *cobalt_switch_prev_state_field;
+	struct format_field     *cobalt_switch_next_name_field;
+
+	struct event_format	*cobalt_wakeup_event;
+	struct format_field	*cobalt_wakeup_pid_field;
+};
+
+struct xenomai_context   *xenomai_context_handler = NULL;
+struct gui_event_handler *switch_handler = NULL;
+struct gui_event_handler *wakeup_handler = NULL;
+
+#define COBALT_PREV_STATE_BIT 		(1 << 3)
+#define COBALT_COMM_OFFSET_MASK 	0xFFFF
+
+static gboolean xenomai_update_context(struct pevent *pevent, int task_id)
+{
+	struct event_format *event;
+	struct xenomai_context *ctx = xenomai_context_handler;
+
+	if (!ctx)
+		return FALSE;
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_SWITCH_EVENT) {
+		event = pevent_find_event_by_name(pevent,
+						  "cobalt_core",
+						  "cobalt_switch_context");
+		if (!event)
+			return FALSE;
+
+		ctx->cobalt_switch_event = event;
+	}
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_WAKEUP_EVENT) {
+		event = pevent_find_event_by_name(pevent,
+						  "cobalt_core",
+						  "cobalt_thread_resume");
+		if (!event)
+			return FALSE;
+
+		ctx->cobalt_wakeup_event = event;
+	}
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_SWITCH_PID) {
+		ctx->cobalt_switch_next_pid_field =
+			pevent_find_field(ctx->cobalt_switch_event, "next_pid");
+	}
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_PREV_STATE) {
+		ctx->cobalt_switch_prev_state_field =
+			pevent_find_field(ctx->cobalt_switch_event, "prev_state");
+	}
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_NEXT_NAME) {
+		ctx->cobalt_switch_next_name_field =
+			pevent_find_field(ctx->cobalt_switch_event, "next_name");
+	}
+
+	if (task_id & KSHARK_PLUGIN_UPDATE_WAKEUP_PID) {
+		ctx->cobalt_wakeup_pid_field =
+			pevent_find_field(ctx->cobalt_wakeup_event, "pid");
+	}
+
+	return TRUE;
+}
+
+static void xenomai_context_new(struct shark_info *info, struct trace_view_store *store)
+{
+	if (!xenomai_context_handler) {
+		xenomai_context_handler =
+		(struct xenomai_context*) malloc(sizeof(struct xenomai_context));
+	}
+
+	xenomai_context_handler->pevent = tracecmd_get_pevent(info->handle);
+
+	int status = xenomai_update_context(xenomai_context_handler->pevent,
+					    KSHARK_PLUGIN_UPDATE_ALL);
+	if (status == FALSE) {
+		free(xenomai_context_handler);
+		xenomai_context_handler = NULL;
+	}
+}
+
+static int cobalt_get_next_pid(struct xenomai_context *ctx,
+			       struct pevent_record *record,
+			       int *pid)
+{
+	long long unsigned int val;
+	int status = pevent_read_number_field(ctx->cobalt_switch_next_pid_field,
+					      record->data, &val);
+	if (pid)
+		*pid = val;
+
+	return status;
+}
+
+static int cobalt_get_prev_state(struct xenomai_context *ctx,
+				 struct pevent_record *record,
+				 int *state)
+{
+	long long unsigned int val;
+	pevent_read_number_field(ctx->cobalt_switch_prev_state_field,
+				 record->data, &val);
+
+	if (state)
+		*state = val;
+
+	return (val & COBALT_PREV_STATE_BIT) ? 1 : 0;
+}
+
+static void cobalt_get_command(struct xenomai_context *ctx,
+			       struct pevent_record *record,
+			       const char **comm)
+{
+	int offset =
+	data2host4(ctx->pevent, record->data + ctx->cobalt_switch_next_name_field->offset);
+
+	offset &= COBALT_COMM_OFFSET_MASK;
+	*comm = record->data + offset;
+}
+
+static gboolean xenomai_switch_handler(struct pevent_record *record,
+				       int task_id,
+				       void *output)
+{
+	struct xenomai_context *ctx = xenomai_context_handler;
+
+	if (!ctx)
+		return FALSE;
+
+	switch (task_id) {
+		case KSHARK_PLUGIN_GET_PID:
+			cobalt_get_next_pid(ctx, record, output);
+			return TRUE;
+
+		case KSHARK_PLUGIN_GET_PREV_STATE:
+			return cobalt_get_prev_state(ctx, record, output);
+
+		case KSHARK_PLUGIN_GET_COMMAND:
+			cobalt_get_command(ctx, record, (const char**) output);
+			return TRUE;
+
+		default:
+			return FALSE;
+	}
+}
+
+static int cobalt_get_wakeup_pid(struct xenomai_context *ctx,
+				 struct pevent_record *record,
+				 int *pid)
+{
+	long long unsigned int val;
+	int status = pevent_read_number_field(ctx->cobalt_wakeup_pid_field,
+					      record->data, &val);
+
+	if (pid)
+		*pid = val;
+
+	return status;
+}
+
+static gboolean xenomai_wakeup_handler(struct pevent_record *record,
+					int task_id,
+					void *output)
+{
+	struct xenomai_context *ctx = xenomai_context_handler;
+
+	if (!ctx)
+		return FALSE;
+
+	switch (task_id) {
+		case KSHARK_PLUGIN_GET_PID:
+			cobalt_get_wakeup_pid(ctx, record, output);
+			return TRUE;
+
+		default:
+			return FALSE;
+	}
+}
+
+void KSHARK_PLUGIN_LOADER(void *info, void *store)
+{
+	struct shark_info *ks_info = info;
+	struct trace_view_store *ks_store = store;
+
+	xenomai_context_new(ks_info, ks_store);
+
+	if (!xenomai_context_handler)
+		return;
+
+	struct xenomai_context *ctx = xenomai_context_handler;
+
+	switch_handler = make_gui_event_handler(ctx->cobalt_switch_event->id,
+						KSHARK_PLUGIN_SWITCH_EVENT,
+						xenomai_switch_handler,
+						xenomai_update_context);
+
+	wakeup_handler = make_gui_event_handler(ctx->cobalt_wakeup_event->id,
+						KSHARK_PLUGIN_WAKEUP_EVENT,
+						xenomai_wakeup_handler,
+						xenomai_update_context);
+
+	if (switch_handler && wakeup_handler) {
+		trace_view_store_register_gui_handler(ks_store, switch_handler);
+		trace_view_store_register_gui_handler(ks_store, wakeup_handler);
+
+		trace_graph_register_gui_handler(ks_info->ginfo, switch_handler);
+		trace_graph_register_gui_handler(ks_info->ginfo, wakeup_handler);
+	}
+}
+
+void KSHARK_PLUGIN_RELOADER(void *info, void *store)
+{
+	struct shark_info *ks_info = info;
+	struct trace_view_store *ks_store = store;
+
+	if (!xenomai_context_handler) {
+		xenomai_context_new(ks_info, ks_store);
+
+		if (!xenomai_context_handler)
+			return;
+	} else {
+		int status = xenomai_update_context(tracecmd_get_pevent(ks_info->handle),
+						    KSHARK_PLUGIN_UPDATE_ALL);
+
+		if (status == FALSE)
+			return;
+	}
+
+	if (switch_handler && wakeup_handler) {
+		trace_view_store_register_gui_handler(ks_store, switch_handler);
+		trace_view_store_register_gui_handler(ks_store, wakeup_handler);
+	}
+}
+
+void KSHARK_PLUGIN_UNLOADER(void *info, void *store)
+{
+	struct shark_info *ks_info = info;
+	struct trace_view_store *ks_store = store;
+	struct xenomai_context *ctx = xenomai_context_handler;
+
+	if (!ctx)
+		return;
+
+	if (switch_handler) {
+		unregister_gui_event_handler(&ks_store->event_handlers,
+					     ctx->cobalt_switch_event->id);
+
+		unregister_gui_event_handler(&ks_info->ginfo->event_handlers,
+					     ctx->cobalt_switch_event->id);
+
+		free(switch_handler);
+		switch_handler = NULL;
+	}
+
+	if (wakeup_handler) {
+		unregister_gui_event_handler(&ks_store->event_handlers,
+					     ctx->cobalt_wakeup_event->id);
+
+		unregister_gui_event_handler(&ks_info->ginfo->event_handlers,
+				             ctx->cobalt_wakeup_event->id);
+
+		free(wakeup_handler);
+		wakeup_handler = NULL;
+	}
+
+	free(ctx);
+	xenomai_context_handler = NULL;
+}
-- 
2.15.0.rc0

  parent reply	other threads:[~2017-11-10 12:31 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-10 12:29 [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Yordan Karadzhov (VMware)
2017-11-10 12:29 ` [PATCH v2 2/4] kernelshark: Adding a GUI event handler Yordan Karadzhov (VMware)
2017-11-10 14:27   ` Steven Rostedt
2017-11-10 12:29 ` [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph Yordan Karadzhov (VMware)
2017-11-10 15:28   ` Steven Rostedt
2017-11-10 17:58     ` Yordan Karadzhov
2017-11-10 12:29 ` Yordan Karadzhov (VMware) [this message]
2017-11-10 14:23 ` [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins 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=20171110122915.24929-4-y.karadz@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=jan.kiszka@siemens.com \
    --cc=linux-kernel@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

all inboxes | Powered by JetHome®