diff options
author | Frederic Weisbecker <fweisbec@gmail.com> | 2009-05-02 20:48:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-07 04:05:57 -0400 |
commit | e8808c1019b048a43686dbd25c188a035842c2e2 (patch) | |
tree | 350eefee96e540ee855a6aefc64a17af25486234 /kernel/trace | |
parent | 8ae79a138e88aceeeb07077bff2883245fb7c218 (diff) |
tracing/filters: support for filters of dynamic sized arrays
Currently the filtering infrastructure supports well the
numeric types and fixed sized array types.
But the recently added __string() field uses a specific
indirect offset mechanism which requires a specific
predicate. Until now it wasn't supported.
This patch adds this support and implies very few changes,
only a new predicate is needed, the management of this specific
field can be done through the usual string helpers in the
filtering infrastructure.
[ Impact: support all kinds of strings in the tracing filters ]
Cc: Tom Zanussi <tzanussi@gmail.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Li Zefan <lizf@cn.fujitsu.com>
Cc: Zhaolei <zhaolei@cn.fujitsu.com>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/trace_events_filter.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 7ac691085276..01c76eb3e168 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -151,6 +151,7 @@ static int filter_pred_or(struct filter_pred *pred __attribute((unused)), | |||
151 | return val1 || val2; | 151 | return val1 || val2; |
152 | } | 152 | } |
153 | 153 | ||
154 | /* Filter predicate for fixed sized arrays of characters */ | ||
154 | static int filter_pred_string(struct filter_pred *pred, void *event, | 155 | static int filter_pred_string(struct filter_pred *pred, void *event, |
155 | int val1, int val2) | 156 | int val1, int val2) |
156 | { | 157 | { |
@@ -164,6 +165,30 @@ static int filter_pred_string(struct filter_pred *pred, void *event, | |||
164 | return match; | 165 | return match; |
165 | } | 166 | } |
166 | 167 | ||
168 | /* | ||
169 | * Filter predicate for dynamic sized arrays of characters. | ||
170 | * These are implemented through a list of strings at the end | ||
171 | * of the entry. | ||
172 | * Also each of these strings have a field in the entry which | ||
173 | * contains its offset from the beginning of the entry. | ||
174 | * We have then first to get this field, dereference it | ||
175 | * and add it to the address of the entry, and at last we have | ||
176 | * the address of the string. | ||
177 | */ | ||
178 | static int filter_pred_strloc(struct filter_pred *pred, void *event, | ||
179 | int val1, int val2) | ||
180 | { | ||
181 | int str_loc = *(int *)(event + pred->offset); | ||
182 | char *addr = (char *)(event + str_loc); | ||
183 | int cmp, match; | ||
184 | |||
185 | cmp = strncmp(addr, pred->str_val, pred->str_len); | ||
186 | |||
187 | match = (!cmp) ^ pred->not; | ||
188 | |||
189 | return match; | ||
190 | } | ||
191 | |||
167 | static int filter_pred_none(struct filter_pred *pred, void *event, | 192 | static int filter_pred_none(struct filter_pred *pred, void *event, |
168 | int val1, int val2) | 193 | int val1, int val2) |
169 | { | 194 | { |
@@ -446,10 +471,18 @@ static int filter_add_pred_fn(struct filter_parse_state *ps, | |||
446 | return 0; | 471 | return 0; |
447 | } | 472 | } |
448 | 473 | ||
474 | enum { | ||
475 | FILTER_STATIC_STRING = 1, | ||
476 | FILTER_DYN_STRING | ||
477 | }; | ||
478 | |||
449 | static int is_string_field(const char *type) | 479 | static int is_string_field(const char *type) |
450 | { | 480 | { |
451 | if (strchr(type, '[') && strstr(type, "char")) | 481 | if (strchr(type, '[') && strstr(type, "char")) |
452 | return 1; | 482 | return FILTER_STATIC_STRING; |
483 | |||
484 | if (!strcmp(type, "__str_loc")) | ||
485 | return FILTER_DYN_STRING; | ||
453 | 486 | ||
454 | return 0; | 487 | return 0; |
455 | } | 488 | } |
@@ -512,6 +545,7 @@ static int filter_add_pred(struct filter_parse_state *ps, | |||
512 | struct ftrace_event_field *field; | 545 | struct ftrace_event_field *field; |
513 | filter_pred_fn_t fn; | 546 | filter_pred_fn_t fn; |
514 | unsigned long long val; | 547 | unsigned long long val; |
548 | int string_type; | ||
515 | 549 | ||
516 | pred->fn = filter_pred_none; | 550 | pred->fn = filter_pred_none; |
517 | 551 | ||
@@ -536,8 +570,12 @@ static int filter_add_pred(struct filter_parse_state *ps, | |||
536 | return -EINVAL; | 570 | return -EINVAL; |
537 | } | 571 | } |
538 | 572 | ||
539 | if (is_string_field(field->type)) { | 573 | string_type = is_string_field(field->type); |
540 | fn = filter_pred_string; | 574 | if (string_type) { |
575 | if (string_type == FILTER_STATIC_STRING) | ||
576 | fn = filter_pred_string; | ||
577 | else | ||
578 | fn = filter_pred_strloc; | ||
541 | pred->str_len = field->size; | 579 | pred->str_len = field->size; |
542 | if (pred->op == OP_NE) | 580 | if (pred->op == OP_NE) |
543 | pred->not = 1; | 581 | pred->not = 1; |