diff options
| -rw-r--r-- | include/linux/ftrace_event.h | 1 | ||||
| -rw-r--r-- | include/linux/syscalls.h | 2 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 1 | ||||
| -rw-r--r-- | kernel/trace/trace_events_filter.c | 50 | ||||
| -rw-r--r-- | kernel/trace/trace_export.c | 1 |
5 files changed, 41 insertions, 14 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index ace2da9e0a0d..755480484eb6 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
| @@ -133,7 +133,6 @@ struct ftrace_event_call { | |||
| 133 | #define MAX_FILTER_PRED 32 | 133 | #define MAX_FILTER_PRED 32 |
| 134 | #define MAX_FILTER_STR_VAL 128 | 134 | #define MAX_FILTER_STR_VAL 128 |
| 135 | 135 | ||
| 136 | extern int init_preds(struct ftrace_event_call *call); | ||
| 137 | extern void destroy_preds(struct ftrace_event_call *call); | 136 | extern void destroy_preds(struct ftrace_event_call *call); |
| 138 | extern int filter_match_preds(struct ftrace_event_call *call, void *rec); | 137 | extern int filter_match_preds(struct ftrace_event_call *call, void *rec); |
| 139 | extern int filter_current_check_discard(struct ftrace_event_call *call, | 138 | extern int filter_current_check_discard(struct ftrace_event_call *call, |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index f124c8995555..a8e37821cc60 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -177,7 +177,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ | |||
| 177 | event_enter_##sname.id = id; \ | 177 | event_enter_##sname.id = id; \ |
| 178 | set_syscall_enter_id(num, id); \ | 178 | set_syscall_enter_id(num, id); \ |
| 179 | INIT_LIST_HEAD(&event_enter_##sname.fields); \ | 179 | INIT_LIST_HEAD(&event_enter_##sname.fields); \ |
| 180 | init_preds(&event_enter_##sname); \ | ||
| 181 | return 0; \ | 180 | return 0; \ |
| 182 | } \ | 181 | } \ |
| 183 | TRACE_SYS_ENTER_PROFILE(sname); \ | 182 | TRACE_SYS_ENTER_PROFILE(sname); \ |
| @@ -214,7 +213,6 @@ static void prof_sysexit_disable_##sname(struct ftrace_event_call *event_call) \ | |||
| 214 | event_exit_##sname.id = id; \ | 213 | event_exit_##sname.id = id; \ |
| 215 | set_syscall_exit_id(num, id); \ | 214 | set_syscall_exit_id(num, id); \ |
| 216 | INIT_LIST_HEAD(&event_exit_##sname.fields); \ | 215 | INIT_LIST_HEAD(&event_exit_##sname.fields); \ |
| 217 | init_preds(&event_exit_##sname); \ | ||
| 218 | return 0; \ | 216 | return 0; \ |
| 219 | } \ | 217 | } \ |
| 220 | TRACE_SYS_EXIT_PROFILE(sname); \ | 218 | TRACE_SYS_EXIT_PROFILE(sname); \ |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 57c56a998ee6..bfbc842600a1 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -622,7 +622,6 @@ static int ftrace_raw_init_event_##call(void) \ | |||
| 622 | return -ENODEV; \ | 622 | return -ENODEV; \ |
| 623 | event_##call.id = id; \ | 623 | event_##call.id = id; \ |
| 624 | INIT_LIST_HEAD(&event_##call.fields); \ | 624 | INIT_LIST_HEAD(&event_##call.fields); \ |
| 625 | init_preds(&event_##call); \ | ||
| 626 | return 0; \ | 625 | return 0; \ |
| 627 | } \ | 626 | } \ |
| 628 | \ | 627 | \ |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 9f03082c81d8..c6b2edfb7fe9 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
| @@ -309,7 +309,7 @@ void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s) | |||
| 309 | struct event_filter *filter = call->filter; | 309 | struct event_filter *filter = call->filter; |
| 310 | 310 | ||
| 311 | mutex_lock(&event_mutex); | 311 | mutex_lock(&event_mutex); |
| 312 | if (filter->filter_string) | 312 | if (filter && filter->filter_string) |
| 313 | trace_seq_printf(s, "%s\n", filter->filter_string); | 313 | trace_seq_printf(s, "%s\n", filter->filter_string); |
| 314 | else | 314 | else |
| 315 | trace_seq_printf(s, "none\n"); | 315 | trace_seq_printf(s, "none\n"); |
| @@ -322,7 +322,7 @@ void print_subsystem_event_filter(struct event_subsystem *system, | |||
| 322 | struct event_filter *filter = system->filter; | 322 | struct event_filter *filter = system->filter; |
| 323 | 323 | ||
| 324 | mutex_lock(&event_mutex); | 324 | mutex_lock(&event_mutex); |
| 325 | if (filter->filter_string) | 325 | if (filter && filter->filter_string) |
| 326 | trace_seq_printf(s, "%s\n", filter->filter_string); | 326 | trace_seq_printf(s, "%s\n", filter->filter_string); |
| 327 | else | 327 | else |
| 328 | trace_seq_printf(s, "none\n"); | 328 | trace_seq_printf(s, "none\n"); |
| @@ -390,6 +390,9 @@ void destroy_preds(struct ftrace_event_call *call) | |||
| 390 | struct event_filter *filter = call->filter; | 390 | struct event_filter *filter = call->filter; |
| 391 | int i; | 391 | int i; |
| 392 | 392 | ||
| 393 | if (!filter) | ||
| 394 | return; | ||
| 395 | |||
| 393 | for (i = 0; i < MAX_FILTER_PRED; i++) { | 396 | for (i = 0; i < MAX_FILTER_PRED; i++) { |
| 394 | if (filter->preds[i]) | 397 | if (filter->preds[i]) |
| 395 | filter_free_pred(filter->preds[i]); | 398 | filter_free_pred(filter->preds[i]); |
| @@ -400,7 +403,7 @@ void destroy_preds(struct ftrace_event_call *call) | |||
| 400 | call->filter = NULL; | 403 | call->filter = NULL; |
| 401 | } | 404 | } |
| 402 | 405 | ||
| 403 | int init_preds(struct ftrace_event_call *call) | 406 | static int init_preds(struct ftrace_event_call *call) |
| 404 | { | 407 | { |
| 405 | struct event_filter *filter; | 408 | struct event_filter *filter; |
| 406 | struct filter_pred *pred; | 409 | struct filter_pred *pred; |
| @@ -410,7 +413,6 @@ int init_preds(struct ftrace_event_call *call) | |||
| 410 | if (!call->filter) | 413 | if (!call->filter) |
| 411 | return -ENOMEM; | 414 | return -ENOMEM; |
| 412 | 415 | ||
| 413 | call->filter_active = 0; | ||
| 414 | filter->n_preds = 0; | 416 | filter->n_preds = 0; |
| 415 | 417 | ||
| 416 | filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL); | 418 | filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL); |
| @@ -432,7 +434,28 @@ oom: | |||
| 432 | 434 | ||
| 433 | return -ENOMEM; | 435 | return -ENOMEM; |
| 434 | } | 436 | } |
| 435 | EXPORT_SYMBOL_GPL(init_preds); | 437 | |
| 438 | static int init_subsystem_preds(struct event_subsystem *system) | ||
| 439 | { | ||
| 440 | struct ftrace_event_call *call; | ||
| 441 | int err; | ||
| 442 | |||
| 443 | list_for_each_entry(call, &ftrace_events, list) { | ||
| 444 | if (!call->define_fields) | ||
| 445 | continue; | ||
| 446 | |||
| 447 | if (strcmp(call->system, system->name) != 0) | ||
| 448 | continue; | ||
| 449 | |||
| 450 | if (!call->filter) { | ||
| 451 | err = init_preds(call); | ||
| 452 | if (err) | ||
| 453 | return err; | ||
| 454 | } | ||
| 455 | } | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 436 | 459 | ||
| 437 | enum { | 460 | enum { |
| 438 | FILTER_DISABLE_ALL, | 461 | FILTER_DISABLE_ALL, |
| @@ -449,6 +472,9 @@ static void filter_free_subsystem_preds(struct event_subsystem *system, | |||
| 449 | if (!call->define_fields) | 472 | if (!call->define_fields) |
| 450 | continue; | 473 | continue; |
| 451 | 474 | ||
| 475 | if (strcmp(call->system, system->name) != 0) | ||
| 476 | continue; | ||
| 477 | |||
| 452 | if (flag == FILTER_INIT_NO_RESET) { | 478 | if (flag == FILTER_INIT_NO_RESET) { |
| 453 | call->filter->no_reset = false; | 479 | call->filter->no_reset = false; |
| 454 | continue; | 480 | continue; |
| @@ -457,10 +483,8 @@ static void filter_free_subsystem_preds(struct event_subsystem *system, | |||
| 457 | if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset) | 483 | if (flag == FILTER_SKIP_NO_RESET && call->filter->no_reset) |
| 458 | continue; | 484 | continue; |
| 459 | 485 | ||
| 460 | if (!strcmp(call->system, system->name)) { | 486 | filter_disable_preds(call); |
| 461 | filter_disable_preds(call); | 487 | remove_filter_string(call->filter); |
| 462 | remove_filter_string(call->filter); | ||
| 463 | } | ||
| 464 | } | 488 | } |
| 465 | } | 489 | } |
| 466 | 490 | ||
| @@ -1094,6 +1118,10 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | |||
| 1094 | 1118 | ||
| 1095 | mutex_lock(&event_mutex); | 1119 | mutex_lock(&event_mutex); |
| 1096 | 1120 | ||
| 1121 | err = init_preds(call); | ||
| 1122 | if (err) | ||
| 1123 | goto out_unlock; | ||
| 1124 | |||
| 1097 | if (!strcmp(strstrip(filter_string), "0")) { | 1125 | if (!strcmp(strstrip(filter_string), "0")) { |
| 1098 | filter_disable_preds(call); | 1126 | filter_disable_preds(call); |
| 1099 | remove_filter_string(call->filter); | 1127 | remove_filter_string(call->filter); |
| @@ -1139,6 +1167,10 @@ int apply_subsystem_event_filter(struct event_subsystem *system, | |||
| 1139 | 1167 | ||
| 1140 | mutex_lock(&event_mutex); | 1168 | mutex_lock(&event_mutex); |
| 1141 | 1169 | ||
| 1170 | err = init_subsystem_preds(system); | ||
| 1171 | if (err) | ||
| 1172 | goto out_unlock; | ||
| 1173 | |||
| 1142 | if (!strcmp(strstrip(filter_string), "0")) { | 1174 | if (!strcmp(strstrip(filter_string), "0")) { |
| 1143 | filter_free_subsystem_preds(system, FILTER_DISABLE_ALL); | 1175 | filter_free_subsystem_preds(system, FILTER_DISABLE_ALL); |
| 1144 | remove_filter_string(system->filter); | 1176 | remove_filter_string(system->filter); |
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 029a91f42287..df1bf6e48bb9 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
| @@ -135,7 +135,6 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
| 135 | static int ftrace_raw_init_event_##call(void) \ | 135 | static int ftrace_raw_init_event_##call(void) \ |
| 136 | { \ | 136 | { \ |
| 137 | INIT_LIST_HEAD(&event_##call.fields); \ | 137 | INIT_LIST_HEAD(&event_##call.fields); \ |
| 138 | init_preds(&event_##call); \ | ||
| 139 | return 0; \ | 138 | return 0; \ |
| 140 | } \ | 139 | } \ |
| 141 | 140 | ||
