tracing/filters: Add filter_type to struct ftrace_event_field
authorLi Zefan <lizf@cn.fujitsu.com>
Fri, 7 Aug 2009 02:33:02 +0000 (10:33 +0800)
committerSteven Rostedt <rostedt@goodmis.org>
Wed, 26 Aug 2009 04:32:06 +0000 (00:32 -0400)
The type of a field is stored as a string in @type, and here
we add @filter_type which is an enum value.

This prepares for later patches, so we can specifically assign
different @filter_type for the same @type.

For example normally a "char *" field is treated as a ptr,
but we may want it to be treated as a string when doing filting.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
LKML-Reference: <4A7B925E.9030605@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
kernel/trace/trace.h
kernel/trace/trace_events.c
kernel/trace/trace_events_filter.c

index 300ef788c976fc8689bfd95f962c653d308f8748..64dda5709cb9019170bd5e9047a407f7eaf83bbe 100644 (file)
@@ -755,6 +755,7 @@ struct ftrace_event_field {
        struct list_head        link;
        char                    *name;
        char                    *type;
+       int                     filter_type;
        int                     offset;
        int                     size;
        int                     is_signed;
@@ -800,6 +801,7 @@ extern int apply_subsystem_event_filter(struct event_subsystem *system,
                                        char *filter_string);
 extern void print_subsystem_event_filter(struct event_subsystem *system,
                                         struct trace_seq *s);
+extern int filter_assign_type(const char *type);
 
 static inline int
 filter_check_discard(struct ftrace_event_call *call, void *rec,
index 79d352027a6194759c6477e64b5390b1a5da2822..5740e90f4ca11ae1aace7a759998da68431234ac 100644 (file)
@@ -44,9 +44,11 @@ int trace_define_field(struct ftrace_event_call *call, const char *type,
        if (!field->type)
                goto err;
 
+       field->filter_type = filter_assign_type(type);
        field->offset = offset;
        field->size = size;
        field->is_signed = is_signed;
+
        list_add(&field->link, &call->fields);
 
        return 0;
index 490337abed7592b563331c4a36d440c23de2338b..22e6d822bbaa4ba6a348cf265a5201ef8c387852 100644 (file)
@@ -476,11 +476,12 @@ static int filter_add_pred_fn(struct filter_parse_state *ps,
 }
 
 enum {
-       FILTER_STATIC_STRING = 1,
-       FILTER_DYN_STRING
+       FILTER_OTHER = 0,
+       FILTER_STATIC_STRING,
+       FILTER_DYN_STRING,
 };
 
-static int is_string_field(const char *type)
+int filter_assign_type(const char *type)
 {
        if (strstr(type, "__data_loc") && strstr(type, "char"))
                return FILTER_DYN_STRING;
@@ -488,12 +489,18 @@ static int is_string_field(const char *type)
        if (strchr(type, '[') && strstr(type, "char"))
                return FILTER_STATIC_STRING;
 
-       return 0;
+       return FILTER_OTHER;
+}
+
+static bool is_string_field(struct ftrace_event_field *field)
+{
+       return field->filter_type == FILTER_DYN_STRING ||
+              field->filter_type == FILTER_STATIC_STRING;
 }
 
 static int is_legal_op(struct ftrace_event_field *field, int op)
 {
-       if (is_string_field(field->type) && (op != OP_EQ && op != OP_NE))
+       if (is_string_field(field) && (op != OP_EQ && op != OP_NE))
                return 0;
 
        return 1;
@@ -550,7 +557,6 @@ static int filter_add_pred(struct filter_parse_state *ps,
        struct ftrace_event_field *field;
        filter_pred_fn_t fn;
        unsigned long long val;
-       int string_type;
        int ret;
 
        pred->fn = filter_pred_none;
@@ -578,9 +584,8 @@ static int filter_add_pred(struct filter_parse_state *ps,
                return -EINVAL;
        }
 
-       string_type = is_string_field(field->type);
-       if (string_type) {
-               if (string_type == FILTER_STATIC_STRING)
+       if (is_string_field(field)) {
+               if (field->filter_type == FILTER_STATIC_STRING)
                        fn = filter_pred_string;
                else
                        fn = filter_pred_strloc;