History

Merge tag 'trace-v4.2-rc2-fix3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull ftrace fix from Steven Rostedt: "Back in 3.16 the ftrace code was redesigned and cleaned up to remove the double iteration list (one for registered ftrace ops, and one for registered "global" ops), to just use one list. That simplified the code but also broke the function tracing filtering on pid. This updates the code to handle the filtering again with the new logic" * tag 'trace-v4.2-rc2-fix3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: ftrace: Fix breakage of set_ftrace_pid

Linus Torvalds committed 11 years ago

Commit 763e3262 parents 4520083 e3eea142 files · +37 −18Browse files

Unified · Split

2 files
  1. include/linux/ftrace.h +3 −0
  2. kernel/trace/ftrace.c +34 −18
include/linux/ftrace.h+3−0
@@ -116,6 +116,7 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops); · 115 unmodified lines
116116 * SAVE_REGS. If another ops with this flag set is already registered
117117 * for any of the functions that this ops will be registered for, then
118118 * this ops will fail to register or set_filter_ip.
119+ * PID - Is affected by set_ftrace_pid (allows filtering on those pids)
119120 */
120121 enum {
121122 FTRACE_OPS_FL_ENABLED = 1 << 0,
@@ -132,6 +133,7 @@ enum { · 10 unmodified lines
132133 FTRACE_OPS_FL_MODIFYING = 1 << 11,
133134 FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12,
134135 FTRACE_OPS_FL_IPMODIFY = 1 << 13,
136+ FTRACE_OPS_FL_PID = 1 << 14,
135137 };
136138
137139 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -159,6 +161,7 @@ struct ftrace_ops { · 21 unmodified lines
159161 struct ftrace_ops *next;
160162 unsigned long flags;
161163 void *private;
164+ ftrace_func_t saved_func;
162165 int __percpu *disabled;
163166 #ifdef CONFIG_DYNAMIC_FTRACE
164167 int nr_trampolines;
kernel/trace/ftrace.c+34−18
@@ -98,6 +98,13 @@ struct ftrace_pid { · 97 unmodified lines
9898 struct pid *pid;
9999 };
100100
101+static bool ftrace_pids_enabled(void)
102+{
103+ return !list_empty(&ftrace_pids);
104+}
105+
106+static void ftrace_update_trampoline(struct ftrace_ops *ops);
107+
101108 /*
102109 * ftrace_disabled is set when an anomaly is discovered.
103110 * ftrace_disabled is much stronger than ftrace_enabled.
@@ -109,7 +116,6 @@ static DEFINE_MUTEX(ftrace_lock); · 5 unmodified lines
109116 static struct ftrace_ops *ftrace_control_list __read_mostly = &ftrace_list_end;
110117 static struct ftrace_ops *ftrace_ops_list __read_mostly = &ftrace_list_end;
111118 ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
112−ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
113119 static struct ftrace_ops global_ops;
114120 static struct ftrace_ops control_ops;
115121
@@ -183,14 +189,7 @@ static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip, · 67 unmodified lines
183189 if (!test_tsk_trace_trace(current))
184190 return;
185191
186− ftrace_pid_function(ip, parent_ip, op, regs);
187−}
188−
189−static void set_ftrace_pid_function(ftrace_func_t func)
190−{
191− /* do not set ftrace_pid_function to itself! */
192− if (func != ftrace_pid_func)
193− ftrace_pid_function = func;
192+ op->saved_func(ip, parent_ip, op, regs);
194193 }
195194
196195 /**
@@ -202,7 +201,6 @@ static void set_ftrace_pid_function(ftrace_func_t func) · 5 unmodified lines
202201 void clear_ftrace_function(void)
203202 {
204203 ftrace_trace_function = ftrace_stub;
205− ftrace_pid_function = ftrace_stub;
206204 }
207205
208206 static void control_ops_disable_all(struct ftrace_ops *ops)
@@ -436,6 +434,12 @@ static int __register_ftrace_function(struct ftrace_ops *ops) · 227 unmodified lines
436434 } else
437435 add_ftrace_ops(&ftrace_ops_list, ops);
438436
437+ /* Always save the function, and reset at unregistering */
438+ ops->saved_func = ops->func;
439+
440+ if (ops->flags & FTRACE_OPS_FL_PID && ftrace_pids_enabled())
441+ ops->func = ftrace_pid_func;
442+
439443 ftrace_update_trampoline(ops);
440444
441445 if (ftrace_enabled)
@@ -463,15 +467,28 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops) · 21 unmodified lines
463467 if (ftrace_enabled)
464468 update_ftrace_function();
465469
470+ ops->func = ops->saved_func;
471+
466472 return 0;
467473 }
468474
469475 static void ftrace_update_pid_func(void)
470476 {
477+ bool enabled = ftrace_pids_enabled();
478+ struct ftrace_ops *op;
479+
471480 /* Only do something if we are tracing something */
472481 if (ftrace_trace_function == ftrace_stub)
473482 return;
474483
484+ do_for_each_ftrace_op(op, ftrace_ops_list) {
485+ if (op->flags & FTRACE_OPS_FL_PID) {
486+ op->func = enabled ? ftrace_pid_func :
487+ op->saved_func;
488+ ftrace_update_trampoline(op);
489+ }
490+ } while_for_each_ftrace_op(op);
491+
475492 update_ftrace_function();
476493 }
477494
@@ -1133,7 +1150,8 @@ static struct ftrace_ops global_ops = { · 655 unmodified lines
11331150 .local_hash.filter_hash = EMPTY_HASH,
11341151 INIT_OPS_HASH(global_ops)
11351152 .flags = FTRACE_OPS_FL_RECURSION_SAFE |
1136− FTRACE_OPS_FL_INITIALIZED,
1153+ FTRACE_OPS_FL_INITIALIZED |
1154+ FTRACE_OPS_FL_PID,
11371155 };
11381156
11391157 /*
@@ -5023,7 +5041,9 @@ static void ftrace_update_trampoline(struct ftrace_ops *ops) · 3883 unmodified lines
50235041
50245042 static struct ftrace_ops global_ops = {
50255043 .func = ftrace_stub,
5026− .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED,
5044+ .flags = FTRACE_OPS_FL_RECURSION_SAFE |
5045+ FTRACE_OPS_FL_INITIALIZED |
5046+ FTRACE_OPS_FL_PID,
50275047 };
50285048
50295049 static int __init ftrace_nodyn_init(void)
@@ -5080,11 +5100,6 @@ void ftrace_init_array_ops(struct trace_array *tr, ftrace_func_t func) · 50 unmodified lines
50805100 if (WARN_ON(tr->ops->func != ftrace_stub))
50815101 printk("ftrace ops had %pS for function\n",
50825102 tr->ops->func);
5083− /* Only the top level instance does pid tracing */
5084− if (!list_empty(&ftrace_pids)) {
5085− set_ftrace_pid_function(func);
5086− func = ftrace_pid_func;
5087− }
50885103 }
50895104 tr->ops->func = func;
50905105 tr->ops->private = tr;
@@ -5371,7 +5386,7 @@ static void *fpid_start(struct seq_file *m, loff_t *pos) · 280 unmodified lines
53715386 {
53725387 mutex_lock(&ftrace_lock);
53735388
5374− if (list_empty(&ftrace_pids) && (!*pos))
5389+ if (!ftrace_pids_enabled() && (!*pos))
53755390 return (void *) 1;
53765391
53775392 return seq_list_start(&ftrace_pids, *pos);
@@ -5610,6 +5625,7 @@ static struct ftrace_ops graph_ops = { · 232 unmodified lines
56105625 .func = ftrace_stub,
56115626 .flags = FTRACE_OPS_FL_RECURSION_SAFE |
56125627 FTRACE_OPS_FL_INITIALIZED |
5628+ FTRACE_OPS_FL_PID |
56135629 FTRACE_OPS_FL_STUB,
56145630 #ifdef FTRACE_GRAPH_TRAMP_ADDR
56155631 .trampoline = FTRACE_GRAPH_TRAMP_ADDR,