@@ -101,6 +101,206 @@ static inline void warn_failed_init_tracer(struct tracer *trace, int init_ret)
101101
102102#ifdef CONFIG_DYNAMIC_FTRACE
103103
104+ static int trace_selftest_test_probe1_cnt ;
105+ static void trace_selftest_test_probe1_func (unsigned long ip ,
106+ unsigned long pip )
107+ {
108+ trace_selftest_test_probe1_cnt ++ ;
109+ }
110+
111+ static int trace_selftest_test_probe2_cnt ;
112+ static void trace_selftest_test_probe2_func (unsigned long ip ,
113+ unsigned long pip )
114+ {
115+ trace_selftest_test_probe2_cnt ++ ;
116+ }
117+
118+ static int trace_selftest_test_probe3_cnt ;
119+ static void trace_selftest_test_probe3_func (unsigned long ip ,
120+ unsigned long pip )
121+ {
122+ trace_selftest_test_probe3_cnt ++ ;
123+ }
124+
125+ static int trace_selftest_test_global_cnt ;
126+ static void trace_selftest_test_global_func (unsigned long ip ,
127+ unsigned long pip )
128+ {
129+ trace_selftest_test_global_cnt ++ ;
130+ }
131+
132+ static int trace_selftest_test_dyn_cnt ;
133+ static void trace_selftest_test_dyn_func (unsigned long ip ,
134+ unsigned long pip )
135+ {
136+ trace_selftest_test_dyn_cnt ++ ;
137+ }
138+
139+ static struct ftrace_ops test_probe1 = {
140+ .func = trace_selftest_test_probe1_func ,
141+ };
142+
143+ static struct ftrace_ops test_probe2 = {
144+ .func = trace_selftest_test_probe2_func ,
145+ };
146+
147+ static struct ftrace_ops test_probe3 = {
148+ .func = trace_selftest_test_probe3_func ,
149+ };
150+
151+ static struct ftrace_ops test_global = {
152+ .func = trace_selftest_test_global_func ,
153+ .flags = FTRACE_OPS_FL_GLOBAL ,
154+ };
155+
156+ static void print_counts (void )
157+ {
158+ printk ("(%d %d %d %d %d) " ,
159+ trace_selftest_test_probe1_cnt ,
160+ trace_selftest_test_probe2_cnt ,
161+ trace_selftest_test_probe3_cnt ,
162+ trace_selftest_test_global_cnt ,
163+ trace_selftest_test_dyn_cnt );
164+ }
165+
166+ static void reset_counts (void )
167+ {
168+ trace_selftest_test_probe1_cnt = 0 ;
169+ trace_selftest_test_probe2_cnt = 0 ;
170+ trace_selftest_test_probe3_cnt = 0 ;
171+ trace_selftest_test_global_cnt = 0 ;
172+ trace_selftest_test_dyn_cnt = 0 ;
173+ }
174+
175+ static int trace_selftest_ops (int cnt )
176+ {
177+ int save_ftrace_enabled = ftrace_enabled ;
178+ struct ftrace_ops * dyn_ops ;
179+ char * func1_name ;
180+ char * func2_name ;
181+ int len1 ;
182+ int len2 ;
183+ int ret = -1 ;
184+
185+ printk (KERN_CONT "PASSED\n" );
186+ pr_info ("Testing dynamic ftrace ops #%d: " , cnt );
187+
188+ ftrace_enabled = 1 ;
189+ reset_counts ();
190+
191+ /* Handle PPC64 '.' name */
192+ func1_name = "*" __stringify (DYN_FTRACE_TEST_NAME );
193+ func2_name = "*" __stringify (DYN_FTRACE_TEST_NAME2 );
194+ len1 = strlen (func1_name );
195+ len2 = strlen (func2_name );
196+
197+ /*
198+ * Probe 1 will trace function 1.
199+ * Probe 2 will trace function 2.
200+ * Probe 3 will trace functions 1 and 2.
201+ */
202+ ftrace_set_filter (& test_probe1 , func1_name , len1 , 1 );
203+ ftrace_set_filter (& test_probe2 , func2_name , len2 , 1 );
204+ ftrace_set_filter (& test_probe3 , func1_name , len1 , 1 );
205+ ftrace_set_filter (& test_probe3 , func2_name , len2 , 0 );
206+
207+ register_ftrace_function (& test_probe1 );
208+ register_ftrace_function (& test_probe2 );
209+ register_ftrace_function (& test_probe3 );
210+ register_ftrace_function (& test_global );
211+
212+ DYN_FTRACE_TEST_NAME ();
213+
214+ print_counts ();
215+
216+ if (trace_selftest_test_probe1_cnt != 1 )
217+ goto out ;
218+ if (trace_selftest_test_probe2_cnt != 0 )
219+ goto out ;
220+ if (trace_selftest_test_probe3_cnt != 1 )
221+ goto out ;
222+ if (trace_selftest_test_global_cnt == 0 )
223+ goto out ;
224+
225+ DYN_FTRACE_TEST_NAME2 ();
226+
227+ print_counts ();
228+
229+ if (trace_selftest_test_probe1_cnt != 1 )
230+ goto out ;
231+ if (trace_selftest_test_probe2_cnt != 1 )
232+ goto out ;
233+ if (trace_selftest_test_probe3_cnt != 2 )
234+ goto out ;
235+
236+ /* Add a dynamic probe */
237+ dyn_ops = kzalloc (sizeof (* dyn_ops ), GFP_KERNEL );
238+ if (!dyn_ops ) {
239+ printk ("MEMORY ERROR " );
240+ goto out ;
241+ }
242+
243+ dyn_ops -> func = trace_selftest_test_dyn_func ;
244+
245+ register_ftrace_function (dyn_ops );
246+
247+ trace_selftest_test_global_cnt = 0 ;
248+
249+ DYN_FTRACE_TEST_NAME ();
250+
251+ print_counts ();
252+
253+ if (trace_selftest_test_probe1_cnt != 2 )
254+ goto out_free ;
255+ if (trace_selftest_test_probe2_cnt != 1 )
256+ goto out_free ;
257+ if (trace_selftest_test_probe3_cnt != 3 )
258+ goto out_free ;
259+ if (trace_selftest_test_global_cnt == 0 )
260+ goto out ;
261+ if (trace_selftest_test_dyn_cnt == 0 )
262+ goto out_free ;
263+
264+ DYN_FTRACE_TEST_NAME2 ();
265+
266+ print_counts ();
267+
268+ if (trace_selftest_test_probe1_cnt != 2 )
269+ goto out_free ;
270+ if (trace_selftest_test_probe2_cnt != 2 )
271+ goto out_free ;
272+ if (trace_selftest_test_probe3_cnt != 4 )
273+ goto out_free ;
274+
275+ ret = 0 ;
276+ out_free :
277+ unregister_ftrace_function (dyn_ops );
278+ kfree (dyn_ops );
279+
280+ out :
281+ /* Purposely unregister in the same order */
282+ unregister_ftrace_function (& test_probe1 );
283+ unregister_ftrace_function (& test_probe2 );
284+ unregister_ftrace_function (& test_probe3 );
285+ unregister_ftrace_function (& test_global );
286+
287+ /* Make sure everything is off */
288+ reset_counts ();
289+ DYN_FTRACE_TEST_NAME ();
290+ DYN_FTRACE_TEST_NAME ();
291+
292+ if (trace_selftest_test_probe1_cnt ||
293+ trace_selftest_test_probe2_cnt ||
294+ trace_selftest_test_probe3_cnt ||
295+ trace_selftest_test_global_cnt ||
296+ trace_selftest_test_dyn_cnt )
297+ ret = -1 ;
298+
299+ ftrace_enabled = save_ftrace_enabled ;
300+
301+ return ret ;
302+ }
303+
104304/* Test dynamic code modification and ftrace filters */
105305int trace_selftest_startup_dynamic_tracing (struct tracer * trace ,
106306 struct trace_array * tr ,
@@ -166,23 +366,31 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
166366
167367 /* check the trace buffer */
168368 ret = trace_test_buffer (tr , & count );
169- trace -> reset (tr );
170369 tracing_start ();
171370
172371 /* we should only have one item */
173372 if (!ret && count != 1 ) {
373+ trace -> reset (tr );
174374 printk (KERN_CONT ".. filter failed count=%ld .." , count );
175375 ret = -1 ;
176376 goto out ;
177377 }
178378
379+ /* Test the ops with global tracing running */
380+ ret = trace_selftest_ops (1 );
381+ trace -> reset (tr );
382+
179383 out :
180384 ftrace_enabled = save_ftrace_enabled ;
181385 tracer_enabled = save_tracer_enabled ;
182386
183387 /* Enable tracing on all functions again */
184388 ftrace_set_global_filter (NULL , 0 , 1 );
185389
390+ /* Test the ops with global tracing off */
391+ if (!ret )
392+ ret = trace_selftest_ops (2 );
393+
186394 return ret ;
187395}
188396#else
0 commit comments