aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_events_filter.c12
-rw-r--r--kernel/trace/trace_events_trigger.c170
-rw-r--r--kernel/trace/trace_syscalls.c46
4 files changed, 219 insertions, 14 deletions
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index ccbd8104cf99..433bfc5dd576 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1,3 +1,4 @@
1
1#ifndef _LINUX_KERNEL_TRACE_H 2#ifndef _LINUX_KERNEL_TRACE_H
2#define _LINUX_KERNEL_TRACE_H 3#define _LINUX_KERNEL_TRACE_H
3 4
@@ -1020,6 +1021,10 @@ extern int apply_subsystem_event_filter(struct ftrace_subsystem_dir *dir,
1020extern void print_subsystem_event_filter(struct event_subsystem *system, 1021extern void print_subsystem_event_filter(struct event_subsystem *system,
1021 struct trace_seq *s); 1022 struct trace_seq *s);
1022extern int filter_assign_type(const char *type); 1023extern int filter_assign_type(const char *type);
1024extern int create_event_filter(struct ftrace_event_call *call,
1025 char *filter_str, bool set_str,
1026 struct event_filter **filterp);
1027extern void free_event_filter(struct event_filter *filter);
1023 1028
1024struct ftrace_event_field * 1029struct ftrace_event_field *
1025trace_find_event_field(struct ftrace_event_call *call, char *name); 1030trace_find_event_field(struct ftrace_event_call *call, char *name);
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 2468f56dc5db..8a8631926a07 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -799,6 +799,11 @@ static void __free_filter(struct event_filter *filter)
799 kfree(filter); 799 kfree(filter);
800} 800}
801 801
802void free_event_filter(struct event_filter *filter)
803{
804 __free_filter(filter);
805}
806
802void destroy_call_preds(struct ftrace_event_call *call) 807void destroy_call_preds(struct ftrace_event_call *call)
803{ 808{
804 __free_filter(call->filter); 809 __free_filter(call->filter);
@@ -1938,6 +1943,13 @@ static int create_filter(struct ftrace_event_call *call,
1938 return err; 1943 return err;
1939} 1944}
1940 1945
1946int create_event_filter(struct ftrace_event_call *call,
1947 char *filter_str, bool set_str,
1948 struct event_filter **filterp)
1949{
1950 return create_filter(call, filter_str, set_str, filterp);
1951}
1952
1941/** 1953/**
1942 * create_system_filter - create a filter for an event_subsystem 1954 * create_system_filter - create a filter for an event_subsystem
1943 * @system: event_subsystem to create a filter for 1955 * @system: event_subsystem to create a filter for
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index 45e48b109d51..f5b3f780fda4 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -31,6 +31,9 @@ static DEFINE_MUTEX(trigger_cmd_mutex);
31static void 31static void
32trigger_data_free(struct event_trigger_data *data) 32trigger_data_free(struct event_trigger_data *data)
33{ 33{
34 if (data->cmd_ops->set_filter)
35 data->cmd_ops->set_filter(NULL, data, NULL);
36
34 synchronize_sched(); /* make sure current triggers exit before free */ 37 synchronize_sched(); /* make sure current triggers exit before free */
35 kfree(data); 38 kfree(data);
36} 39}
@@ -38,27 +41,78 @@ trigger_data_free(struct event_trigger_data *data)
38/** 41/**
39 * event_triggers_call - Call triggers associated with a trace event 42 * event_triggers_call - Call triggers associated with a trace event
40 * @file: The ftrace_event_file associated with the event 43 * @file: The ftrace_event_file associated with the event
44 * @rec: The trace entry for the event, NULL for unconditional invocation
41 * 45 *
42 * For each trigger associated with an event, invoke the trigger 46 * For each trigger associated with an event, invoke the trigger
43 * function registered with the associated trigger command. 47 * function registered with the associated trigger command. If rec is
48 * non-NULL, it means that the trigger requires further processing and
49 * shouldn't be unconditionally invoked. If rec is non-NULL and the
50 * trigger has a filter associated with it, rec will checked against
51 * the filter and if the record matches the trigger will be invoked.
52 * If the trigger is a 'post_trigger', meaning it shouldn't be invoked
53 * in any case until the current event is written, the trigger
54 * function isn't invoked but the bit associated with the deferred
55 * trigger is set in the return value.
56 *
57 * Returns an enum event_trigger_type value containing a set bit for
58 * any trigger that should be deferred, ETT_NONE if nothing to defer.
44 * 59 *
45 * Called from tracepoint handlers (with rcu_read_lock_sched() held). 60 * Called from tracepoint handlers (with rcu_read_lock_sched() held).
46 * 61 *
47 * Return: an enum event_trigger_type value containing a set bit for 62 * Return: an enum event_trigger_type value containing a set bit for
48 * any trigger that should be deferred, ETT_NONE if nothing to defer. 63 * any trigger that should be deferred, ETT_NONE if nothing to defer.
49 */ 64 */
50void event_triggers_call(struct ftrace_event_file *file) 65enum event_trigger_type
66event_triggers_call(struct ftrace_event_file *file, void *rec)
51{ 67{
52 struct event_trigger_data *data; 68 struct event_trigger_data *data;
69 enum event_trigger_type tt = ETT_NONE;
53 70
54 if (list_empty(&file->triggers)) 71 if (list_empty(&file->triggers))
55 return; 72 return tt;
56 73
57 list_for_each_entry_rcu(data, &file->triggers, list) 74 list_for_each_entry_rcu(data, &file->triggers, list) {
75 if (!rec) {
76 data->ops->func(data);
77 continue;
78 }
79 if (data->filter && !filter_match_preds(data->filter, rec))
80 continue;
81 if (data->cmd_ops->post_trigger) {
82 tt |= data->cmd_ops->trigger_type;
83 continue;
84 }
58 data->ops->func(data); 85 data->ops->func(data);
86 }
87 return tt;
59} 88}
60EXPORT_SYMBOL_GPL(event_triggers_call); 89EXPORT_SYMBOL_GPL(event_triggers_call);
61 90
91/**
92 * event_triggers_post_call - Call 'post_triggers' for a trace event
93 * @file: The ftrace_event_file associated with the event
94 * @tt: enum event_trigger_type containing a set bit for each trigger to invoke
95 *
96 * For each trigger associated with an event, invoke the trigger
97 * function registered with the associated trigger command, if the
98 * corresponding bit is set in the tt enum passed into this function.
99 * See @event_triggers_call for details on how those bits are set.
100 *
101 * Called from tracepoint handlers (with rcu_read_lock_sched() held).
102 */
103void
104event_triggers_post_call(struct ftrace_event_file *file,
105 enum event_trigger_type tt)
106{
107 struct event_trigger_data *data;
108
109 list_for_each_entry_rcu(data, &file->triggers, list) {
110 if (data->cmd_ops->trigger_type & tt)
111 data->ops->func(data);
112 }
113}
114EXPORT_SYMBOL_GPL(event_triggers_post_call);
115
62static void *trigger_next(struct seq_file *m, void *t, loff_t *pos) 116static void *trigger_next(struct seq_file *m, void *t, loff_t *pos)
63{ 117{
64 struct ftrace_event_file *event_file = event_file_data(m->private); 118 struct ftrace_event_file *event_file = event_file_data(m->private);
@@ -403,6 +457,34 @@ clear_event_triggers(struct trace_array *tr)
403} 457}
404 458
405/** 459/**
460 * update_cond_flag - Set or reset the TRIGGER_COND bit
461 * @file: The ftrace_event_file associated with the event
462 *
463 * If an event has triggers and any of those triggers has a filter or
464 * a post_trigger, trigger invocation needs to be deferred until after
465 * the current event has logged its data, and the event should have
466 * its TRIGGER_COND bit set, otherwise the TRIGGER_COND bit should be
467 * cleared.
468 */
469static void update_cond_flag(struct ftrace_event_file *file)
470{
471 struct event_trigger_data *data;
472 bool set_cond = false;
473
474 list_for_each_entry_rcu(data, &file->triggers, list) {
475 if (data->filter || data->cmd_ops->post_trigger) {
476 set_cond = true;
477 break;
478 }
479 }
480
481 if (set_cond)
482 set_bit(FTRACE_EVENT_FL_TRIGGER_COND_BIT, &file->flags);
483 else
484 clear_bit(FTRACE_EVENT_FL_TRIGGER_COND_BIT, &file->flags);
485}
486
487/**
406 * register_trigger - Generic event_command @reg implementation 488 * register_trigger - Generic event_command @reg implementation
407 * @glob: The raw string used to register the trigger 489 * @glob: The raw string used to register the trigger
408 * @ops: The trigger ops associated with the trigger 490 * @ops: The trigger ops associated with the trigger
@@ -443,6 +525,7 @@ static int register_trigger(char *glob, struct event_trigger_ops *ops,
443 list_del_rcu(&data->list); 525 list_del_rcu(&data->list);
444 ret--; 526 ret--;
445 } 527 }
528 update_cond_flag(file);
446out: 529out:
447 return ret; 530 return ret;
448} 531}
@@ -470,6 +553,7 @@ static void unregister_trigger(char *glob, struct event_trigger_ops *ops,
470 if (data->cmd_ops->trigger_type == test->cmd_ops->trigger_type) { 553 if (data->cmd_ops->trigger_type == test->cmd_ops->trigger_type) {
471 unregistered = true; 554 unregistered = true;
472 list_del_rcu(&data->list); 555 list_del_rcu(&data->list);
556 update_cond_flag(file);
473 trace_event_trigger_enable_disable(file, 0); 557 trace_event_trigger_enable_disable(file, 0);
474 break; 558 break;
475 } 559 }
@@ -572,10 +656,78 @@ event_trigger_callback(struct event_command *cmd_ops,
572 return ret; 656 return ret;
573 657
574 out_free: 658 out_free:
659 if (cmd_ops->set_filter)
660 cmd_ops->set_filter(NULL, trigger_data, NULL);
575 kfree(trigger_data); 661 kfree(trigger_data);
576 goto out; 662 goto out;
577} 663}
578 664
665/**
666 * set_trigger_filter - Generic event_command @set_filter implementation
667 * @filter_str: The filter string for the trigger, NULL to remove filter
668 * @trigger_data: Trigger-specific data
669 * @file: The ftrace_event_file associated with the event
670 *
671 * Common implementation for event command filter parsing and filter
672 * instantiation.
673 *
674 * Usually used directly as the @set_filter method in event command
675 * implementations.
676 *
677 * Also used to remove a filter (if filter_str = NULL).
678 *
679 * Return: 0 on success, errno otherwise
680 */
681static int set_trigger_filter(char *filter_str,
682 struct event_trigger_data *trigger_data,
683 struct ftrace_event_file *file)
684{
685 struct event_trigger_data *data = trigger_data;
686 struct event_filter *filter = NULL, *tmp;
687 int ret = -EINVAL;
688 char *s;
689
690 if (!filter_str) /* clear the current filter */
691 goto assign;
692
693 s = strsep(&filter_str, " \t");
694
695 if (!strlen(s) || strcmp(s, "if") != 0)
696 goto out;
697
698 if (!filter_str)
699 goto out;
700
701 /* The filter is for the 'trigger' event, not the triggered event */
702 ret = create_event_filter(file->event_call, filter_str, false, &filter);
703 if (ret)
704 goto out;
705 assign:
706 tmp = data->filter;
707
708 rcu_assign_pointer(data->filter, filter);
709
710 if (tmp) {
711 /* Make sure the call is done with the filter */
712 synchronize_sched();
713 free_event_filter(tmp);
714 }
715
716 kfree(data->filter_str);
717 data->filter_str = NULL;
718
719 if (filter_str) {
720 data->filter_str = kstrdup(filter_str, GFP_KERNEL);
721 if (!data->filter_str) {
722 free_event_filter(data->filter);
723 data->filter = NULL;
724 ret = -ENOMEM;
725 }
726 }
727 out:
728 return ret;
729}
730
579static void 731static void
580traceon_trigger(struct event_trigger_data *data) 732traceon_trigger(struct event_trigger_data *data)
581{ 733{
@@ -685,6 +837,7 @@ static struct event_command trigger_traceon_cmd = {
685 .reg = register_trigger, 837 .reg = register_trigger,
686 .unreg = unregister_trigger, 838 .unreg = unregister_trigger,
687 .get_trigger_ops = onoff_get_trigger_ops, 839 .get_trigger_ops = onoff_get_trigger_ops,
840 .set_filter = set_trigger_filter,
688}; 841};
689 842
690static struct event_command trigger_traceoff_cmd = { 843static struct event_command trigger_traceoff_cmd = {
@@ -694,6 +847,7 @@ static struct event_command trigger_traceoff_cmd = {
694 .reg = register_trigger, 847 .reg = register_trigger,
695 .unreg = unregister_trigger, 848 .unreg = unregister_trigger,
696 .get_trigger_ops = onoff_get_trigger_ops, 849 .get_trigger_ops = onoff_get_trigger_ops,
850 .set_filter = set_trigger_filter,
697}; 851};
698 852
699#ifdef CONFIG_TRACER_SNAPSHOT 853#ifdef CONFIG_TRACER_SNAPSHOT
@@ -765,6 +919,7 @@ static struct event_command trigger_snapshot_cmd = {
765 .reg = register_snapshot_trigger, 919 .reg = register_snapshot_trigger,
766 .unreg = unregister_trigger, 920 .unreg = unregister_trigger,
767 .get_trigger_ops = snapshot_get_trigger_ops, 921 .get_trigger_ops = snapshot_get_trigger_ops,
922 .set_filter = set_trigger_filter,
768}; 923};
769 924
770static __init int register_trigger_snapshot_cmd(void) 925static __init int register_trigger_snapshot_cmd(void)
@@ -843,6 +998,7 @@ static struct event_command trigger_stacktrace_cmd = {
843 .reg = register_trigger, 998 .reg = register_trigger,
844 .unreg = unregister_trigger, 999 .unreg = unregister_trigger,
845 .get_trigger_ops = stacktrace_get_trigger_ops, 1000 .get_trigger_ops = stacktrace_get_trigger_ops,
1001 .set_filter = set_trigger_filter,
846}; 1002};
847 1003
848static __init int register_trigger_stacktrace_cmd(void) 1004static __init int register_trigger_stacktrace_cmd(void)
@@ -1100,6 +1256,8 @@ event_enable_trigger_func(struct event_command *cmd_ops,
1100 out_put: 1256 out_put:
1101 module_put(event_enable_file->event_call->mod); 1257 module_put(event_enable_file->event_call->mod);
1102 out_free: 1258 out_free:
1259 if (cmd_ops->set_filter)
1260 cmd_ops->set_filter(NULL, trigger_data, NULL);
1103 kfree(trigger_data); 1261 kfree(trigger_data);
1104 kfree(enable_data); 1262 kfree(enable_data);
1105 goto out; 1263 goto out;
@@ -1137,6 +1295,7 @@ static int event_enable_register_trigger(char *glob,
1137 list_del_rcu(&data->list); 1295 list_del_rcu(&data->list);
1138 ret--; 1296 ret--;
1139 } 1297 }
1298 update_cond_flag(file);
1140out: 1299out:
1141 return ret; 1300 return ret;
1142} 1301}
@@ -1157,6 +1316,7 @@ static void event_enable_unregister_trigger(char *glob,
1157 (enable_data->file == test_enable_data->file)) { 1316 (enable_data->file == test_enable_data->file)) {
1158 unregistered = true; 1317 unregistered = true;
1159 list_del_rcu(&data->list); 1318 list_del_rcu(&data->list);
1319 update_cond_flag(file);
1160 trace_event_trigger_enable_disable(file, 0); 1320 trace_event_trigger_enable_disable(file, 0);
1161 break; 1321 break;
1162 } 1322 }
@@ -1191,6 +1351,7 @@ static struct event_command trigger_enable_cmd = {
1191 .reg = event_enable_register_trigger, 1351 .reg = event_enable_register_trigger,
1192 .unreg = event_enable_unregister_trigger, 1352 .unreg = event_enable_unregister_trigger,
1193 .get_trigger_ops = event_enable_get_trigger_ops, 1353 .get_trigger_ops = event_enable_get_trigger_ops,
1354 .set_filter = set_trigger_filter,
1194}; 1355};
1195 1356
1196static struct event_command trigger_disable_cmd = { 1357static struct event_command trigger_disable_cmd = {
@@ -1200,6 +1361,7 @@ static struct event_command trigger_disable_cmd = {
1200 .reg = event_enable_register_trigger, 1361 .reg = event_enable_register_trigger,
1201 .unreg = event_enable_unregister_trigger, 1362 .unreg = event_enable_unregister_trigger,
1202 .get_trigger_ops = event_enable_get_trigger_ops, 1363 .get_trigger_ops = event_enable_get_trigger_ops,
1364 .set_filter = set_trigger_filter,
1203}; 1365};
1204 1366
1205static __init void unregister_trigger_enable_disable_cmds(void) 1367static __init void unregister_trigger_enable_disable_cmds(void)
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 936ec3960335..fdd955f2f1aa 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -306,8 +306,10 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
306 struct syscall_trace_enter *entry; 306 struct syscall_trace_enter *entry;
307 struct syscall_metadata *sys_data; 307 struct syscall_metadata *sys_data;
308 struct ring_buffer_event *event; 308 struct ring_buffer_event *event;
309 enum event_trigger_type __tt = ETT_NONE;
309 struct ring_buffer *buffer; 310 struct ring_buffer *buffer;
310 unsigned long irq_flags; 311 unsigned long irq_flags;
312 unsigned long eflags;
311 int pc; 313 int pc;
312 int syscall_nr; 314 int syscall_nr;
313 int size; 315 int size;
@@ -321,10 +323,14 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
321 if (!ftrace_file) 323 if (!ftrace_file)
322 return; 324 return;
323 325
324 if (test_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &ftrace_file->flags)) 326 eflags = ftrace_file->flags;
325 event_triggers_call(ftrace_file); 327
326 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) 328 if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
327 return; 329 if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
330 event_triggers_call(ftrace_file, NULL);
331 if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
332 return;
333 }
328 334
329 sys_data = syscall_nr_to_meta(syscall_nr); 335 sys_data = syscall_nr_to_meta(syscall_nr);
330 if (!sys_data) 336 if (!sys_data)
@@ -345,9 +351,16 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
345 entry->nr = syscall_nr; 351 entry->nr = syscall_nr;
346 syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args); 352 syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args);
347 353
348 if (!filter_check_discard(ftrace_file, entry, buffer, event)) 354 if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
355 __tt = event_triggers_call(ftrace_file, entry);
356
357 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
358 ring_buffer_discard_commit(buffer, event);
359 else if (!filter_check_discard(ftrace_file, entry, buffer, event))
349 trace_current_buffer_unlock_commit(buffer, event, 360 trace_current_buffer_unlock_commit(buffer, event,
350 irq_flags, pc); 361 irq_flags, pc);
362 if (__tt)
363 event_triggers_post_call(ftrace_file, __tt);
351} 364}
352 365
353static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) 366static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
@@ -357,8 +370,10 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
357 struct syscall_trace_exit *entry; 370 struct syscall_trace_exit *entry;
358 struct syscall_metadata *sys_data; 371 struct syscall_metadata *sys_data;
359 struct ring_buffer_event *event; 372 struct ring_buffer_event *event;
373 enum event_trigger_type __tt = ETT_NONE;
360 struct ring_buffer *buffer; 374 struct ring_buffer *buffer;
361 unsigned long irq_flags; 375 unsigned long irq_flags;
376 unsigned long eflags;
362 int pc; 377 int pc;
363 int syscall_nr; 378 int syscall_nr;
364 379
@@ -371,10 +386,14 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
371 if (!ftrace_file) 386 if (!ftrace_file)
372 return; 387 return;
373 388
374 if (test_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &ftrace_file->flags)) 389 eflags = ftrace_file->flags;
375 event_triggers_call(ftrace_file); 390
376 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) 391 if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
377 return; 392 if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
393 event_triggers_call(ftrace_file, NULL);
394 if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
395 return;
396 }
378 397
379 sys_data = syscall_nr_to_meta(syscall_nr); 398 sys_data = syscall_nr_to_meta(syscall_nr);
380 if (!sys_data) 399 if (!sys_data)
@@ -394,9 +413,16 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
394 entry->nr = syscall_nr; 413 entry->nr = syscall_nr;
395 entry->ret = syscall_get_return_value(current, regs); 414 entry->ret = syscall_get_return_value(current, regs);
396 415
397 if (!filter_check_discard(ftrace_file, entry, buffer, event)) 416 if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
417 __tt = event_triggers_call(ftrace_file, entry);
418
419 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
420 ring_buffer_discard_commit(buffer, event);
421 else if (!filter_check_discard(ftrace_file, entry, buffer, event))
398 trace_current_buffer_unlock_commit(buffer, event, 422 trace_current_buffer_unlock_commit(buffer, event,
399 irq_flags, pc); 423 irq_flags, pc);
424 if (__tt)
425 event_triggers_post_call(ftrace_file, __tt);
400} 426}
401 427
402static int reg_event_syscall_enter(struct ftrace_event_file *file, 428static int reg_event_syscall_enter(struct ftrace_event_file *file,