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