[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1249111408-8657-6-git-send-email-fweisbec@gmail.com>
Date: Sat, 1 Aug 2009 09:23:28 +0200
From: Frederic Weisbecker <fweisbec@...il.com>
To: Ingo Molnar <mingo@...e.hu>
Cc: LKML <linux-kernel@...r.kernel.org>,
Frederic Weisbecker <fweisbec@...il.com>,
Steven Rostedt <rostedt@...dmis.org>,
Li Zefan <lizf@...fujitsu.com>,
Lai Jiangshan <laijs@...fujitsu.com>,
Tom Zanussi <tzanussi@...il.com>,
Thomas Gleixner <tglx@...utronix.de>,
Peter Zijlstra <peterz@...radead.org>
Subject: [RFC][PATCH 5/5] tracing/filters: Provide support for char * pointers
Provide support for char * pointers in the filtering framework.
Usually, char * entries are dangerous in traces because the string
can be released whereas a pointer to it can still wait to be read from
the ring buffer. But sometimes we can assume it's safe, like in case
of RO data (eg: __file__ or __line__, used in bkl trace event). If
these RO data are in a module and so is the call to the trace event,
then it's safe, because the ring buffer will be flushed once this
module get unloaded.
Now the bkl events becomes more useful. Say that you want to trace
only the bkl use in reiserfs:
cd /debug/tracing/events/bkl/lock_kernel
echo "file == fs/reiserfs*" > filter_regex
cat /debug/tracing/trace
syslogd-3658 [001] 1874.661878: lock_kernel: depth: 1, fs/reiserfs/super.c:563 reiserfs_dirty_inode()
syslogd-3658 [001] 1874.662266: lock_kernel: depth: 0, fs/reiserfs/inode.c:2695 reiserfs_write_end()
syslogd-3658 [001] 1874.662268: lock_kernel: depth: 1, fs/reiserfs/super.c:563 reiserfs_dirty_inode()
syslogd-3658 [001] 1874.662291: lock_kernel: depth: 0, fs/reiserfs/inode.c:2695 reiserfs_write_end()
Signed-off-by: Frederic Weisbecker <fweisbec@...il.com>
Cc: Tom Zanussi <tzanussi@...il.com>
Cc: Steven Rostedt <rostedt@...dmis.org>
---
kernel/trace/trace_events_filter.c | 34 +++++++++++++++++++++++++++++-----
1 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 51b4e24..071c93e 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -160,6 +160,20 @@ static int filter_pred_string(struct filter_pred *pred, void *event,
return match;
}
+/* Filter predicate for char * pointers */
+static int filter_pred_pchar(struct filter_pred *pred, void *event,
+ int val1, int val2)
+{
+ char **addr = (char **)(event + pred->offset);
+ int cmp, match;
+
+ cmp = pred->regex.match(*addr, &pred->regex);
+
+ match = (!!cmp) ^ pred->not;
+
+ return match;
+}
+
/*
* Filter predicate for dynamic sized arrays of characters.
* These are implemented through a list of strings at the end
@@ -547,6 +561,7 @@ static int filter_add_pred_fn(struct filter_parse_state *ps,
enum {
FILTER_STATIC_STRING = 1,
FILTER_DYN_STRING,
+ FILTER_PTR_STRING
};
static int is_string_field(const char *type)
@@ -557,6 +572,9 @@ static int is_string_field(const char *type)
if (strchr(type, '[') && strstr(type, "char"))
return FILTER_STATIC_STRING;
+ if (strstr(type, "char *"))
+ return FILTER_PTR_STRING;
+
return 0;
}
@@ -646,12 +664,18 @@ static int filter_add_pred(struct filter_parse_state *ps,
string_type = is_string_field(field->type);
if (string_type) {
- if (string_type == FILTER_DYN_STRING)
- fn = filter_pred_strloc;
- else
- fn = filter_pred_string;
+ if (string_type == FILTER_PTR_STRING) {
+ fn = filter_pred_pchar;
+ pred->regex.len = strlen(pred->regex.pattern);
+ } else {
+ pred->regex.len = field->size;
+
+ if (string_type == FILTER_DYN_STRING)
+ fn = filter_pred_strloc;
+ else
+ fn = filter_pred_string;
+ }
- pred->regex.len = field->size;
if (pred->op == OP_NE)
pred->not = 1;
--
1.6.2.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists