linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins
@ 2017-11-10 12:29 Yordan Karadzhov (VMware)
  2017-11-10 12:29 ` [PATCH v2 2/4] kernelshark: Adding a GUI event handler Yordan Karadzhov (VMware)
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Yordan Karadzhov (VMware) @ 2017-11-10 12:29 UTC (permalink / raw)
  To: rostedt; +Cc: jan.kiszka, linux-kernel, Yordan Karadzhov (VMware)

Makefile modified in order to support building of GUI plugins.

kshark_plugin_loader and kshark_plugin_unloader are modified

kshark_plugin_reloader is defined and is called when the user
loads a new trace data file.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 Makefile        |  31 ++++++++++--
 kernel-shark.c  | 150 +++++++++++++++++++++++++++++++++++++-------------------
 kshark-plugin.h |  22 ++++++++-
 3 files changed, 146 insertions(+), 57 deletions(-)

diff --git a/Makefile b/Makefile
index 5c35143..8d0f16f 100644
--- a/Makefile
+++ b/Makefile
@@ -293,6 +293,8 @@ else
   print_shared_lib_compile =	echo '  $(GUI)COMPILE SHARED LIB '$(GOBJ);
   print_plugin_obj_compile =	echo '  $(GUI)COMPILE PLUGIN OBJ '$(GOBJ);
   print_plugin_build =		echo '  $(GUI)BUILD PLUGIN       '$(GOBJ);
+  print_gui_plugin_obj_compile =	echo '  $(GUI)COMPILE GUI_PLUGIN OBJ '$(GOBJ);
+  print_gui_plugin_build =		echo '  $(GUI)BUILD GUI_PLUGIN       '$(GOBJ);
   print_static_lib_build =	echo '  $(GUI)BUILD STATIC LIB   '$(GOBJ);
   print_install =		echo '  $(GUI)INSTALL     '$(GSPACE)$1'	to	$(DESTDIR_SQ)$2';
 endif
@@ -317,6 +319,14 @@ do_plugin_build =				\
 	($(print_plugin_build)			\
 	$(CC) $(CFLAGS) $(LDFLAGS) -shared -nostartfiles -o $@ $<)
 
+do_compile_gui_plugin_obj =				\
+	($(print_gui_plugin_obj_compile)		\
+	$(CC) -c $(CPPFLAGS) $(CFLAGS) -fPIC -o $@ $<)
+
+do_gui_plugin_build =				\
+	($(print_gui_plugin_build)			\
+	$(CC) $(CFLAGS) $(LDFLAGS) -shared -nostartfiles -o $@ $<)
+
 do_build_static_lib =				\
 	($(print_static_lib_build)		\
 	$(RM) $@;  $(AR) rcs $@ $^)
@@ -373,13 +383,17 @@ PLUGIN_OBJS += plugin_tlb.o
 
 PLUGINS := $(PLUGIN_OBJS:.o=.so)
 
+GUI_PLUGIN_OBJS =
+
+GUI_PLUGINS := $(GUI_PLUGIN_OBJS:.o=.so)
+
 ALL_OBJS = $(TRACE_CMD_OBJS) $(KERNEL_SHARK_OBJS) $(TRACE_VIEW_MAIN_OBJS) \
-	$(TRACE_GRAPH_MAIN_OBJS) $(TCMD_LIB_OBJS) $(PLUGIN_OBJS)
+	$(TRACE_GRAPH_MAIN_OBJS) $(TCMD_LIB_OBJS) $(PLUGIN_OBJS) $(GUI_PLUGIN_OBJS)
 
 CMD_TARGETS = trace_plugin_dir trace_python_dir tc_version.h libparsevent.a $(LIB_FILE) \
 	trace-cmd  $(PLUGINS) $(BUILD_PYTHON)
 
-GUI_TARGETS = ks_version.h trace-graph trace-view kernelshark
+GUI_TARGETS = ks_version.h trace-graph trace-view kernelshark $(GUI_PLUGINS)
 
 TARGETS = $(CMD_TARGETS) $(GUI_TARGETS)
 
@@ -401,7 +415,7 @@ gui: $(CMD_TARGETS)
 
 all_gui: $(GUI_TARGETS) show_gui_done
 
-GUI_OBJS = $(KERNEL_SHARK_OBJS) $(TRACE_VIEW_MAIN_OBJS) $(TRACE_GRAPH_MAIN_OBJS)
+GUI_OBJS = $(KERNEL_SHARK_OBJS) $(TRACE_VIEW_MAIN_OBJS) $(TRACE_GRAPH_MAIN_OBJS) $(GUI_PLUGIN_OBJS)
 
 gui_objs := $(sort $(GUI_OBJS))
 
@@ -447,6 +461,12 @@ $(PLUGIN_OBJS): %.o : $(src)/%.c
 $(PLUGINS): %.so: %.o
 	$(Q)$(do_plugin_build)
 
+$(GUI_PLUGIN_OBJS): %.o : $(src)/%.c
+	$(Q)$(do_compile_gui_plugin_obj)
+
+$(GUI_PLUGINS): %.so: %.o
+	$(Q)$(do_gui_plugin_build)
+
 define make_version.h
 	(echo '/* This file is automatically generated. Do not modify. */';		\
 	echo \#define VERSION_CODE $(shell						\
@@ -549,7 +569,10 @@ cscope: force
 	$(RM) cscope*
 	find . -name '*.[ch]' | cscope -b -q
 
-PLUGINS_INSTALL = $(subst .so,.install,$(PLUGINS)) $(subst .so,.install,$(PYTHON_PLUGINS))
+PLUGINS_INSTALL =
+PLUGINS_INSTALL += $(subst .so,.install,$(PLUGINS))
+PLUGINS_INSTALL += $(subst .so,.install,$(GUI_PLUGINS))
+PLUGINS_INSTALL += $(subst .so,.install,$(PYTHON_PLUGINS))
 
 define do_install
 	$(print_install)				\
diff --git a/kernel-shark.c b/kernel-shark.c
index 89723c3..79b387a 100644
--- a/kernel-shark.c
+++ b/kernel-shark.c
@@ -339,6 +339,96 @@ int kernelshark_load_file(struct shark_info *info, const char *file)
 	return 0;
 }
 
+static struct plugin_list {
+	struct plugin_list		*next;
+	const char			*file;
+} *plugins;
+static struct plugin_list **plugin_next = &plugins;
+
+static void add_plugin(const char *file)
+{
+	struct stat st;
+	int ret;
+
+	ret = stat(file, &st);
+	if (ret < 0) {
+		warning("plugin %s not found", file);
+		return;
+	}
+
+	*plugin_next = calloc(sizeof(struct plugin_list), 1);
+	if (!*plugin_next) {
+		warning("failed to allocat memory for plugin");
+		return;
+	}
+
+	(*plugin_next)->file = file;
+	plugin_next = &(*plugin_next)->next;
+}
+
+static void handle_plugins(struct shark_info *info,
+			   struct trace_view_store *store,
+			   int task_id)
+{
+	kshark_plugin_load_func func;
+	struct plugin_list *plugin;
+	void *handle;
+	char* func_name;
+	int fn_size = 0;
+
+	switch (task_id) {
+		case KSHARK_PLUGIN_LOAD:
+			fn_size = asprintf(&func_name, KSHARK_PLUGIN_LOADER_NAME);
+			break;
+
+		case KSHARK_PLUGIN_RELOAD:
+			fn_size = asprintf(&func_name, KSHARK_PLUGIN_RELOADER_NAME);
+			break;
+
+		case KSHARK_PLUGIN_UNLOAD:
+			fn_size = asprintf(&func_name, KSHARK_PLUGIN_UNLOADER_NAME);
+			break;
+
+		default:
+			return;
+	}
+
+	if (fn_size <= 0) {
+		warning("failed to allocat memory for plugin function name");
+		return;
+	}
+
+	for (plugin = plugins; plugin; plugin = plugin->next) {
+		handle = dlopen(plugin->file, RTLD_NOW | RTLD_GLOBAL);
+
+		if (!handle) {
+			warning("cound not load plugin '%s'\n%s\n",
+				plugin->file, dlerror());
+			continue;
+		}
+
+		func = dlsym(handle, func_name);
+		if (!func) {
+			warning("cound not find func '%s' in plugin '%s'\n%s\n",
+				func_name, plugin->file, dlerror());
+			continue;
+		}
+
+		func(info, store);
+	}
+
+	if (task_id == KSHARK_PLUGIN_UNLOAD) {
+		while ((plugin = plugins)) {
+			plugins = plugin->next;
+			free(plugin);
+		}
+
+		plugin_next = &plugins;
+	}
+
+	free(func_name);
+}
+
 static void
 /* Callback for the clicked signal of the Load button */
 load_clicked (gpointer data)
@@ -353,6 +443,9 @@ load_clicked (gpointer data)
 
 	kernelshark_load_file(info, filename);
 
+	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->treeview));
+	handle_plugins(info, TRACE_VIEW_STORE(model), KSHARK_PLUGIN_RELOAD);
+
 	g_free(filename);
 }
 
@@ -1805,56 +1898,6 @@ button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
 	return FALSE;
 }
 
-static struct plugin_list {
-	struct plugin_list		*next;
-	const char			*file;
-} *plugins;
-static struct plugin_list **plugin_next = &plugins;
-
-static void add_plugin(const char *file)
-{
-	struct stat st;
-	int ret;
-
-	ret = stat(file, &st);
-	if (ret < 0) {
-		warning("plugin %s not found", file);
-		return;
-	}
-
-	*plugin_next = calloc(sizeof(struct plugin_list), 1);
-	if (!*plugin_next)
-		die("failed to allocat memory for plugin");
-
-	(*plugin_next)->file = file;
-	plugin_next = &(*plugin_next)->next;
-}
-
-static void handle_plugins(struct shark_info *info)
-{
-	kshark_plugin_load_func func;
-	struct plugin_list *plugin;
-	void *handle;
-
-	while ((plugin = plugins)) {
-		plugins = plugin->next;
-
-		handle = dlopen(plugin->file, RTLD_NOW | RTLD_GLOBAL);
-		free(plugin);
-		if (!handle) {
-			warning("cound not load plugin '%s'\n%s\n",
-				plugin->file, dlerror());
-			continue;
-		}
-		func = dlsym(handle, KSHARK_PLUGIN_LOADER_NAME);
-		if (!func) {
-			warning("cound not find func '%s' in plugin '%s'\n%s\n",
-				KSHARK_PLUGIN_LOADER_NAME, plugin->file, dlerror());
-			continue;
-		}
-		func(info);
-	}
-}
 
 static void sig_end(int sig)
 {
@@ -1882,6 +1925,7 @@ void kernel_shark(int argc, char **argv)
 	GtkWidget *spin;
 	GtkWidget *check;
 	GtkWidget *statusbar;
+	GtkTreeModel *model;
 	int ret;
 	int c;
 
@@ -2495,7 +2539,8 @@ void kernel_shark(int argc, char **argv)
 
 	gtk_widget_set_size_request(window, TRACE_WIDTH, TRACE_HEIGHT);
 
-	handle_plugins(info);
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->treeview));
+	handle_plugins(info, TRACE_VIEW_STORE(model), KSHARK_PLUGIN_LOAD);
 
 	gdk_threads_enter();
 
@@ -2510,6 +2555,9 @@ void kernel_shark(int argc, char **argv)
 	info->ginfo->no_draw = FALSE;
 	gtk_main ();
 	gdk_threads_leave();
+
+	model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->treeview));
+	handle_plugins(info, TRACE_VIEW_STORE(model), KSHARK_PLUGIN_UNLOAD);
 }
 
 int main(int argc, char **argv)
diff --git a/kshark-plugin.h b/kshark-plugin.h
index 95ba797..81c09b5 100644
--- a/kshark-plugin.h
+++ b/kshark-plugin.h
@@ -17,19 +17,37 @@
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
+
+#include <limits.h>
+
+#include "event-parse.h"
+
 #ifndef _KSHARK_PLUGIN_H
 #define _KSHARK_PLUGIN_H
 
 #define KSHARK_PLUGIN_LOADER kshark_plugin_loader
+#define KSHARK_PLUGIN_RELOADER kshark_plugin_reloader
 #define KSHARK_PLUGIN_UNLOADER kshark_plugin_unloader
 
 #define _MAKE_STR(x)	#x
 #define MAKE_STR(x)	_MAKE_STR(x)
 #define KSHARK_PLUGIN_LOADER_NAME MAKE_STR(KSHARK_PLUGIN_LOADER)
+#define KSHARK_PLUGIN_RELOADER_NAME MAKE_STR(KSHARK_PLUGIN_RELOADER)
 #define KSHARK_PLUGIN_UNLOADER_NAME MAKE_STR(KSHARK_PLUGIN_UNLOADER)
 
-typedef int (*kshark_plugin_load_func)(void *info);
-typedef int (*kshark_plugin_unload_func)(void *info);
+typedef int (*kshark_plugin_load_func)(void *info, void *store);
+typedef int (*kshark_plugin_unload_func)(void *info, void *store);
+
+typedef int (*kshark_plugin_event_handler_func)(struct pevent_record *record,
+						int task_id,
+						void *val);
+
+typedef int (*kshark_plugin_context_update_func)(struct pevent *pevent, int task_id);
 
+enum gui_plugin_actions {
+	KSHARK_PLUGIN_LOAD,
+	KSHARK_PLUGIN_RELOAD,
+	KSHARK_PLUGIN_UNLOAD,
+};
 
 #endif
-- 
2.15.0.rc0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/4] kernelshark: Adding a GUI event handler
  2017-11-10 12:29 [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Yordan Karadzhov (VMware)
@ 2017-11-10 12:29 ` 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)
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Yordan Karadzhov (VMware) @ 2017-11-10 12:29 UTC (permalink / raw)
  To: rostedt; +Cc: jan.kiszka, linux-kernel, Yordan Karadzhov (VMware)

gui_event_handler is defined. Instruments for dealing
with this handler are added.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 Makefile        |  6 ++---
 kshark-plugin.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 kshark-plugin.h | 22 ++++++++++++++++++
 3 files changed, 94 insertions(+), 3 deletions(-)
 create mode 100644 kshark-plugin.c

diff --git a/Makefile b/Makefile
index 8d0f16f..992e6b0 100644
--- a/Makefile
+++ b/Makefile
@@ -348,17 +348,17 @@ $(obj)/%.o: $(src)/%.c
 	$(Q)$(call check_gui)
 
 TRACE_GUI_OBJS = trace-filter.o trace-compat.o trace-filter-hash.o trace-dialog.o \
-		trace-xml.o
+		trace-xml.o kshark-plugin.o
 TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \
 	 trace-stack.o trace-hist.o trace-mem.o trace-snapshot.o trace-stat.o \
 	 trace-hash.o trace-profile.o trace-stream.o trace-record.o trace-restore.o \
 	 trace-check-events.o trace-show.o trace-list.o
-TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
+TRACE_VIEW_OBJS = trace-view.o trace-view-store.o kshark-plugin.o
 TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o
 TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS)
 TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS)
 KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \
-	trace-capture.o kernel-shark.o
+	trace-capture.o kernel-shark.o kshark-plugin.o
 
 PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o str_error_r.o
 TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \
diff --git a/kshark-plugin.c b/kshark-plugin.c
new file mode 100644
index 0000000..6532512
--- /dev/null
+++ b/kshark-plugin.c
@@ -0,0 +1,69 @@
+/*
+ * 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 General Public License as published by
+ * the Free Software Foundation; version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,  see <http://www.gnu.org/licenses>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <stdlib.h>
+
+#include "kshark-plugin.h"
+
+struct gui_event_handler *make_gui_event_handler(int event_id, int type,
+						 kshark_plugin_event_handler_func evt_func,
+						 kshark_plugin_context_update_func ctx_func)
+{
+	struct gui_event_handler *handler = malloc(sizeof(struct gui_event_handler));
+
+	if (!handler)
+		return NULL;
+
+	handler->next = NULL;
+	handler->id = event_id;
+	handler->type = type;
+	handler->event_func = evt_func;
+	handler->context_func = ctx_func;
+
+	return handler;
+}
+
+struct gui_event_handler *find_gui_event_handler(struct gui_event_handler *handlers,
+						 int event_id)
+{
+	while (handlers) {
+		if (handlers->id == event_id)
+			return handlers;
+
+		handlers = handlers->next;
+	}
+
+	return NULL;
+}
+
+void unregister_gui_event_handler(struct gui_event_handler **handlers, int event_id)
+{
+	struct gui_event_handler **last = handlers;
+	struct gui_event_handler *list;
+
+	for (list = *handlers; list; list = list->next) {
+		if (list->id == event_id) {
+			*last = list->next;
+			return;
+		}
+
+		last = &list->next;
+	}
+}
diff --git a/kshark-plugin.h b/kshark-plugin.h
index 81c09b5..d65ee02 100644
--- a/kshark-plugin.h
+++ b/kshark-plugin.h
@@ -50,4 +50,26 @@ enum gui_plugin_actions {
 	KSHARK_PLUGIN_UNLOAD,
 };
 
+enum gui_event_types {
+	KSHARK_PLUGIN_SWITCH_EVENT,
+	KSHARK_PLUGIN_WAKEUP_EVENT,
+};
+
+struct gui_event_handler {
+	struct gui_event_handler		*next;
+	int					id;
+	int 					type;
+	kshark_plugin_event_handler_func	event_func;
+	kshark_plugin_context_update_func       context_func;
+};
+
+struct gui_event_handler *make_gui_event_handler(int event_id, int type,
+						 kshark_plugin_event_handler_func evt_func,
+						 kshark_plugin_context_update_func ctx_func);
+
+struct gui_event_handler *find_gui_event_handler(struct gui_event_handler *handlers,
+						 int event_id);
+
+void unregister_gui_event_handler(struct gui_event_handler **handlers, int event_id);
+
 #endif
-- 
2.15.0.rc0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph
  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 12:29 ` Yordan Karadzhov (VMware)
  2017-11-10 15:28   ` Steven Rostedt
  2017-11-10 12:29 ` [PATCH v2 4/4] kernelshark: Adding a GUI plugin for xenomai events Yordan Karadzhov (VMware)
  2017-11-10 14:23 ` [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Steven Rostedt
  3 siblings, 1 reply; 8+ messages in thread
From: Yordan Karadzhov (VMware) @ 2017-11-10 12:29 UTC (permalink / raw)
  To: rostedt; +Cc: jan.kiszka, linux-kernel, Yordan Karadzhov (VMware)

gui_event_handlers are added to trace_view_store and graph_info.
The handlers are used to execute plugin-specific actions
during the processing of the trace data.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kshark-plugin.h    |  3 +++
 trace-graph.c      | 41 +++++++++++++++++++++++++++++++++++++++++
 trace-graph.h      |  7 +++++++
 trace-plot-task.c  | 17 +++++++++++++----
 trace-view-store.c | 16 ++++++++++++++++
 trace-view-store.h |  5 +++++
 6 files changed, 85 insertions(+), 4 deletions(-)

diff --git a/kshark-plugin.h b/kshark-plugin.h
index d65ee02..42fb40c 100644
--- a/kshark-plugin.h
+++ b/kshark-plugin.h
@@ -48,6 +48,9 @@ enum gui_plugin_actions {
 	KSHARK_PLUGIN_LOAD,
 	KSHARK_PLUGIN_RELOAD,
 	KSHARK_PLUGIN_UNLOAD,
+	KSHARK_PLUGIN_GET_PID,
+	KSHARK_PLUGIN_GET_PREV_STATE,
+	KSHARK_PLUGIN_GET_COMMAND,
 };
 
 enum gui_event_types {
diff --git a/trace-graph.c b/trace-graph.c
index 1db342f..a79aacf 100644
--- a/trace-graph.c
+++ b/trace-graph.c
@@ -129,6 +129,12 @@ static void free_task_hash(struct graph_info *ginfo)
 	}
 }
 
+void trace_graph_register_gui_handler(struct graph_info *info,
+				      struct gui_event_handler *handler) {
+	handler->next = info->event_handlers;
+	info->event_handlers = handler;
+}
+
 /**
  * trace_graph_task_list - return an allocated list of all found tasks
  * @ginfo: The graph info structure
@@ -1021,6 +1027,7 @@ int trace_graph_check_sched_wakeup(struct graph_info *ginfo,
 				   gint *pid)
 {
 	struct event_format *event;
+	struct gui_event_handler *handler;
 	unsigned long long val;
 	gboolean found;
 	gint id;
@@ -1079,6 +1086,20 @@ int trace_graph_check_sched_wakeup(struct graph_info *ginfo,
 		return 1;
 	}
 
+	handler = find_gui_event_handler(ginfo->event_handlers, id);
+
+	if (handler) {
+		if (handler->type == KSHARK_PLUGIN_WAKEUP_EVENT) {
+			if (!handler->event_func(record, KSHARK_PLUGIN_GET_PID, &val))
+				return 0;
+
+			if (pid)
+				*pid = val;
+
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
@@ -1088,6 +1109,7 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo,
 {
 	unsigned long long val;
 	struct event_format *event;
+	struct gui_event_handler *handler;
 	gint this_pid;
 	gint id;
 	int ret = 1;
@@ -1118,7 +1140,9 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo,
 		}
 	}
 
+
 	id = pevent_data_type(ginfo->pevent, record);
+
 	if (id == ginfo->event_sched_switch_id) {
 		pevent_read_number_field(ginfo->event_pid_field, record->data, &val);
 		if (comm)
@@ -1139,6 +1163,20 @@ int trace_graph_check_sched_switch(struct graph_info *ginfo,
 		goto out;
 	}
 
+	handler = find_gui_event_handler(ginfo->event_handlers, id);
+
+	if (handler) {
+		if (handler->type == KSHARK_PLUGIN_SWITCH_EVENT) {
+			if (handler->event_func(record, KSHARK_PLUGIN_GET_PID, &val)) {
+				if (pid)
+					*pid = val;
+				if(comm)
+					handler->event_func(record, KSHARK_PLUGIN_GET_COMMAND, &comm);
+				goto out;
+			}
+		}
+	}
+
 	ret = 0;
  out:
 	if (ret && comm && ginfo->read_comms) {
@@ -1285,6 +1323,7 @@ static void draw_info_box(struct graph_info *ginfo, const gchar *buffer,
 
 	view_start = gtk_adjustment_get_value(ginfo->hadj);
 	view_width = gtk_adjustment_get_page_size(ginfo->hadj);
+
 	if (x > view_start + width)
 		x -= width;
 
@@ -2781,6 +2820,8 @@ trace_graph_create_with_callbacks(struct tracecmd_input *handle,
 
 	ginfo->callbacks = cbs;
 
+	ginfo->event_handlers = NULL;
+
 	ginfo->task_filter = filter_task_hash_alloc();
 	ginfo->hide_tasks = filter_task_hash_alloc();
 
diff --git a/trace-graph.h b/trace-graph.h
index 7e66838..21e8feb 100644
--- a/trace-graph.h
+++ b/trace-graph.h
@@ -24,6 +24,7 @@
 #include "trace-cmd.h"
 #include "trace-filter-hash.h"
 #include "trace-xml.h"
+#include "kshark-plugin.h"
 
 struct graph_info;
 
@@ -258,6 +259,8 @@ struct graph_info {
 	gint			plot_data_y;
 	gint			plot_data_w;
 	gint			plot_data_h;
+
+	struct gui_event_handler *event_handlers;
 };
 
 
@@ -266,6 +269,10 @@ trace_graph_create(struct tracecmd_input *handle);
 struct graph_info *
 trace_graph_create_with_callbacks(struct tracecmd_input *handle,
 				  struct graph_callbacks *cbs);
+
+void trace_graph_register_gui_handler(struct graph_info *info,
+				      struct gui_event_handler *handler);
+
 void trace_graph_select_by_time(struct graph_info *ginfo, guint64 time);
 
 void trace_graph_event_filter_callback(gboolean accept,
diff --git a/trace-plot-task.c b/trace-plot-task.c
index 3b7e81f..56c3e96 100644
--- a/trace-plot-task.c
+++ b/trace-plot-task.c
@@ -68,11 +68,20 @@ static gboolean is_running(struct graph_info *ginfo, struct pevent_record *recor
 	int id;
 
 	id = pevent_data_type(ginfo->pevent, record);
-	if (id != ginfo->event_sched_switch_id)
-		return FALSE;
 
-	pevent_read_number_field(ginfo->event_prev_state, record->data, &val);
-	return val & ((1 << 11) - 1)? FALSE : TRUE;
+	if (id == ginfo->event_sched_switch_id) {
+		pevent_read_number_field(ginfo->event_prev_state, record->data, &val);
+		return val & ((1 << 11) - 1)? FALSE : TRUE;
+	}
+
+	struct gui_event_handler *handler =
+	find_gui_event_handler(ginfo->event_handlers, id);
+	if (handler) {
+		if (handler->type == KSHARK_PLUGIN_SWITCH_EVENT)
+			return handler->event_func(record, KSHARK_PLUGIN_GET_PREV_STATE, NULL);
+	}
+
+	return FALSE;
 }
 
 static gboolean record_matches_pid(struct graph_info *ginfo,
diff --git a/trace-view-store.c b/trace-view-store.c
index f5d0a04..39d0c74 100644
--- a/trace-view-store.c
+++ b/trace-view-store.c
@@ -70,6 +70,12 @@ static gboolean		trace_view_store_iter_parent	(GtkTreeModel	*tree_model,
 static GObjectClass *parent_class = NULL;	/* GObject stuff - nothing to worry about */
 
 
+void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler)
+{
+	handler->next = store->event_handlers;
+	store->event_handlers = handler;
+}
+
 /*****************************************************************************
  *
  *	trace_view_store_get_type: here we register our new type and its interfaces
@@ -866,6 +872,7 @@ trace_view_store_new (struct tracecmd_input *handle)
 
 	g_assert( newstore != NULL );
 
+	newstore->event_handlers = NULL;
 	newstore->handle = handle;
 	newstore->cpus = tracecmd_cpus(handle);
 	tracecmd_ref(handle);
@@ -1194,6 +1201,7 @@ static gboolean show_task(TraceViewStore *store, struct pevent *pevent,
 			  struct pevent_record *record, gint pid)
 {
 	gint event_id;
+	struct gui_event_handler *ge_handler;
 
 	if (view_task(store, pid))
 		return TRUE;
@@ -1224,6 +1232,14 @@ static gboolean show_task(TraceViewStore *store, struct pevent *pevent,
 			return TRUE;
 	}
 
+	ge_handler = find_gui_event_handler(store->event_handlers, event_id);
+
+	if (ge_handler) {
+		if (ge_handler->event_func(record, KSHARK_PLUGIN_GET_PID, &pid))
+			if (view_task(store, pid))
+				return TRUE;
+	}
+
 	return FALSE;
 }
 
diff --git a/trace-view-store.h b/trace-view-store.h
index 03141b1..333116c 100644
--- a/trace-view-store.h
+++ b/trace-view-store.h
@@ -23,6 +23,7 @@
 #include <gtk/gtk.h>
 #include "trace-cmd.h"
 #include "trace-filter-hash.h"
+#include "kshark-plugin.h"
 
 /* Some boilerplate GObject defines. 'klass' is used
  *   instead of 'class', because 'class' is a C++ keyword */
@@ -125,8 +126,12 @@ struct trace_view_store
 	guint64			*cpu_mask;  /* cpus that are enabled */
 
 	gint		stamp;	/* Random integer to check whether an iter belongs to our model */
+
+	struct gui_event_handler *event_handlers;
 };
 
+void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler);
+
 gboolean trace_view_store_cpu_isset(TraceViewStore *store, gint cpu);
 
 void trace_view_store_set_all_cpus(TraceViewStore *store);
-- 
2.15.0.rc0

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/4] kernelshark: Adding a GUI plugin for xenomai events
  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 12:29 ` [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph Yordan Karadzhov (VMware)
@ 2017-11-10 12:29 ` Yordan Karadzhov (VMware)
  2017-11-10 14:23 ` [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Steven Rostedt
  3 siblings, 0 replies; 8+ messages in thread
From: Yordan Karadzhov (VMware) @ 2017-11-10 12:29 UTC (permalink / raw)
  To: rostedt; +Cc: jan.kiszka, linux-kernel, Yordan Karadzhov (VMware)

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

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins
  2017-11-10 12:29 [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Yordan Karadzhov (VMware)
                   ` (2 preceding siblings ...)
  2017-11-10 12:29 ` [PATCH v2 4/4] kernelshark: Adding a GUI plugin for xenomai events Yordan Karadzhov (VMware)
@ 2017-11-10 14:23 ` Steven Rostedt
  3 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2017-11-10 14:23 UTC (permalink / raw)
  To: Yordan Karadzhov (VMware); +Cc: jan.kiszka, linux-kernel

On Fri, 10 Nov 2017 14:29:12 +0200
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> --- a/kernel-shark.c
> +++ b/kernel-shark.c
> @@ -339,6 +339,96 @@ int kernelshark_load_file(struct shark_info *info, const char *file)
>  	return 0;
>  }
>  
> +static struct plugin_list {
> +	struct plugin_list		*next;
> +	const char			*file;
> +} *plugins;
> +static struct plugin_list **plugin_next = &plugins;
> +
> +static void add_plugin(const char *file)
> +{
> +	struct stat st;
> +	int ret;
> +
> +	ret = stat(file, &st);
> +	if (ret < 0) {
> +		warning("plugin %s not found", file);
> +		return;
> +	}
> +
> +	*plugin_next = calloc(sizeof(struct plugin_list), 1);
> +	if (!*plugin_next) {
> +		warning("failed to allocat memory for plugin");
> +		return;
> +	}
> +
> +	(*plugin_next)->file = file;
> +	plugin_next = &(*plugin_next)->next;
> +}
> +
> +static void handle_plugins(struct shark_info *info,
> +			   struct trace_view_store *store,
> +			   int task_id)
> +{
> +	kshark_plugin_load_func func;
> +	struct plugin_list *plugin;
> +	void *handle;
> +	char* func_name;
> +	int fn_size = 0;
> +
> +	switch (task_id) {
> +		case KSHARK_PLUGIN_LOAD:
> +			fn_size = asprintf(&func_name, KSHARK_PLUGIN_LOADER_NAME);
> +			break;
> +
> +		case KSHARK_PLUGIN_RELOAD:
> +			fn_size = asprintf(&func_name, KSHARK_PLUGIN_RELOADER_NAME);
> +			break;
> +
> +		case KSHARK_PLUGIN_UNLOAD:
> +			fn_size = asprintf(&func_name, KSHARK_PLUGIN_UNLOADER_NAME);
> +			break;
> +
> +		default:
> +			return;
> +	}
> +
> +	if (fn_size <= 0) {
> +		warning("failed to allocat memory for plugin function name");
> +		return;
> +	}
> +
> +	for (plugin = plugins; plugin; plugin = plugin->next) {
> +		handle = dlopen(plugin->file, RTLD_NOW | RTLD_GLOBAL);
> +
> +		if (!handle) {
> +			warning("cound not load plugin '%s'\n%s\n",
> +				plugin->file, dlerror());
> +			continue;
> +		}
> +
> +		func = dlsym(handle, func_name);
> +		if (!func) {
> +			warning("cound not find func '%s' in plugin '%s'\n%s\n",
> +				func_name, plugin->file, dlerror());
> +			continue;
> +		}
> +
> +		func(info, store);
> +	}
> +
> +	if (task_id == KSHARK_PLUGIN_UNLOAD) {
> +		while ((plugin = plugins)) {
> +			plugins = plugin->next;
> +			free(plugin);
> +		}
> +
> +		plugin_next = &plugins;
> +	}
> +
> +	free(func_name);
> +}
> +

Break the move of the above functions into their own patch first, then
it is easier to see what changed here.

-- Steve

>  static void
>  /* Callback for the clicked signal of the Load button */
>  load_clicked (gpointer data)
> @@ -353,6 +443,9 @@ load_clicked (gpointer data)
>  
>  	kernelshark_load_file(info, filename);
>  
> +	GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(info->treeview));
> +	handle_plugins(info, TRACE_VIEW_STORE(model), KSHARK_PLUGIN_RELOAD);
> +
>  	g_free(filename);
>  }
>  
> @@ -1805,56 +1898,6 @@ button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
>  	return FALSE;
>  }
>  
> -static struct plugin_list {
> -	struct plugin_list		*next;
> -	const char			*file;
> -} *plugins;
> -static struct plugin_list **plugin_next = &plugins;
> -
> -static void add_plugin(const char *file)
> -{
> -	struct stat st;
> -	int ret;
> -
> -	ret = stat(file, &st);
> -	if (ret < 0) {
> -		warning("plugin %s not found", file);
> -		return;
> -	}
> -
> -	*plugin_next = calloc(sizeof(struct plugin_list), 1);
> -	if (!*plugin_next)
> -		die("failed to allocat memory for plugin");
> -
> -	(*plugin_next)->file = file;
> -	plugin_next = &(*plugin_next)->next;
> -}
> -
> -static void handle_plugins(struct shark_info *info)
> -{
> -	kshark_plugin_load_func func;
> -	struct plugin_list *plugin;
> -	void *handle;
> -
> -	while ((plugin = plugins)) {
> -		plugins = plugin->next;
> -
> -		handle = dlopen(plugin->file, RTLD_NOW | RTLD_GLOBAL);
> -		free(plugin);
> -		if (!handle) {
> -			warning("cound not load plugin '%s'\n%s\n",
> -				plugin->file, dlerror());
> -			continue;
> -		}
> -		func = dlsym(handle, KSHARK_PLUGIN_LOADER_NAME);
> -		if (!func) {
> -			warning("cound not find func '%s' in plugin '%s'\n%s\n",
> -				KSHARK_PLUGIN_LOADER_NAME, plugin->file, dlerror());
> -			continue;
> -		}
> -		func(info);
> -	}
> -}
>  

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 2/4] kernelshark: Adding a GUI event handler
  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
  0 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2017-11-10 14:27 UTC (permalink / raw)
  To: Yordan Karadzhov (VMware); +Cc: jan.kiszka, linux-kernel

On Fri, 10 Nov 2017 14:29:13 +0200
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> gui_event_handler is defined. Instruments for dealing
> with this handler are added.

Please add why this patch is needed in the change log.

> 
> Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
> ---
>  Makefile        |  6 ++---
>  kshark-plugin.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  kshark-plugin.h | 22 ++++++++++++++++++
>  3 files changed, 94 insertions(+), 3 deletions(-)
>  create mode 100644 kshark-plugin.c
> 
> diff --git a/Makefile b/Makefile
> index 8d0f16f..992e6b0 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -348,17 +348,17 @@ $(obj)/%.o: $(src)/%.c
>  	$(Q)$(call check_gui)
>  
>  TRACE_GUI_OBJS = trace-filter.o trace-compat.o trace-filter-hash.o trace-dialog.o \
> -		trace-xml.o
> +		trace-xml.o kshark-plugin.o
>  TRACE_CMD_OBJS = trace-cmd.o trace-record.o trace-read.o trace-split.o trace-listen.o \
>  	 trace-stack.o trace-hist.o trace-mem.o trace-snapshot.o trace-stat.o \
>  	 trace-hash.o trace-profile.o trace-stream.o trace-record.o trace-restore.o \
>  	 trace-check-events.o trace-show.o trace-list.o
> -TRACE_VIEW_OBJS = trace-view.o trace-view-store.o
> +TRACE_VIEW_OBJS = trace-view.o trace-view-store.o kshark-plugin.o
>  TRACE_GRAPH_OBJS = trace-graph.o trace-plot.o trace-plot-cpu.o trace-plot-task.o
>  TRACE_VIEW_MAIN_OBJS = trace-view-main.o $(TRACE_VIEW_OBJS) $(TRACE_GUI_OBJS)
>  TRACE_GRAPH_MAIN_OBJS = trace-graph-main.o $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS)
>  KERNEL_SHARK_OBJS = $(TRACE_VIEW_OBJS) $(TRACE_GRAPH_OBJS) $(TRACE_GUI_OBJS) \
> -	trace-capture.o kernel-shark.o
> +	trace-capture.o kernel-shark.o kshark-plugin.o
>  
>  PEVENT_LIB_OBJS = event-parse.o trace-seq.o parse-filter.o parse-utils.o str_error_r.o
>  TCMD_LIB_OBJS = $(PEVENT_LIB_OBJS) trace-util.o trace-input.o trace-ftrace.o \
> diff --git a/kshark-plugin.c b/kshark-plugin.c
> new file mode 100644
> index 0000000..6532512
> --- /dev/null
> +++ b/kshark-plugin.c
> @@ -0,0 +1,69 @@
> +/*
> + * 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 General Public License as published by
> + * the Free Software Foundation; version 2 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 General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not,  see <http://www.gnu.org/licenses>
> + *
> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> + */
> +
> +#include <stdlib.h>
> +
> +#include "kshark-plugin.h"
> +
> +struct gui_event_handler *make_gui_event_handler(int event_id, int type,
> +						 kshark_plugin_event_handler_func evt_func,
> +						 kshark_plugin_context_update_func ctx_func)
> +{
> +	struct gui_event_handler *handler = malloc(sizeof(struct gui_event_handler));
> +
> +	if (!handler)
> +		return NULL;
> +
> +	handler->next = NULL;
> +	handler->id = event_id;
> +	handler->type = type;
> +	handler->event_func = evt_func;
> +	handler->context_func = ctx_func;
> +
> +	return handler;
> +}
> +
> +struct gui_event_handler *find_gui_event_handler(struct gui_event_handler *handlers,
> +						 int event_id)
> +{
> +	while (handlers) {
> +		if (handlers->id == event_id)
> +			return handlers;
> +
> +		handlers = handlers->next;
> +	}
> +
> +	return NULL;
> +}
> +
> +void unregister_gui_event_handler(struct gui_event_handler **handlers, int event_id)
> +{
> +	struct gui_event_handler **last = handlers;
> +	struct gui_event_handler *list;
> +
> +	for (list = *handlers; list; list = list->next) {
> +		if (list->id == event_id) {
> +			*last = list->next;
> +			return;
> +		}
> +
> +		last = &list->next;
> +	}

Is something suppose to free the gui_event_handler?

Should there be a matching register_gui_event_handler()?

-- Steve

> +}
> diff --git a/kshark-plugin.h b/kshark-plugin.h
> index 81c09b5..d65ee02 100644
> --- a/kshark-plugin.h
> +++ b/kshark-plugin.h
> @@ -50,4 +50,26 @@ enum gui_plugin_actions {
>  	KSHARK_PLUGIN_UNLOAD,
>  };
>  
> +enum gui_event_types {
> +	KSHARK_PLUGIN_SWITCH_EVENT,
> +	KSHARK_PLUGIN_WAKEUP_EVENT,
> +};
> +
> +struct gui_event_handler {
> +	struct gui_event_handler		*next;
> +	int					id;
> +	int 					type;
> +	kshark_plugin_event_handler_func	event_func;
> +	kshark_plugin_context_update_func       context_func;
> +};
> +
> +struct gui_event_handler *make_gui_event_handler(int event_id, int type,
> +						 kshark_plugin_event_handler_func evt_func,
> +						 kshark_plugin_context_update_func ctx_func);
> +
> +struct gui_event_handler *find_gui_event_handler(struct gui_event_handler *handlers,
> +						 int event_id);
> +
> +void unregister_gui_event_handler(struct gui_event_handler **handlers, int event_id);
> +
>  #endif

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph
  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
  0 siblings, 1 reply; 8+ messages in thread
From: Steven Rostedt @ 2017-11-10 15:28 UTC (permalink / raw)
  To: Yordan Karadzhov (VMware); +Cc: jan.kiszka, linux-kernel

On Fri, 10 Nov 2017 14:29:14 +0200
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:


> +void trace_graph_register_gui_handler(struct graph_info *info,
> +				      struct gui_event_handler *handler) {
> +	handler->next = info->event_handlers;
> +	info->event_handlers = handler;
> +}
> +


>  
> +void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler)
> +{
> +	handler->next = store->event_handlers;
> +	store->event_handlers = handler;
> +}
> +


Hmm, and in the last patch we have:

+		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);

I think I see an issue here. ;-)

(Hint, what's the state of switch_handler->next and
 wakeup_handler->next, when this is done?)

-- Steve

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 3/4] kernelshark: Adding gui_event_handlers for View and Graph
  2017-11-10 15:28   ` Steven Rostedt
@ 2017-11-10 17:58     ` Yordan Karadzhov
  0 siblings, 0 replies; 8+ messages in thread
From: Yordan Karadzhov @ 2017-11-10 17:58 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: jan.kiszka, linux-kernel

On 10.11.2017 17:28, Steven Rostedt wrote:
> On Fri, 10 Nov 2017 14:29:14 +0200
> "Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:
>
>
>> +void trace_graph_register_gui_handler(struct graph_info *info,
>> +				      struct gui_event_handler *handler) {
>> +	handler->next = info->event_handlers;
>> +	info->event_handlers = handler;
>> +}
>> +
>
>>   
>> +void trace_view_store_register_gui_handler(TraceViewStore *store, struct gui_event_handler *handler)
>> +{
>> +	handler->next = store->event_handlers;
>> +	store->event_handlers = handler;
>> +}
>> +
>
> Hmm, and in the last patch we have:
>
> +		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);
>
> I think I see an issue here. ;-)
>
> (Hint, what's the state of switch_handler->next and
>   wakeup_handler->next, when this is done?)
I see the issue now.
Thank you very much!
Yordan

> -- Steve

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2017-11-10 17:59 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH v2 4/4] kernelshark: Adding a GUI plugin for xenomai events Yordan Karadzhov (VMware)
2017-11-10 14:23 ` [PATCH v2 1/4] kernelshark: Adding infrastructure for GUI plugins Steven Rostedt

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).