* [PATCH v2 0/3] tracing/filters: Support specifying filter hook to a TRACE_EVENT field
@ 2009-08-07 2:32 Li Zefan
2009-08-07 2:33 ` [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field Li Zefan
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Li Zefan @ 2009-08-07 2:32 UTC (permalink / raw)
To: Steven Rostedt, Frederic Weisbecker; +Cc: Ingo Molnar, LKML, Tom Zanussi
v2: no big changes, but addressed Steven's comments
Currently only static strings and dynamic strings have their
own filter functions, other types of field are treated as
integers.
This patchset allows assigning a specific filter type to a
field, so a field which is defined as:
__field_ext(const char *, str, FILTER_PTR_STR)
will be treated as a string but not a plain pointer, and then
we can set the filter like this:
# echo 'str == foo' > filter
And it's easy to add more filter functions for different types
to turn these into valid operations:
(dev is of type dev_t)
# echo 'dev == 8:0' > filter
(callsite is of type void * or unsigned long)
# echo 'callsite == skb_free' > filter
[PATCH 1/3] tracing/filters: Add filter_type to struct ftrace_event_field
[PATCH 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT
[PATCH 3/3] tracing/filters: Support filtering for char * strings
---
include/linux/ftrace_event.h | 12 +++++++-
include/trace/ftrace.h | 31 ++++++++++++++++++-----
kernel/trace/trace.h | 2 +
kernel/trace/trace_events.c | 9 ++++++-
kernel/trace/trace_events_filter.c | 47 +++++++++++++++++++++++++----------
kernel/trace/trace_export.c | 8 ++++--
6 files changed, 82 insertions(+), 27 deletions(-)
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field 2009-08-07 2:32 [PATCH v2 0/3] tracing/filters: Support specifying filter hook to a TRACE_EVENT field Li Zefan @ 2009-08-07 2:33 ` Li Zefan 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 2009-08-07 2:33 ` [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT Li Zefan 2009-08-07 2:33 ` [PATCH v2 3/3] tracing/filters: Support filtering for char * strings Li Zefan 2 siblings, 1 reply; 10+ messages in thread From: Li Zefan @ 2009-08-07 2:33 UTC (permalink / raw) To: Steven Rostedt, Frederic Weisbecker; +Cc: Ingo Molnar, LKML, Tom Zanussi 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> --- kernel/trace/trace.h | 2 ++ kernel/trace/trace_events.c | 2 ++ kernel/trace/trace_events_filter.c | 23 ++++++++++++++--------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 87b004f..3482540 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -783,6 +783,7 @@ struct ftrace_event_field { struct list_head link; char *name; char *type; + int filter_type; int offset; int size; int is_signed; @@ -828,6 +829,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, diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index e0cbede..cbc5e31 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -44,9 +44,11 @@ int trace_define_field(struct ftrace_event_call *call, 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; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 27c2dbe..cc66f1c 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -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; -- 1.6.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing/filters: Add filter_type to struct ftrace_event_field 2009-08-07 2:33 ` [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field Li Zefan @ 2009-08-26 7:23 ` tip-bot for Li Zefan 0 siblings, 0 replies; 10+ messages in thread From: tip-bot for Li Zefan @ 2009-08-26 7:23 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, lizf, tglx Commit-ID: aa38e9fc3ea804290efd3a39316d7f7e6c945800 Gitweb: http://git.kernel.org/tip/aa38e9fc3ea804290efd3a39316d7f7e6c945800 Author: Li Zefan <lizf@cn.fujitsu.com> AuthorDate: Fri, 7 Aug 2009 10:33:02 +0800 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Wed, 26 Aug 2009 00:32:06 -0400 tracing/filters: Add filter_type to struct ftrace_event_field 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 | 2 ++ kernel/trace/trace_events.c | 2 ++ kernel/trace/trace_events_filter.c | 23 ++++++++++++++--------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 300ef78..64dda57 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -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, diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 79d3520..5740e90 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -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; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 490337a..22e6d82 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -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; ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT 2009-08-07 2:32 [PATCH v2 0/3] tracing/filters: Support specifying filter hook to a TRACE_EVENT field Li Zefan 2009-08-07 2:33 ` [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field Li Zefan @ 2009-08-07 2:33 ` Li Zefan 2009-08-07 2:43 ` Steven Rostedt 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 2009-08-07 2:33 ` [PATCH v2 3/3] tracing/filters: Support filtering for char * strings Li Zefan 2 siblings, 2 replies; 10+ messages in thread From: Li Zefan @ 2009-08-07 2:33 UTC (permalink / raw) To: Steven Rostedt, Frederic Weisbecker; +Cc: Ingo Molnar, LKML, Tom Zanussi Add __field_ext(), so a field can be assigned to a specific filter_type, which matches a corresponding filter function. For example, a later patch will allow this: __field_ext(const char *, str, FILTER_PTR_STR); Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> --- include/linux/ftrace_event.h | 11 +++++++++-- include/trace/ftrace.h | 31 ++++++++++++++++++++++++------- kernel/trace/trace_events.c | 9 +++++++-- kernel/trace/trace_events_filter.c | 6 ------ kernel/trace/trace_export.c | 8 +++++--- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index c04e6d9..f034e8f 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -136,8 +136,15 @@ extern int filter_current_check_discard(struct ftrace_event_call *call, void *rec, struct ring_buffer_event *event); +enum { + FILTER_OTHER = 0, + FILTER_STATIC_STRING, + FILTER_DYN_STRING, +}; + extern int trace_define_field(struct ftrace_event_call *call, char *type, - char *name, int offset, int size, int is_signed); + char *name, int offset, int size, + int is_signed, int filter_type); #define is_signed_type(type) (((type)(-1)) < 0) @@ -165,7 +172,7 @@ do { \ #define __common_field(type, item, is_signed) \ ret = trace_define_field(event_call, #type, "common_" #item, \ offsetof(typeof(field.ent), item), \ - sizeof(field.ent.item), is_signed); \ + sizeof(field.ent.item), is_signed, -1);\ if (ret) \ return ret; diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 380b603..8fb7cc3 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -21,6 +21,9 @@ #undef __field #define __field(type, item) type item; +#undef __field_ext +#define __field_ext(type, item, filter_type) type item; + #undef __array #define __array(type, item, len) type item[len]; @@ -62,7 +65,10 @@ */ #undef __field -#define __field(type, item); +#define __field(type, item) + +#undef __field_ext +#define __field_ext(type, item, filter_type) #undef __array #define __array(type, item, len) @@ -110,6 +116,9 @@ if (!ret) \ return 0; +#undef __field_ext +#define __field_ext(type, item, filter_type) __field(type, item) + #undef __array #define __array(type, item, len) \ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ @@ -264,28 +273,33 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -#undef __field -#define __field(type, item) \ +#undef __field_ext +#define __field_ext(type, item, filter_type) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), filter_type); \ if (ret) \ return ret; +#undef __field +#define __field(type, item) __field_ext(type, item, FILTER_OTHER) + #undef __array #define __array(type, item, len) \ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret; #undef __dynamic_array #define __dynamic_array(type, item, len) \ ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ - offsetof(typeof(field), __data_loc_##item), \ - sizeof(field.__data_loc_##item), 0); + offsetof(typeof(field), __data_loc_##item), \ + sizeof(field.__data_loc_##item), 0, \ + FILTER_OTHER); #undef __string #define __string(item, src) __dynamic_array(char, item, -1) @@ -322,6 +336,9 @@ ftrace_define_fields_##call(void) \ #undef __field #define __field(type, item) +#undef __field_ext +#define __field_ext(type, item, filter_type) + #undef __array #define __array(type, item, len) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index cbc5e31..841226a 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -28,7 +28,8 @@ DEFINE_MUTEX(event_mutex); LIST_HEAD(ftrace_events); int trace_define_field(struct ftrace_event_call *call, char *type, - char *name, int offset, int size, int is_signed) + char *name, int offset, int size, + int is_signed, int filter_type) { struct ftrace_event_field *field; @@ -44,7 +45,11 @@ int trace_define_field(struct ftrace_event_call *call, char *type, if (!field->type) goto err; - field->filter_type = filter_assign_type(type); + if (filter_type == FILTER_OTHER) + field->filter_type = filter_assign_type(type); + else + field->filter_type = filter_type; + field->offset = offset; field->size = size; field->is_signed = is_signed; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index cc66f1c..5e7f031 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -475,12 +475,6 @@ static int filter_add_pred_fn(struct filter_parse_state *ps, return 0; } -enum { - FILTER_OTHER = 0, - FILTER_STATIC_STRING, - FILTER_DYN_STRING, -}; - int filter_assign_type(const char *type) { if (strstr(type, "__data_loc") && strstr(type, "char")) diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index d06cf89..bce9306 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -156,7 +156,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD(type, item, assign) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; @@ -164,7 +165,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret; @@ -172,7 +173,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed); \ + sizeof(field.item), is_signed, \ + FILTER_OTHER); \ if (ret) \ return ret; -- 1.6.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT 2009-08-07 2:33 ` [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT Li Zefan @ 2009-08-07 2:43 ` Steven Rostedt 2009-08-07 2:45 ` Li Zefan 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 1 sibling, 1 reply; 10+ messages in thread From: Steven Rostedt @ 2009-08-07 2:43 UTC (permalink / raw) To: Li Zefan; +Cc: Frederic Weisbecker, Ingo Molnar, LKML, Tom Zanussi Hi Li, Thanks for the updates ... On Fri, 7 Aug 2009, Li Zefan wrote: > Add __field_ext(), so a field can be assigned to a specific > filter_type, which matches a corresponding filter function. > > For example, a later patch will allow this: > __field_ext(const char *, str, FILTER_PTR_STR); > > Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> > --- > include/linux/ftrace_event.h | 11 +++++++++-- > include/trace/ftrace.h | 31 ++++++++++++++++++++++++------- > kernel/trace/trace_events.c | 9 +++++++-- > kernel/trace/trace_events_filter.c | 6 ------ > kernel/trace/trace_export.c | 8 +++++--- > 5 files changed, 45 insertions(+), 20 deletions(-) > > diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h > index c04e6d9..f034e8f 100644 > --- a/include/linux/ftrace_event.h > +++ b/include/linux/ftrace_event.h > @@ -136,8 +136,15 @@ extern int filter_current_check_discard(struct ftrace_event_call *call, > void *rec, > struct ring_buffer_event *event); > > +enum { > + FILTER_OTHER = 0, > + FILTER_STATIC_STRING, > + FILTER_DYN_STRING, > +}; > + > extern int trace_define_field(struct ftrace_event_call *call, char *type, > - char *name, int offset, int size, int is_signed); > + char *name, int offset, int size, > + int is_signed, int filter_type); > > #define is_signed_type(type) (((type)(-1)) < 0) > > @@ -165,7 +172,7 @@ do { \ > #define __common_field(type, item, is_signed) \ > ret = trace_define_field(event_call, #type, "common_" #item, \ > offsetof(typeof(field.ent), item), \ > - sizeof(field.ent.item), is_signed); \ > + sizeof(field.ent.item), is_signed, -1);\ I think this wants to be FILTER_OTHER? -- Steve > if (ret) \ > return ret; > > diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h > index 380b603..8fb7cc3 100644 > --- a/include/trace/ftrace.h > +++ b/include/trace/ftrace.h > @@ -21,6 +21,9 @@ > #undef __field > #define __field(type, item) type item; > > +#undef __field_ext > +#define __field_ext(type, item, filter_type) type item; > + > #undef __array > #define __array(type, item, len) type item[len]; > > @@ -62,7 +65,10 @@ > */ > > #undef __field > -#define __field(type, item); > +#define __field(type, item) > + > +#undef __field_ext > +#define __field_ext(type, item, filter_type) > > #undef __array > #define __array(type, item, len) > @@ -110,6 +116,9 @@ > if (!ret) \ > return 0; > > +#undef __field_ext > +#define __field_ext(type, item, filter_type) __field(type, item) > + > #undef __array > #define __array(type, item, len) \ > ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ > @@ -264,28 +273,33 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ > > #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) > > -#undef __field > -#define __field(type, item) \ > +#undef __field_ext > +#define __field_ext(type, item, filter_type) \ > ret = trace_define_field(event_call, #type, #item, \ > offsetof(typeof(field), item), \ > - sizeof(field.item), is_signed_type(type)); \ > + sizeof(field.item), \ > + is_signed_type(type), filter_type); \ > if (ret) \ > return ret; > > +#undef __field > +#define __field(type, item) __field_ext(type, item, FILTER_OTHER) > + > #undef __array > #define __array(type, item, len) \ > BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ > ret = trace_define_field(event_call, #type "[" #len "]", #item, \ > offsetof(typeof(field), item), \ > - sizeof(field.item), 0); \ > + sizeof(field.item), 0, FILTER_OTHER); \ > if (ret) \ > return ret; > > #undef __dynamic_array > #define __dynamic_array(type, item, len) \ > ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ > - offsetof(typeof(field), __data_loc_##item), \ > - sizeof(field.__data_loc_##item), 0); > + offsetof(typeof(field), __data_loc_##item), \ > + sizeof(field.__data_loc_##item), 0, \ > + FILTER_OTHER); > > #undef __string > #define __string(item, src) __dynamic_array(char, item, -1) > @@ -322,6 +336,9 @@ ftrace_define_fields_##call(void) \ > #undef __field > #define __field(type, item) > > +#undef __field_ext > +#define __field_ext(type, item, filter_type) > + > #undef __array > #define __array(type, item, len) > > diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c > index cbc5e31..841226a 100644 > --- a/kernel/trace/trace_events.c > +++ b/kernel/trace/trace_events.c > @@ -28,7 +28,8 @@ DEFINE_MUTEX(event_mutex); > LIST_HEAD(ftrace_events); > > int trace_define_field(struct ftrace_event_call *call, char *type, > - char *name, int offset, int size, int is_signed) > + char *name, int offset, int size, > + int is_signed, int filter_type) > { > struct ftrace_event_field *field; > > @@ -44,7 +45,11 @@ int trace_define_field(struct ftrace_event_call *call, char *type, > if (!field->type) > goto err; > > - field->filter_type = filter_assign_type(type); > + if (filter_type == FILTER_OTHER) > + field->filter_type = filter_assign_type(type); > + else > + field->filter_type = filter_type; > + > field->offset = offset; > field->size = size; > field->is_signed = is_signed; > diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c > index cc66f1c..5e7f031 100644 > --- a/kernel/trace/trace_events_filter.c > +++ b/kernel/trace/trace_events_filter.c > @@ -475,12 +475,6 @@ static int filter_add_pred_fn(struct filter_parse_state *ps, > return 0; > } > > -enum { > - FILTER_OTHER = 0, > - FILTER_STATIC_STRING, > - FILTER_DYN_STRING, > -}; > - > int filter_assign_type(const char *type) > { > if (strstr(type, "__data_loc") && strstr(type, "char")) > diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c > index d06cf89..bce9306 100644 > --- a/kernel/trace/trace_export.c > +++ b/kernel/trace/trace_export.c > @@ -156,7 +156,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > #define TRACE_FIELD(type, item, assign) \ > ret = trace_define_field(event_call, #type, #item, \ > offsetof(typeof(field), item), \ > - sizeof(field.item), is_signed_type(type)); \ > + sizeof(field.item), \ > + is_signed_type(type), FILTER_OTHER); \ > if (ret) \ > return ret; > > @@ -164,7 +165,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ > ret = trace_define_field(event_call, #type "[" #len "]", #item, \ > offsetof(typeof(field), item), \ > - sizeof(field.item), 0); \ > + sizeof(field.item), 0, FILTER_OTHER); \ > if (ret) \ > return ret; > > @@ -172,7 +173,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ > #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ > ret = trace_define_field(event_call, #type, #item, \ > offsetof(typeof(field), item), \ > - sizeof(field.item), is_signed); \ > + sizeof(field.item), is_signed, \ > + FILTER_OTHER); \ > if (ret) \ > return ret; > > -- > 1.6.3 > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT 2009-08-07 2:43 ` Steven Rostedt @ 2009-08-07 2:45 ` Li Zefan 2009-08-07 2:51 ` Steven Rostedt 0 siblings, 1 reply; 10+ messages in thread From: Li Zefan @ 2009-08-07 2:45 UTC (permalink / raw) To: Steven Rostedt; +Cc: Frederic Weisbecker, Ingo Molnar, LKML, Tom Zanussi >> #define is_signed_type(type) (((type)(-1)) < 0) >> >> @@ -165,7 +172,7 @@ do { \ >> #define __common_field(type, item, is_signed) \ >> ret = trace_define_field(event_call, #type, "common_" #item, \ >> offsetof(typeof(field.ent), item), \ >> - sizeof(field.ent.item), is_signed); \ >> + sizeof(field.ent.item), is_signed, -1);\ > > I think this wants to be FILTER_OTHER? > oops.. I thought I had changed all -1 to FILTER_OTHER.. I guess you're going to fix this manually? ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT 2009-08-07 2:45 ` Li Zefan @ 2009-08-07 2:51 ` Steven Rostedt 0 siblings, 0 replies; 10+ messages in thread From: Steven Rostedt @ 2009-08-07 2:51 UTC (permalink / raw) To: Li Zefan; +Cc: Frederic Weisbecker, Ingo Molnar, LKML, Tom Zanussi On Fri, 7 Aug 2009, Li Zefan wrote: > >> #define is_signed_type(type) (((type)(-1)) < 0) > >> > >> @@ -165,7 +172,7 @@ do { \ > >> #define __common_field(type, item, is_signed) \ > >> ret = trace_define_field(event_call, #type, "common_" #item, \ > >> offsetof(typeof(field.ent), item), \ > >> - sizeof(field.ent.item), is_signed); \ > >> + sizeof(field.ent.item), is_signed, -1);\ > > > > I think this wants to be FILTER_OTHER? > > > > oops.. I thought I had changed all -1 to FILTER_OTHER.. > > I guess you're going to fix this manually? Yeah, I can make that change. Thanks! -- Steve ^ permalink raw reply [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing/filters: Add __field_ext() to TRACE_EVENT 2009-08-07 2:33 ` [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT Li Zefan 2009-08-07 2:43 ` Steven Rostedt @ 2009-08-26 7:23 ` tip-bot for Li Zefan 1 sibling, 0 replies; 10+ messages in thread From: tip-bot for Li Zefan @ 2009-08-26 7:23 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, lizf, tglx Commit-ID: 43b51ead3f752a3935116e5b1a94254b8573734f Gitweb: http://git.kernel.org/tip/43b51ead3f752a3935116e5b1a94254b8573734f Author: Li Zefan <lizf@cn.fujitsu.com> AuthorDate: Fri, 7 Aug 2009 10:33:22 +0800 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Wed, 26 Aug 2009 00:32:06 -0400 tracing/filters: Add __field_ext() to TRACE_EVENT Add __field_ext(), so a field can be assigned to a specific filter_type, which matches a corresponding filter function. For example, a later patch will allow this: __field_ext(const char *, str, FILTER_PTR_STR); Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> LKML-Reference: <4A7B9272.6050709@cn.fujitsu.com> [ Fixed a -1 to FILTER_OTHER Forward ported to latest kernel. ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/linux/ftrace_event.h | 9 ++++++++- include/trace/ftrace.h | 31 ++++++++++++++++++++++++------- kernel/trace/trace_events.c | 11 ++++++++--- kernel/trace/trace_events_filter.c | 6 ------ kernel/trace/trace_export.c | 8 +++++--- kernel/trace/trace_syscalls.c | 6 ++++-- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index df5b085..0440bea 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -140,9 +140,16 @@ extern int filter_current_check_discard(struct ftrace_event_call *call, void *rec, struct ring_buffer_event *event); +enum { + FILTER_OTHER = 0, + FILTER_STATIC_STRING, + FILTER_DYN_STRING, +}; + extern int trace_define_field(struct ftrace_event_call *call, const char *type, const char *name, - int offset, int size, int is_signed); + int offset, int size, int is_signed, + int filter_type); extern int trace_define_common_fields(struct ftrace_event_call *call); #define is_signed_type(type) (((type)(-1)) < 0) diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 1274002..1b1f742 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -21,6 +21,9 @@ #undef __field #define __field(type, item) type item; +#undef __field_ext +#define __field_ext(type, item, filter_type) type item; + #undef __array #define __array(type, item, len) type item[len]; @@ -62,7 +65,10 @@ */ #undef __field -#define __field(type, item); +#define __field(type, item) + +#undef __field_ext +#define __field_ext(type, item, filter_type) #undef __array #define __array(type, item, len) @@ -110,6 +116,9 @@ if (!ret) \ return 0; +#undef __field_ext +#define __field_ext(type, item, filter_type) __field(type, item) + #undef __array #define __array(type, item, len) \ ret = trace_seq_printf(s, "\tfield:" #type " " #item "[" #len "];\t" \ @@ -265,28 +274,33 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) -#undef __field -#define __field(type, item) \ +#undef __field_ext +#define __field_ext(type, item, filter_type) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), filter_type); \ if (ret) \ return ret; +#undef __field +#define __field(type, item) __field_ext(type, item, FILTER_OTHER) + #undef __array #define __array(type, item, len) \ BUILD_BUG_ON(len > MAX_FILTER_STR_VAL); \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret; #undef __dynamic_array #define __dynamic_array(type, item, len) \ ret = trace_define_field(event_call, "__data_loc " #type "[]", #item, \ - offsetof(typeof(field), __data_loc_##item), \ - sizeof(field.__data_loc_##item), 0); + offsetof(typeof(field), __data_loc_##item), \ + sizeof(field.__data_loc_##item), 0, \ + FILTER_OTHER); #undef __string #define __string(item, src) __dynamic_array(char, item, -1) @@ -320,6 +334,9 @@ ftrace_define_fields_##call(struct ftrace_event_call *event_call) \ #undef __field #define __field(type, item) +#undef __field_ext +#define __field_ext(type, item, filter_type) + #undef __array #define __array(type, item, len) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 5740e90..d33bcde 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -28,7 +28,8 @@ DEFINE_MUTEX(event_mutex); LIST_HEAD(ftrace_events); int trace_define_field(struct ftrace_event_call *call, const char *type, - const char *name, int offset, int size, int is_signed) + const char *name, int offset, int size, int is_signed, + int filter_type) { struct ftrace_event_field *field; @@ -44,7 +45,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); + if (filter_type == FILTER_OTHER) + field->filter_type = filter_assign_type(type); + else + field->filter_type = filter_type; + field->offset = offset; field->size = size; field->is_signed = is_signed; @@ -68,7 +73,7 @@ EXPORT_SYMBOL_GPL(trace_define_field); ret = trace_define_field(call, #type, "common_" #item, \ offsetof(typeof(ent), item), \ sizeof(ent.item), \ - is_signed_type(type)); \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 22e6d82..8a8e576 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -475,12 +475,6 @@ static int filter_add_pred_fn(struct filter_parse_state *ps, return 0; } -enum { - FILTER_OTHER = 0, - FILTER_STATIC_STRING, - FILTER_DYN_STRING, -}; - int filter_assign_type(const char *type) { if (strstr(type, "__data_loc") && strstr(type, "char")) diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 7087530..029a91f 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c @@ -158,7 +158,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD(type, item, assign) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed_type(type)); \ + sizeof(field.item), \ + is_signed_type(type), FILTER_OTHER); \ if (ret) \ return ret; @@ -166,7 +167,7 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD_SPECIAL(type, item, len, cmd) \ ret = trace_define_field(event_call, #type "[" #len "]", #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), 0); \ + sizeof(field.item), 0, FILTER_OTHER); \ if (ret) \ return ret; @@ -174,7 +175,8 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ #define TRACE_FIELD_SIGN(type, item, assign, is_signed) \ ret = trace_define_field(event_call, #type, #item, \ offsetof(typeof(field), item), \ - sizeof(field.item), is_signed); \ + sizeof(field.item), is_signed, \ + FILTER_OTHER); \ if (ret) \ return ret; diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 46c1b97..97a2454 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -194,7 +194,8 @@ int syscall_enter_define_fields(struct ftrace_event_call *call) for (i = 0; i < meta->nb_args; i++) { ret = trace_define_field(call, meta->types[i], meta->args[i], offset, - sizeof(unsigned long), 0); + sizeof(unsigned long), 0, + FILTER_OTHER); offset += sizeof(unsigned long); } @@ -210,7 +211,8 @@ int syscall_exit_define_fields(struct ftrace_event_call *call) if (ret) return ret; - ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0); + ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0, + FILTER_OTHER); return ret; } ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/3] tracing/filters: Support filtering for char * strings 2009-08-07 2:32 [PATCH v2 0/3] tracing/filters: Support specifying filter hook to a TRACE_EVENT field Li Zefan 2009-08-07 2:33 ` [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field Li Zefan 2009-08-07 2:33 ` [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT Li Zefan @ 2009-08-07 2:33 ` Li Zefan 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 2 siblings, 1 reply; 10+ messages in thread From: Li Zefan @ 2009-08-07 2:33 UTC (permalink / raw) To: Steven Rostedt, Frederic Weisbecker; +Cc: Ingo Molnar, LKML, Tom Zanussi 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. To allow char * to be treated as a string: TRACE_EVENT(..., TP_STRUCT__entry( __field_ext(const char *, name, FILTER_PTR_STRING) ... ) ... ); Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> --- include/linux/ftrace_event.h | 1 + kernel/trace/trace_events_filter.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index f034e8f..fd5f329 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -140,6 +140,7 @@ enum { FILTER_OTHER = 0, FILTER_STATIC_STRING, FILTER_DYN_STRING, + FILTER_PTR_STRING, }; extern int trace_define_field(struct ftrace_event_call *call, char *type, diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 5e7f031..b16923e 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -163,6 +163,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 = strncmp(*addr, pred->str_val, pred->str_len); + + 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 @@ -489,7 +503,8 @@ int filter_assign_type(const char *type) static bool is_string_field(struct ftrace_event_field *field) { return field->filter_type == FILTER_DYN_STRING || - field->filter_type == FILTER_STATIC_STRING; + field->filter_type == FILTER_STATIC_STRING || + field->filter_type == FILTER_PTR_STRING; } static int is_legal_op(struct ftrace_event_field *field, int op) @@ -579,11 +594,16 @@ static int filter_add_pred(struct filter_parse_state *ps, } if (is_string_field(field)) { + pred->str_len = field->size; + if (field->filter_type == FILTER_STATIC_STRING) fn = filter_pred_string; - else + else if (field->filter_type == FILTER_DYN_STRING) fn = filter_pred_strloc; - pred->str_len = field->size; + else { + fn = filter_pred_pchar; + pred->str_len = strlen(pred->str_val); + } } else { if (field->is_signed) ret = strict_strtoll(pred->str_val, 0, &val); -- 1.6.3 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [tip:tracing/core] tracing/filters: Support filtering for char * strings 2009-08-07 2:33 ` [PATCH v2 3/3] tracing/filters: Support filtering for char * strings Li Zefan @ 2009-08-26 7:23 ` tip-bot for Li Zefan 0 siblings, 0 replies; 10+ messages in thread From: tip-bot for Li Zefan @ 2009-08-26 7:23 UTC (permalink / raw) To: linux-tip-commits; +Cc: linux-kernel, hpa, mingo, rostedt, lizf, tglx Commit-ID: 87a342f5db69d53ea70493bb1ec69c9047677038 Gitweb: http://git.kernel.org/tip/87a342f5db69d53ea70493bb1ec69c9047677038 Author: Li Zefan <lizf@cn.fujitsu.com> AuthorDate: Fri, 7 Aug 2009 10:33:43 +0800 Committer: Steven Rostedt <rostedt@goodmis.org> CommitDate: Wed, 26 Aug 2009 00:32:07 -0400 tracing/filters: Support filtering for char * strings 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. To allow char * to be treated as a string: TRACE_EVENT(..., TP_STRUCT__entry( __field_ext(const char *, name, FILTER_PTR_STRING) ... ) ... ); The filtering will not dereference "char *" unless the developer explicitly sets FILTER_PTR_STR in __field_ext. Signed-off-by: Li Zefan <lizf@cn.fujitsu.com> LKML-Reference: <4A7B9287.90205@cn.fujitsu.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> --- include/linux/ftrace_event.h | 1 + kernel/trace/trace_events_filter.c | 26 +++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 0440bea..ace2da9 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h @@ -144,6 +144,7 @@ enum { FILTER_OTHER = 0, FILTER_STATIC_STRING, FILTER_DYN_STRING, + FILTER_PTR_STRING, }; extern int trace_define_field(struct ftrace_event_call *call, diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 8a8e576..9f03082 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -163,6 +163,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 = strncmp(*addr, pred->str_val, pred->str_len); + + 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 @@ -489,7 +503,8 @@ int filter_assign_type(const char *type) static bool is_string_field(struct ftrace_event_field *field) { return field->filter_type == FILTER_DYN_STRING || - field->filter_type == FILTER_STATIC_STRING; + field->filter_type == FILTER_STATIC_STRING || + field->filter_type == FILTER_PTR_STRING; } static int is_legal_op(struct ftrace_event_field *field, int op) @@ -579,11 +594,16 @@ static int filter_add_pred(struct filter_parse_state *ps, } if (is_string_field(field)) { + pred->str_len = field->size; + if (field->filter_type == FILTER_STATIC_STRING) fn = filter_pred_string; - else + else if (field->filter_type == FILTER_DYN_STRING) fn = filter_pred_strloc; - pred->str_len = field->size; + else { + fn = filter_pred_pchar; + pred->str_len = strlen(pred->str_val); + } } else { if (field->is_signed) ret = strict_strtoll(pred->str_val, 0, &val); ^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-08-26 7:23 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-08-07 2:32 [PATCH v2 0/3] tracing/filters: Support specifying filter hook to a TRACE_EVENT field Li Zefan 2009-08-07 2:33 ` [PATCH v2 1/3] tracing/filters: Add filter_type to struct ftrace_event_field Li Zefan 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 2009-08-07 2:33 ` [PATCH v2 2/3] tracing/filters: Add __field_ext() to TRACE_EVENT Li Zefan 2009-08-07 2:43 ` Steven Rostedt 2009-08-07 2:45 ` Li Zefan 2009-08-07 2:51 ` Steven Rostedt 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan 2009-08-07 2:33 ` [PATCH v2 3/3] tracing/filters: Support filtering for char * strings Li Zefan 2009-08-26 7:23 ` [tip:tracing/core] " tip-bot for Li Zefan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox