From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: rostedt@goodmis.org
Cc: linux-trace-devel@vger.kernel.org,
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH 6/7] kernel-shark-qt: Add filtering to the C API of KernelShark
Date: Mon, 25 Jun 2018 18:01:20 +0300 [thread overview]
Message-ID: <20180625150121.14291-7-y.karadz@gmail.com> (raw)
In-Reply-To: <20180625150121.14291-1-y.karadz@gmail.com>
Instruments for trace data filtering are added to the C API of
the Qt-based version of KernelShark. The following patch will
introduces an example, demonstrating the usage of this instruments.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
kernel-shark-qt/src/libkshark.c | 141 ++++++++++++++++++++++++++++++++
kernel-shark-qt/src/libkshark.h | 75 +++++++++++++++++
2 files changed, 216 insertions(+)
diff --git a/kernel-shark-qt/src/libkshark.c b/kernel-shark-qt/src/libkshark.c
index f112a50..c6e03a8 100644
--- a/kernel-shark-qt/src/libkshark.c
+++ b/kernel-shark-qt/src/libkshark.c
@@ -28,6 +28,14 @@ static bool kshark_default_context(struct kshark_context **context)
if (!kshark_ctx)
return false;
+ kshark_ctx->show_task_filter = tracecmd_filter_id_hash_alloc();
+ kshark_ctx->hide_task_filter = tracecmd_filter_id_hash_alloc();
+
+ kshark_ctx->show_event_filter = tracecmd_filter_id_hash_alloc();
+ kshark_ctx->hide_event_filter = tracecmd_filter_id_hash_alloc();
+
+ kshark_ctx->filter_mask = 0x0;
+
/* Free the existing context (if any). */
if (*context && *context != kshark_context_handler) {
free(*context);
@@ -112,6 +120,15 @@ void kshark_close(struct kshark_context *kshark_ctx)
if (!kshark_ctx || !kshark_ctx->handle)
return;
+ /*
+ * All Id filters are file specific. Make sure that the Pids and Event Ids
+ * from this file are not going to be used with another file.
+ */
+ tracecmd_filter_id_clear(kshark_ctx->show_task_filter);
+ tracecmd_filter_id_clear(kshark_ctx->hide_task_filter);
+ tracecmd_filter_id_clear(kshark_ctx->show_event_filter);
+ tracecmd_filter_id_clear(kshark_ctx->hide_event_filter);
+
tracecmd_close(kshark_ctx->handle);
kshark_ctx->handle = NULL;
kshark_ctx->pevt = NULL;
@@ -129,6 +146,12 @@ void kshark_free(struct kshark_context *kshark_ctx)
kshark_context_handler = NULL;
}
+ tracecmd_filter_id_hash_free(kshark_ctx->show_task_filter);
+ tracecmd_filter_id_hash_free(kshark_ctx->hide_task_filter);
+
+ tracecmd_filter_id_hash_free(kshark_ctx->show_event_filter);
+ tracecmd_filter_id_hash_free(kshark_ctx->hide_event_filter);
+
kshark_free_task_list(kshark_ctx);
if (seq.buffer)
@@ -171,6 +194,113 @@ kshark_add_task(struct kshark_context *kshark_ctx, int pid)
return list;
}
+static bool kshark_show_task(struct kshark_context *kshark_ctx, int pid)
+{
+ return (!kshark_ctx->show_task_filter ||
+ !kshark_ctx->show_task_filter->count ||
+ tracecmd_filter_id_find(kshark_ctx->show_task_filter, pid)) &&
+ (!kshark_ctx->hide_task_filter ||
+ !kshark_ctx->hide_task_filter->count ||
+ !tracecmd_filter_id_find(kshark_ctx->hide_task_filter, pid));
+}
+
+static bool kshark_show_event(struct kshark_context *kshark_ctx, int event_id)
+{
+ return (!kshark_ctx->show_event_filter ||
+ !kshark_ctx->show_event_filter->count ||
+ tracecmd_filter_id_find(kshark_ctx->show_event_filter, event_id)) &&
+ (!kshark_ctx->hide_event_filter ||
+ !kshark_ctx->hide_event_filter->count ||
+ !tracecmd_filter_id_find(kshark_ctx->hide_event_filter, event_id));
+}
+
+void kshark_filter_add_id(struct kshark_context *kshark_ctx, int filter_id, int id)
+{
+ switch (filter_id) {
+ case SHOW_EVENT_FILTER:
+ tracecmd_filter_id_add(kshark_ctx->show_event_filter, id);
+ break;
+
+ case HIDE_EVENT_FILTER:
+ tracecmd_filter_id_add(kshark_ctx->hide_event_filter, id);
+ break;
+
+ case SHOW_TASK_FILTER:
+ tracecmd_filter_id_add(kshark_ctx->show_task_filter, id);
+ break;
+
+ case HIDE_TASK_FILTER:
+ tracecmd_filter_id_add(kshark_ctx->hide_task_filter, id);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void kshark_filter_clear(struct kshark_context *kshark_ctx, int filter_id)
+{
+ switch (filter_id) {
+ case SHOW_EVENT_FILTER:
+ tracecmd_filter_id_clear(kshark_ctx->show_event_filter);
+ break;
+
+ case HIDE_EVENT_FILTER:
+ tracecmd_filter_id_clear(kshark_ctx->hide_event_filter);
+ break;
+
+ case SHOW_TASK_FILTER:
+ tracecmd_filter_id_clear(kshark_ctx->show_task_filter);
+ break;
+
+ case HIDE_TASK_FILTER:
+ tracecmd_filter_id_clear(kshark_ctx->hide_task_filter);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static bool kshark_filter_is_set(struct kshark_context *kshark_ctx)
+{
+ if ((kshark_ctx->show_task_filter &&
+ kshark_ctx->show_task_filter->count) ||
+ (kshark_ctx->hide_task_filter &&
+ kshark_ctx->hide_task_filter->count) ||
+ (kshark_ctx->show_event_filter &&
+ kshark_ctx->show_event_filter->count) ||
+ (kshark_ctx->hide_event_filter &&
+ kshark_ctx->hide_event_filter->count)) {
+ return true;
+ }
+
+ return false;
+}
+
+void kshark_filter_entries(struct kshark_context *kshark_ctx,
+ struct kshark_entry **data,
+ size_t n_entries)
+{
+ if (!kshark_filter_is_set(kshark_ctx))
+ return;
+
+ int i;
+ for (i = 0; i < n_entries; ++i) {
+ data[i]->visible = 0xFF;
+ if (!kshark_show_task(kshark_ctx, data[i]->pid)) {
+ data[i]->visible &= ~kshark_ctx->filter_mask;
+ }
+
+ if (!kshark_show_event(kshark_ctx, data[i]->event_id)) {
+ int mask = kshark_ctx->filter_mask;
+ mask &= ~KS_GRAPH_VIEW_FILTER_MASK;
+ mask |= KS_EVENT_VIEW_FILTER_MASK;
+ data[i]->visible &= ~mask;
+ }
+ }
+}
+
static void kshark_set_entry_values(struct kshark_context *kshark_ctx,
struct pevent_record *record,
struct kshark_entry *entry)
@@ -224,6 +354,17 @@ size_t kshark_load_data_entries(struct kshark_context *kshark_ctx,
kshark_set_entry_values(kshark_ctx, rec, entry);
kshark_add_task(kshark_ctx, entry->pid);
+ if (!kshark_show_task(kshark_ctx, entry->pid)) {
+ entry->visible &= ~kshark_ctx->filter_mask;
+ }
+
+ if (!kshark_show_event(kshark_ctx, entry->event_id)) {
+ int mask = kshark_ctx->filter_mask;
+ mask &= ~KS_GRAPH_VIEW_FILTER_MASK;
+ mask |= KS_EVENT_VIEW_FILTER_MASK;
+ entry->visible &= ~mask;
+ }
+
entry->next = NULL;
next = &(entry->next);
free_record(rec);
diff --git a/kernel-shark-qt/src/libkshark.h b/kernel-shark-qt/src/libkshark.h
index d6e41bb..460c0c5 100644
--- a/kernel-shark-qt/src/libkshark.h
+++ b/kernel-shark-qt/src/libkshark.h
@@ -22,6 +22,7 @@ extern "C" {
// trace-cmd
#include "trace-cmd.h"
+// #include "trace-filter-hash.h"
#include "event-parse.h"
/**
@@ -82,6 +83,25 @@ struct kshark_context {
/** A mutex, used to protect the access to the input file. */
pthread_mutex_t input_mutex;
+
+ /** Hash of tasks to filter on. */
+ struct tracecmd_filter_id *show_task_filter;
+
+ /** Hash of tasks to not display. */
+ struct tracecmd_filter_id *hide_task_filter;
+
+ /** Hash of events to filter on. */
+ struct tracecmd_filter_id *show_event_filter;
+
+ /** Hash of events to not display. */
+ struct tracecmd_filter_id *hide_event_filter;
+
+ /**
+ * Bit mask, controlling the visibility of the entries after filtering. If given
+ * bit is set here, all entries which are filtered-out will have this bit unset
+ * in their "visible" fields.
+ */
+ uint8_t filter_mask;
};
/**
@@ -150,6 +170,61 @@ void kshark_free(struct kshark_context *kshark_ctx);
*/
char* kshark_dump_entry(struct kshark_entry *entry);
+/** Bit masks used to control the visibility of the entry after filtering. */
+enum kshark_filter_masks {
+ /** Use this mask to check the visibility of the entry in the text view. */
+ KS_TEXT_VIEW_FILTER_MASK = (1 << 0),
+
+ /** Use this mask to check the visibility of the entry in the graph view. */
+ KS_GRAPH_VIEW_FILTER_MASK = (1 << 1),
+
+ /** Special mask used whene filtering events. */
+ KS_EVENT_VIEW_FILTER_MASK = (1 << 2),
+};
+
+/** Filter type identifier. */
+enum kshark_filter_type {
+ /** Identifier of the filter, used to specified the events to be shown. */
+ SHOW_EVENT_FILTER,
+
+ /** Identifier of the filter, used to specified the events to be filtered-out. */
+ HIDE_EVENT_FILTER,
+
+ /** Identifier of the filter, used to specified the tasks to be shown. */
+ SHOW_TASK_FILTER,
+
+ /** Identifier of the filter, used to specified the tasks to be filtered-out. */
+ HIDE_TASK_FILTER,
+};
+
+/**
+ * @brief Add an Id value to the filster specified by "filter_id".
+ * @param kshark_ctx: kshark_ctx: Input location for the session context pointer.
+ * @param filter_id: Identifier of the filter.
+ * @param id: Id value to be added to the filter.
+ */
+void kshark_filter_add_id(struct kshark_context *kshark_ctx, int filter_id, int id);
+
+/**
+ * @brief Clear (reset) the filster specified by "filter_id".
+ * @param kshark_ctx: kshark_ctx: Input location for the session context pointer.
+ * @param filter_id: Identifier of the filter.
+ */
+void kshark_filter_clear(struct kshark_context *kshark_ctx, int filter_id);
+
+/**
+ * @brief This function loops over the array of entries specified by "data" and "n_entries"
+ * and sets the "visible" fields of each entry according to the criteria provided by the
+ * filters of the session's context. The field "filter_mask" of the session's context is
+ * used to control the level of visibility/invisibility of the entries which are filtered-out.
+ * @param kshark_ctx: kshark_ctx: Input location for the session context pointer.
+ * @param data: Input location for the trace data to be filtered.
+ * @param n_entries: The size of the inputted data.
+ */
+void kshark_filter_entries(struct kshark_context *kshark_ctx,
+ struct kshark_entry **data,
+ size_t n_entries);
+
#ifdef __cplusplus
}
#endif
--
2.17.1
next prev parent reply other threads:[~2018-06-25 15:02 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-25 15:01 [PATCH 0/7] Introduce the very basic part of the C API of KS-1.0 Yordan Karadzhov (VMware)
2018-06-25 15:01 ` [PATCH 1/7] kernel-shark-qt: Add Cmake build system for the Qt based KernelShark Yordan Karadzhov (VMware)
2018-06-25 16:06 ` Steven Rostedt
2018-06-26 14:23 ` Yordan Karadzhov (VMware)
2018-06-25 15:01 ` [PATCH 3/7] kernel-shark-qt: Add API for loading trace.dat files Yordan Karadzhov (VMware)
2018-06-25 18:30 ` Steven Rostedt
2018-06-26 14:47 ` Yordan Karadzhov (VMware)
2018-06-26 15:16 ` Steven Rostedt
2018-06-26 15:26 ` Yordan Karadzhov (VMware)
2018-06-25 15:01 ` [PATCH 4/7] kernel-shark-qt: Add an example showing how to load trace data Yordan Karadzhov (VMware)
2018-06-25 18:34 ` Steven Rostedt
2018-06-25 15:01 ` [PATCH 5/7] kernel-shark-qt: Add a README file to trace-cmd/kernel-shark-qt Yordan Karadzhov (VMware)
2018-06-25 18:38 ` Steven Rostedt
2018-06-26 14:51 ` Yordan Karadzhov (VMware)
2018-06-26 15:18 ` Steven Rostedt
2018-06-25 15:01 ` Yordan Karadzhov (VMware) [this message]
2018-06-25 19:07 ` [PATCH 6/7] kernel-shark-qt: Add filtering to the C API of KernelShark Steven Rostedt
2018-06-25 15:01 ` [PATCH 7/7] kernel-shark-qt: Add an example showing how to filter trace data Yordan Karadzhov (VMware)
[not found] ` <20180625150121.14291-3-y.karadz@gmail.com>
2018-06-25 16:09 ` [PATCH 2/7] kernel-shark-qt: Automatic generation of doxygen documentation Steven Rostedt
2018-06-26 14:29 ` Yordan Karadzhov (VMware)
2018-06-26 15:00 ` Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180625150121.14291-7-y.karadz@gmail.com \
--to=y.karadz@gmail.com \
--cc=linux-trace-devel@vger.kernel.org \
--cc=rostedt@goodmis.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.