aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-05-21 02:39:03 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-21 02:39:03 -0400
commit56f410cf45a1c1f68f77741990e0435b06a07676 (patch)
treeb52f55cd45228474818b5409b722255a0a24ed24
parent894e21642dde19184f059c485c49abd7ecdd6ec9 (diff)
parenta33d7d94eed92b23fbbc7b0de06a41b2bbaa49e3 (diff)
Merge tag 'trace-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: - Fix a bug caused by not cleaning up the new instance unique triggers when deleting an instance. It also creates a selftest that triggers that bug. - Fix the delayed optimization happening after kprobes boot up self tests being removed by freeing of init memory. - Comment kprobes on why the delay optimization is not a problem for removal of modules, to keep other developers from searching that riddle. - Fix another case of rcu not watching in stack trace tracing. * tag 'trace-v4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Make sure RCU is watching before calling a stack trace kprobes: Document how optimized kprobes are removed from module unload selftests/ftrace: Add test to remove instance with active event triggers selftests/ftrace: Fix bashisms ftrace: Remove #ifdef from code and add clear_ftrace_function_probes() stub ftrace/instances: Clear function triggers when removing instances ftrace: Simplify glob handling in unregister_ftrace_function_probe_func() tracing/kprobes: Enforce kprobes teardown after testing tracing: Move postpone selftests to core from early_initcall
-rw-r--r--include/linux/kprobes.h3
-rw-r--r--kernel/kprobes.c8
-rw-r--r--kernel/trace/ftrace.c12
-rw-r--r--kernel/trace/trace.c34
-rw-r--r--kernel/trace/trace.h5
-rw-r--r--kernel/trace/trace_kprobe.c5
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest2
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc2
-rw-r--r--tools/testing/selftests/ftrace/test.d/functions4
-rw-r--r--tools/testing/selftests/ftrace/test.d/instances/instance-event.tc8
10 files changed, 72 insertions, 11 deletions
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 30f90c1a0aaf..541df0b5b815 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -349,6 +349,9 @@ extern int proc_kprobes_optimization_handler(struct ctl_table *table,
349 int write, void __user *buffer, 349 int write, void __user *buffer,
350 size_t *length, loff_t *ppos); 350 size_t *length, loff_t *ppos);
351#endif 351#endif
352extern void wait_for_kprobe_optimizer(void);
353#else
354static inline void wait_for_kprobe_optimizer(void) { }
352#endif /* CONFIG_OPTPROBES */ 355#endif /* CONFIG_OPTPROBES */
353#ifdef CONFIG_KPROBES_ON_FTRACE 356#ifdef CONFIG_KPROBES_ON_FTRACE
354extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip, 357extern void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7367e0ec6f81..2d2d3a568e4e 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -595,7 +595,7 @@ static void kprobe_optimizer(struct work_struct *work)
595} 595}
596 596
597/* Wait for completing optimization and unoptimization */ 597/* Wait for completing optimization and unoptimization */
598static void wait_for_kprobe_optimizer(void) 598void wait_for_kprobe_optimizer(void)
599{ 599{
600 mutex_lock(&kprobe_mutex); 600 mutex_lock(&kprobe_mutex);
601 601
@@ -2183,6 +2183,12 @@ static int kprobes_module_callback(struct notifier_block *nb,
2183 * The vaddr this probe is installed will soon 2183 * The vaddr this probe is installed will soon
2184 * be vfreed buy not synced to disk. Hence, 2184 * be vfreed buy not synced to disk. Hence,
2185 * disarming the breakpoint isn't needed. 2185 * disarming the breakpoint isn't needed.
2186 *
2187 * Note, this will also move any optimized probes
2188 * that are pending to be removed from their
2189 * corresponding lists to the freeing_list and
2190 * will not be touched by the delayed
2191 * kprobe_optimizer work handler.
2186 */ 2192 */
2187 kill_kprobe(p); 2193 kill_kprobe(p);
2188 } 2194 }
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 39dca4e86a94..74fdfe9ed3db 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4144,9 +4144,9 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
4144 int i, ret = -ENODEV; 4144 int i, ret = -ENODEV;
4145 int size; 4145 int size;
4146 4146
4147 if (glob && (strcmp(glob, "*") == 0 || !strlen(glob))) 4147 if (!glob || !strlen(glob) || !strcmp(glob, "*"))
4148 func_g.search = NULL; 4148 func_g.search = NULL;
4149 else if (glob) { 4149 else {
4150 int not; 4150 int not;
4151 4151
4152 func_g.type = filter_parse_regex(glob, strlen(glob), 4152 func_g.type = filter_parse_regex(glob, strlen(glob),
@@ -4256,6 +4256,14 @@ unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
4256 return ret; 4256 return ret;
4257} 4257}
4258 4258
4259void clear_ftrace_function_probes(struct trace_array *tr)
4260{
4261 struct ftrace_func_probe *probe, *n;
4262
4263 list_for_each_entry_safe(probe, n, &tr->func_probes, list)
4264 unregister_ftrace_function_probe_func(NULL, tr, probe->probe_ops);
4265}
4266
4259static LIST_HEAD(ftrace_commands); 4267static LIST_HEAD(ftrace_commands);
4260static DEFINE_MUTEX(ftrace_cmd_mutex); 4268static DEFINE_MUTEX(ftrace_cmd_mutex);
4261 4269
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c4536c449021..1122f151466f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1558,7 +1558,7 @@ static __init int init_trace_selftests(void)
1558 1558
1559 return 0; 1559 return 0;
1560} 1560}
1561early_initcall(init_trace_selftests); 1561core_initcall(init_trace_selftests);
1562#else 1562#else
1563static inline int run_tracer_selftest(struct tracer *type) 1563static inline int run_tracer_selftest(struct tracer *type)
1564{ 1564{
@@ -2568,7 +2568,36 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
2568void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, 2568void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
2569 int pc) 2569 int pc)
2570{ 2570{
2571 __ftrace_trace_stack(tr->trace_buffer.buffer, flags, skip, pc, NULL); 2571 struct ring_buffer *buffer = tr->trace_buffer.buffer;
2572
2573 if (rcu_is_watching()) {
2574 __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
2575 return;
2576 }
2577
2578 /*
2579 * When an NMI triggers, RCU is enabled via rcu_nmi_enter(),
2580 * but if the above rcu_is_watching() failed, then the NMI
2581 * triggered someplace critical, and rcu_irq_enter() should
2582 * not be called from NMI.
2583 */
2584 if (unlikely(in_nmi()))
2585 return;
2586
2587 /*
2588 * It is possible that a function is being traced in a
2589 * location that RCU is not watching. A call to
2590 * rcu_irq_enter() will make sure that it is, but there's
2591 * a few internal rcu functions that could be traced
2592 * where that wont work either. In those cases, we just
2593 * do nothing.
2594 */
2595 if (unlikely(rcu_irq_enter_disabled()))
2596 return;
2597
2598 rcu_irq_enter_irqson();
2599 __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
2600 rcu_irq_exit_irqson();
2572} 2601}
2573 2602
2574/** 2603/**
@@ -7550,6 +7579,7 @@ static int instance_rmdir(const char *name)
7550 } 7579 }
7551 7580
7552 tracing_set_nop(tr); 7581 tracing_set_nop(tr);
7582 clear_ftrace_function_probes(tr);
7553 event_trace_del_tracer(tr); 7583 event_trace_del_tracer(tr);
7554 ftrace_clear_pids(tr); 7584 ftrace_clear_pids(tr);
7555 ftrace_destroy_function_files(tr); 7585 ftrace_destroy_function_files(tr);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 291a1bca5748..39fd77330aab 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -980,6 +980,7 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr,
980extern int 980extern int
981unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr, 981unregister_ftrace_function_probe_func(char *glob, struct trace_array *tr,
982 struct ftrace_probe_ops *ops); 982 struct ftrace_probe_ops *ops);
983extern void clear_ftrace_function_probes(struct trace_array *tr);
983 984
984int register_ftrace_command(struct ftrace_func_command *cmd); 985int register_ftrace_command(struct ftrace_func_command *cmd);
985int unregister_ftrace_command(struct ftrace_func_command *cmd); 986int unregister_ftrace_command(struct ftrace_func_command *cmd);
@@ -998,6 +999,10 @@ static inline __init int unregister_ftrace_command(char *cmd_name)
998{ 999{
999 return -EINVAL; 1000 return -EINVAL;
1000} 1001}
1002static inline void clear_ftrace_function_probes(struct trace_array *tr)
1003{
1004}
1005
1001/* 1006/*
1002 * The ops parameter passed in is usually undefined. 1007 * The ops parameter passed in is usually undefined.
1003 * This must be a macro. 1008 * This must be a macro.
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 8485f6738a87..c129fca6ec99 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1535,6 +1535,11 @@ static __init int kprobe_trace_self_tests_init(void)
1535 1535
1536end: 1536end:
1537 release_all_trace_kprobes(); 1537 release_all_trace_kprobes();
1538 /*
1539 * Wait for the optimizer work to finish. Otherwise it might fiddle
1540 * with probes in already freed __init text.
1541 */
1542 wait_for_kprobe_optimizer();
1538 if (warn) 1543 if (warn)
1539 pr_cont("NG: Some tests are failed. Please check them.\n"); 1544 pr_cont("NG: Some tests are failed. Please check them.\n");
1540 else 1545 else
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 32e6211e1c6e..717581145cfc 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -58,7 +58,7 @@ parse_opts() { # opts
58 ;; 58 ;;
59 --verbose|-v|-vv) 59 --verbose|-v|-vv)
60 VERBOSE=$((VERBOSE + 1)) 60 VERBOSE=$((VERBOSE + 1))
61 [ $1 == '-vv' ] && VERBOSE=$((VERBOSE + 1)) 61 [ $1 = '-vv' ] && VERBOSE=$((VERBOSE + 1))
62 shift 1 62 shift 1
63 ;; 63 ;;
64 --debug|-d) 64 --debug|-d)
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
index 07bb3e5930b4..aa31368851c9 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_event_triggers.tc
@@ -48,7 +48,7 @@ test_event_enabled() {
48 e=`cat $EVENT_ENABLE` 48 e=`cat $EVENT_ENABLE`
49 if [ "$e" != $val ]; then 49 if [ "$e" != $val ]; then
50 echo "Expected $val but found $e" 50 echo "Expected $val but found $e"
51 exit -1 51 exit 1
52 fi 52 fi
53} 53}
54 54
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
index 9aec6fcb7729..f2019b37370d 100644
--- a/tools/testing/selftests/ftrace/test.d/functions
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -34,10 +34,10 @@ reset_ftrace_filter() { # reset all triggers in set_ftrace_filter
34 echo > set_ftrace_filter 34 echo > set_ftrace_filter
35 grep -v '^#' set_ftrace_filter | while read t; do 35 grep -v '^#' set_ftrace_filter | while read t; do
36 tr=`echo $t | cut -d: -f2` 36 tr=`echo $t | cut -d: -f2`
37 if [ "$tr" == "" ]; then 37 if [ "$tr" = "" ]; then
38 continue 38 continue
39 fi 39 fi
40 if [ $tr == "enable_event" -o $tr == "disable_event" ]; then 40 if [ $tr = "enable_event" -o $tr = "disable_event" ]; then
41 tr=`echo $t | cut -d: -f1-4` 41 tr=`echo $t | cut -d: -f1-4`
42 limit=`echo $t | cut -d: -f5` 42 limit=`echo $t | cut -d: -f5`
43 else 43 else
diff --git a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
index 4c5a061a5b4e..c73db7863adb 100644
--- a/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
+++ b/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc
@@ -75,9 +75,13 @@ rmdir foo
75if [ -d foo ]; then 75if [ -d foo ]; then
76 fail "foo still exists" 76 fail "foo still exists"
77fi 77fi
78exit 0
79
80 78
79mkdir foo
80echo "schedule:enable_event:sched:sched_switch" > foo/set_ftrace_filter
81rmdir foo
82if [ -d foo ]; then
83 fail "foo still exists"
84fi
81 85
82 86
83instance_slam() { 87instance_slam() {