Blame view

kernel/trace/trace_selftest.c 26.6 KB
60a11774b   Steven Rostedt   ftrace: add self-...
1
  /* Include in trace.c */
9cc26a261   Steven Rostedt   tracing: use gene...
2
  #include <linux/stringify.h>
60a11774b   Steven Rostedt   ftrace: add self-...
3
  #include <linux/kthread.h>
c7aafc549   Ingo Molnar   ftrace: cleanups
4
  #include <linux/delay.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
5
  #include <linux/slab.h>
60a11774b   Steven Rostedt   ftrace: add self-...
6

e309b41dd   Ingo Molnar   ftrace: remove no...
7
  static inline int trace_valid_entry(struct trace_entry *entry)
60a11774b   Steven Rostedt   ftrace: add self-...
8
9
10
11
  {
  	switch (entry->type) {
  	case TRACE_FN:
  	case TRACE_CTX:
57422797d   Ingo Molnar   ftrace: add wakeu...
12
  	case TRACE_WAKE:
06fa75ab5   Steven Rostedt   ftrace: add TRACE...
13
  	case TRACE_STACK:
dd0e545f0   Steven Rostedt   ftrace: printk fo...
14
  	case TRACE_PRINT:
80e5ea450   Steven Rostedt   ftrace: add trace...
15
  	case TRACE_BRANCH:
7447dce96   Frederic Weisbecker   tracing/function-...
16
17
  	case TRACE_GRAPH_ENT:
  	case TRACE_GRAPH_RET:
60a11774b   Steven Rostedt   ftrace: add self-...
18
19
20
21
  		return 1;
  	}
  	return 0;
  }
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
22
  static int trace_test_buffer_cpu(struct trace_buffer *buf, int cpu)
60a11774b   Steven Rostedt   ftrace: add self-...
23
  {
3928a8a2d   Steven Rostedt   ftrace: make work...
24
25
  	struct ring_buffer_event *event;
  	struct trace_entry *entry;
4b3e3d228   Steven Rostedt   tracing: limit th...
26
  	unsigned int loops = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
27

12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
28
  	while ((event = ring_buffer_consume(buf->buffer, cpu, NULL, NULL))) {
3928a8a2d   Steven Rostedt   ftrace: make work...
29
  		entry = ring_buffer_event_data(event);
60a11774b   Steven Rostedt   ftrace: add self-...
30

4b3e3d228   Steven Rostedt   tracing: limit th...
31
32
33
34
35
36
37
38
39
  		/*
  		 * The ring buffer is a size of trace_buf_size, if
  		 * we loop more than the size, there's something wrong
  		 * with the ring buffer.
  		 */
  		if (loops++ > trace_buf_size) {
  			printk(KERN_CONT ".. bad ring buffer ");
  			goto failed;
  		}
3928a8a2d   Steven Rostedt   ftrace: make work...
40
  		if (!trace_valid_entry(entry)) {
c7aafc549   Ingo Molnar   ftrace: cleanups
41
  			printk(KERN_CONT ".. invalid entry %d ",
3928a8a2d   Steven Rostedt   ftrace: make work...
42
  				entry->type);
60a11774b   Steven Rostedt   ftrace: add self-...
43
44
  			goto failed;
  		}
60a11774b   Steven Rostedt   ftrace: add self-...
45
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
46
47
48
  	return 0;
  
   failed:
08bafa0ef   Steven Rostedt   ftrace: disable a...
49
50
  	/* disable tracing */
  	tracing_disabled = 1;
60a11774b   Steven Rostedt   ftrace: add self-...
51
52
53
54
55
56
57
58
  	printk(KERN_CONT ".. corrupted trace buffer .. ");
  	return -1;
  }
  
  /*
   * Test the trace buffer to see if all the elements
   * are still sane.
   */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
59
  static int trace_test_buffer(struct trace_buffer *buf, unsigned long *count)
60a11774b   Steven Rostedt   ftrace: add self-...
60
  {
30afdcb1d   Steven Rostedt   ftrace: selftest ...
61
62
  	unsigned long flags, cnt = 0;
  	int cpu, ret = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
63

30afdcb1d   Steven Rostedt   ftrace: selftest ...
64
  	/* Don't allow flipping of max traces now */
d51ad7ac4   Steven Rostedt   ftrace: replace r...
65
  	local_irq_save(flags);
0b9b12c1b   Steven Rostedt (Red Hat)   tracing: Move ftr...
66
  	arch_spin_lock(&buf->tr->max_lock);
60a11774b   Steven Rostedt   ftrace: add self-...
67

12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
68
  	cnt = ring_buffer_entries(buf->buffer);
60a11774b   Steven Rostedt   ftrace: add self-...
69

0c5119c1e   Steven Rostedt   tracing: disable ...
70
71
72
73
74
75
76
77
  	/*
  	 * The trace_test_buffer_cpu runs a while loop to consume all data.
  	 * If the calling tracer is broken, and is constantly filling
  	 * the buffer, this will run forever, and hard lock the box.
  	 * We disable the ring buffer while we do this test to prevent
  	 * a hard lock up.
  	 */
  	tracing_off();
3928a8a2d   Steven Rostedt   ftrace: make work...
78
  	for_each_possible_cpu(cpu) {
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
79
  		ret = trace_test_buffer_cpu(buf, cpu);
60a11774b   Steven Rostedt   ftrace: add self-...
80
81
82
  		if (ret)
  			break;
  	}
0c5119c1e   Steven Rostedt   tracing: disable ...
83
  	tracing_on();
0b9b12c1b   Steven Rostedt (Red Hat)   tracing: Move ftr...
84
  	arch_spin_unlock(&buf->tr->max_lock);
d51ad7ac4   Steven Rostedt   ftrace: replace r...
85
  	local_irq_restore(flags);
60a11774b   Steven Rostedt   ftrace: add self-...
86
87
88
89
90
91
  
  	if (count)
  		*count = cnt;
  
  	return ret;
  }
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
92
93
94
95
96
97
  static inline void warn_failed_init_tracer(struct tracer *trace, int init_ret)
  {
  	printk(KERN_WARNING "Failed to init %s tracer, init returned %d
  ",
  		trace->name, init_ret);
  }
606576ce8   Steven Rostedt   ftrace: rename FT...
98
  #ifdef CONFIG_FUNCTION_TRACER
77a2b37d2   Steven Rostedt   ftrace: startup t...
99
100
  
  #ifdef CONFIG_DYNAMIC_FTRACE
95950c2ec   Steven Rostedt   ftrace: Add self-...
101
102
  static int trace_selftest_test_probe1_cnt;
  static void trace_selftest_test_probe1_func(unsigned long ip,
2f5f6ad93   Steven Rostedt   ftrace: Pass ftra...
103
  					    unsigned long pip,
a1e2e31d1   Steven Rostedt   ftrace: Return pt...
104
105
  					    struct ftrace_ops *op,
  					    struct pt_regs *pt_regs)
95950c2ec   Steven Rostedt   ftrace: Add self-...
106
107
108
109
110
111
  {
  	trace_selftest_test_probe1_cnt++;
  }
  
  static int trace_selftest_test_probe2_cnt;
  static void trace_selftest_test_probe2_func(unsigned long ip,
2f5f6ad93   Steven Rostedt   ftrace: Pass ftra...
112
  					    unsigned long pip,
a1e2e31d1   Steven Rostedt   ftrace: Return pt...
113
114
  					    struct ftrace_ops *op,
  					    struct pt_regs *pt_regs)
95950c2ec   Steven Rostedt   ftrace: Add self-...
115
116
117
118
119
120
  {
  	trace_selftest_test_probe2_cnt++;
  }
  
  static int trace_selftest_test_probe3_cnt;
  static void trace_selftest_test_probe3_func(unsigned long ip,
2f5f6ad93   Steven Rostedt   ftrace: Pass ftra...
121
  					    unsigned long pip,
a1e2e31d1   Steven Rostedt   ftrace: Return pt...
122
123
  					    struct ftrace_ops *op,
  					    struct pt_regs *pt_regs)
95950c2ec   Steven Rostedt   ftrace: Add self-...
124
125
126
127
128
129
  {
  	trace_selftest_test_probe3_cnt++;
  }
  
  static int trace_selftest_test_global_cnt;
  static void trace_selftest_test_global_func(unsigned long ip,
2f5f6ad93   Steven Rostedt   ftrace: Pass ftra...
130
  					    unsigned long pip,
a1e2e31d1   Steven Rostedt   ftrace: Return pt...
131
132
  					    struct ftrace_ops *op,
  					    struct pt_regs *pt_regs)
95950c2ec   Steven Rostedt   ftrace: Add self-...
133
134
135
136
137
138
  {
  	trace_selftest_test_global_cnt++;
  }
  
  static int trace_selftest_test_dyn_cnt;
  static void trace_selftest_test_dyn_func(unsigned long ip,
2f5f6ad93   Steven Rostedt   ftrace: Pass ftra...
139
  					 unsigned long pip,
a1e2e31d1   Steven Rostedt   ftrace: Return pt...
140
141
  					 struct ftrace_ops *op,
  					 struct pt_regs *pt_regs)
95950c2ec   Steven Rostedt   ftrace: Add self-...
142
143
144
145
146
147
  {
  	trace_selftest_test_dyn_cnt++;
  }
  
  static struct ftrace_ops test_probe1 = {
  	.func			= trace_selftest_test_probe1_func,
4740974a6   Steven Rostedt   ftrace: Add defau...
148
  	.flags			= FTRACE_OPS_FL_RECURSION_SAFE,
95950c2ec   Steven Rostedt   ftrace: Add self-...
149
150
151
152
  };
  
  static struct ftrace_ops test_probe2 = {
  	.func			= trace_selftest_test_probe2_func,
4740974a6   Steven Rostedt   ftrace: Add defau...
153
  	.flags			= FTRACE_OPS_FL_RECURSION_SAFE,
95950c2ec   Steven Rostedt   ftrace: Add self-...
154
155
156
157
  };
  
  static struct ftrace_ops test_probe3 = {
  	.func			= trace_selftest_test_probe3_func,
4740974a6   Steven Rostedt   ftrace: Add defau...
158
  	.flags			= FTRACE_OPS_FL_RECURSION_SAFE,
95950c2ec   Steven Rostedt   ftrace: Add self-...
159
  };
95950c2ec   Steven Rostedt   ftrace: Add self-...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  static void print_counts(void)
  {
  	printk("(%d %d %d %d %d) ",
  	       trace_selftest_test_probe1_cnt,
  	       trace_selftest_test_probe2_cnt,
  	       trace_selftest_test_probe3_cnt,
  	       trace_selftest_test_global_cnt,
  	       trace_selftest_test_dyn_cnt);
  }
  
  static void reset_counts(void)
  {
  	trace_selftest_test_probe1_cnt = 0;
  	trace_selftest_test_probe2_cnt = 0;
  	trace_selftest_test_probe3_cnt = 0;
  	trace_selftest_test_global_cnt = 0;
  	trace_selftest_test_dyn_cnt = 0;
  }
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
178
  static int trace_selftest_ops(struct trace_array *tr, int cnt)
95950c2ec   Steven Rostedt   ftrace: Add self-...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  {
  	int save_ftrace_enabled = ftrace_enabled;
  	struct ftrace_ops *dyn_ops;
  	char *func1_name;
  	char *func2_name;
  	int len1;
  	int len2;
  	int ret = -1;
  
  	printk(KERN_CONT "PASSED
  ");
  	pr_info("Testing dynamic ftrace ops #%d: ", cnt);
  
  	ftrace_enabled = 1;
  	reset_counts();
  
  	/* Handle PPC64 '.' name */
  	func1_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
  	func2_name = "*" __stringify(DYN_FTRACE_TEST_NAME2);
  	len1 = strlen(func1_name);
  	len2 = strlen(func2_name);
  
  	/*
  	 * Probe 1 will trace function 1.
  	 * Probe 2 will trace function 2.
  	 * Probe 3 will trace functions 1 and 2.
  	 */
  	ftrace_set_filter(&test_probe1, func1_name, len1, 1);
  	ftrace_set_filter(&test_probe2, func2_name, len2, 1);
  	ftrace_set_filter(&test_probe3, func1_name, len1, 1);
  	ftrace_set_filter(&test_probe3, func2_name, len2, 0);
  
  	register_ftrace_function(&test_probe1);
  	register_ftrace_function(&test_probe2);
  	register_ftrace_function(&test_probe3);
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
214
215
216
217
218
  	/* First time we are running with main function */
  	if (cnt > 1) {
  		ftrace_init_array_ops(tr, trace_selftest_test_global_func);
  		register_ftrace_function(tr->ops);
  	}
95950c2ec   Steven Rostedt   ftrace: Add self-...
219
220
221
222
223
224
225
226
227
228
229
  
  	DYN_FTRACE_TEST_NAME();
  
  	print_counts();
  
  	if (trace_selftest_test_probe1_cnt != 1)
  		goto out;
  	if (trace_selftest_test_probe2_cnt != 0)
  		goto out;
  	if (trace_selftest_test_probe3_cnt != 1)
  		goto out;
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
230
231
232
233
  	if (cnt > 1) {
  		if (trace_selftest_test_global_cnt == 0)
  			goto out;
  	}
95950c2ec   Steven Rostedt   ftrace: Add self-...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
  
  	DYN_FTRACE_TEST_NAME2();
  
  	print_counts();
  
  	if (trace_selftest_test_probe1_cnt != 1)
  		goto out;
  	if (trace_selftest_test_probe2_cnt != 1)
  		goto out;
  	if (trace_selftest_test_probe3_cnt != 2)
  		goto out;
  
  	/* Add a dynamic probe */
  	dyn_ops = kzalloc(sizeof(*dyn_ops), GFP_KERNEL);
  	if (!dyn_ops) {
  		printk("MEMORY ERROR ");
  		goto out;
  	}
  
  	dyn_ops->func = trace_selftest_test_dyn_func;
  
  	register_ftrace_function(dyn_ops);
  
  	trace_selftest_test_global_cnt = 0;
  
  	DYN_FTRACE_TEST_NAME();
  
  	print_counts();
  
  	if (trace_selftest_test_probe1_cnt != 2)
  		goto out_free;
  	if (trace_selftest_test_probe2_cnt != 1)
  		goto out_free;
  	if (trace_selftest_test_probe3_cnt != 3)
  		goto out_free;
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
269
270
271
272
  	if (cnt > 1) {
  		if (trace_selftest_test_global_cnt == 0)
  			goto out;
  	}
95950c2ec   Steven Rostedt   ftrace: Add self-...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
  	if (trace_selftest_test_dyn_cnt == 0)
  		goto out_free;
  
  	DYN_FTRACE_TEST_NAME2();
  
  	print_counts();
  
  	if (trace_selftest_test_probe1_cnt != 2)
  		goto out_free;
  	if (trace_selftest_test_probe2_cnt != 2)
  		goto out_free;
  	if (trace_selftest_test_probe3_cnt != 4)
  		goto out_free;
  
  	ret = 0;
   out_free:
  	unregister_ftrace_function(dyn_ops);
  	kfree(dyn_ops);
  
   out:
  	/* Purposely unregister in the same order */
  	unregister_ftrace_function(&test_probe1);
  	unregister_ftrace_function(&test_probe2);
  	unregister_ftrace_function(&test_probe3);
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
297
298
299
  	if (cnt > 1)
  		unregister_ftrace_function(tr->ops);
  	ftrace_reset_array_ops(tr);
95950c2ec   Steven Rostedt   ftrace: Add self-...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
  
  	/* Make sure everything is off */
  	reset_counts();
  	DYN_FTRACE_TEST_NAME();
  	DYN_FTRACE_TEST_NAME();
  
  	if (trace_selftest_test_probe1_cnt ||
  	    trace_selftest_test_probe2_cnt ||
  	    trace_selftest_test_probe3_cnt ||
  	    trace_selftest_test_global_cnt ||
  	    trace_selftest_test_dyn_cnt)
  		ret = -1;
  
  	ftrace_enabled = save_ftrace_enabled;
  
  	return ret;
  }
77a2b37d2   Steven Rostedt   ftrace: startup t...
317
  /* Test dynamic code modification and ftrace filters */
ad1438a07   Fabian Frederick   tracing: Add stat...
318
319
320
  static int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
  						  struct trace_array *tr,
  						  int (*func)(void))
77a2b37d2   Steven Rostedt   ftrace: startup t...
321
  {
77a2b37d2   Steven Rostedt   ftrace: startup t...
322
  	int save_ftrace_enabled = ftrace_enabled;
dd0e545f0   Steven Rostedt   ftrace: printk fo...
323
  	unsigned long count;
4e491d14f   Steven Rostedt   ftrace: support f...
324
  	char *func_name;
dd0e545f0   Steven Rostedt   ftrace: printk fo...
325
  	int ret;
77a2b37d2   Steven Rostedt   ftrace: startup t...
326
327
328
329
330
331
332
333
  
  	/* The ftrace test PASSED */
  	printk(KERN_CONT "PASSED
  ");
  	pr_info("Testing dynamic ftrace: ");
  
  	/* enable tracing, and record the filter function */
  	ftrace_enabled = 1;
77a2b37d2   Steven Rostedt   ftrace: startup t...
334
335
336
  
  	/* passed in by parameter to fool gcc from optimizing */
  	func();
4e491d14f   Steven Rostedt   ftrace: support f...
337
  	/*
73d8b8bc4   Wenji Huang   tracing: fix typi...
338
  	 * Some archs *cough*PowerPC*cough* add characters to the
4e491d14f   Steven Rostedt   ftrace: support f...
339
  	 * start of the function names. We simply put a '*' to
73d8b8bc4   Wenji Huang   tracing: fix typi...
340
  	 * accommodate them.
4e491d14f   Steven Rostedt   ftrace: support f...
341
  	 */
9cc26a261   Steven Rostedt   tracing: use gene...
342
  	func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
4e491d14f   Steven Rostedt   ftrace: support f...
343

77a2b37d2   Steven Rostedt   ftrace: startup t...
344
  	/* filter only on our function */
936e074b2   Steven Rostedt   ftrace: Modify ft...
345
  	ftrace_set_global_filter(func_name, strlen(func_name), 1);
77a2b37d2   Steven Rostedt   ftrace: startup t...
346
347
  
  	/* enable tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
348
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
349
350
351
352
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		goto out;
  	}
dd0e545f0   Steven Rostedt   ftrace: printk fo...
353

77a2b37d2   Steven Rostedt   ftrace: startup t...
354
355
356
357
  	/* Sleep for a 1/10 of a second */
  	msleep(100);
  
  	/* we should have nothing in the buffer */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
358
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
77a2b37d2   Steven Rostedt   ftrace: startup t...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  	if (ret)
  		goto out;
  
  	if (count) {
  		ret = -1;
  		printk(KERN_CONT ".. filter did not filter .. ");
  		goto out;
  	}
  
  	/* call our function again */
  	func();
  
  	/* sleep again */
  	msleep(100);
  
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
375
  	tracing_stop();
77a2b37d2   Steven Rostedt   ftrace: startup t...
376
377
378
  	ftrace_enabled = 0;
  
  	/* check the trace buffer */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
379
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
3ddee63a0   Steven Rostedt (Red Hat)   ftrace: Only disa...
380
381
  
  	ftrace_enabled = 1;
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
382
  	tracing_start();
77a2b37d2   Steven Rostedt   ftrace: startup t...
383
384
385
  
  	/* we should only have one item */
  	if (!ret && count != 1) {
95950c2ec   Steven Rostedt   ftrace: Add self-...
386
  		trace->reset(tr);
06fa75ab5   Steven Rostedt   ftrace: add TRACE...
387
  		printk(KERN_CONT ".. filter failed count=%ld ..", count);
77a2b37d2   Steven Rostedt   ftrace: startup t...
388
389
390
  		ret = -1;
  		goto out;
  	}
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
391

95950c2ec   Steven Rostedt   ftrace: Add self-...
392
  	/* Test the ops with global tracing running */
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
393
  	ret = trace_selftest_ops(tr, 1);
95950c2ec   Steven Rostedt   ftrace: Add self-...
394
  	trace->reset(tr);
77a2b37d2   Steven Rostedt   ftrace: startup t...
395
396
   out:
  	ftrace_enabled = save_ftrace_enabled;
77a2b37d2   Steven Rostedt   ftrace: startup t...
397
398
  
  	/* Enable tracing on all functions again */
936e074b2   Steven Rostedt   ftrace: Modify ft...
399
  	ftrace_set_global_filter(NULL, 0, 1);
77a2b37d2   Steven Rostedt   ftrace: startup t...
400

95950c2ec   Steven Rostedt   ftrace: Add self-...
401
402
  	/* Test the ops with global tracing off */
  	if (!ret)
4104d326b   Steven Rostedt (Red Hat)   ftrace: Remove gl...
403
  		ret = trace_selftest_ops(tr, 2);
95950c2ec   Steven Rostedt   ftrace: Add self-...
404

77a2b37d2   Steven Rostedt   ftrace: startup t...
405
406
  	return ret;
  }
ea701f11d   Steven Rostedt   ftrace: Add selft...
407
408
409
410
411
412
413
414
415
416
417
418
  
  static int trace_selftest_recursion_cnt;
  static void trace_selftest_test_recursion_func(unsigned long ip,
  					       unsigned long pip,
  					       struct ftrace_ops *op,
  					       struct pt_regs *pt_regs)
  {
  	/*
  	 * This function is registered without the recursion safe flag.
  	 * The ftrace infrastructure should provide the recursion
  	 * protection. If not, this will crash the kernel!
  	 */
9640388b6   Steven Rostedt   ftrace: Fix funct...
419
420
  	if (trace_selftest_recursion_cnt++ > 10)
  		return;
ea701f11d   Steven Rostedt   ftrace: Add selft...
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
  	DYN_FTRACE_TEST_NAME();
  }
  
  static void trace_selftest_test_recursion_safe_func(unsigned long ip,
  						    unsigned long pip,
  						    struct ftrace_ops *op,
  						    struct pt_regs *pt_regs)
  {
  	/*
  	 * We said we would provide our own recursion. By calling
  	 * this function again, we should recurse back into this function
  	 * and count again. But this only happens if the arch supports
  	 * all of ftrace features and nothing else is using the function
  	 * tracing utility.
  	 */
  	if (trace_selftest_recursion_cnt++)
  		return;
  	DYN_FTRACE_TEST_NAME();
  }
  
  static struct ftrace_ops test_rec_probe = {
  	.func			= trace_selftest_test_recursion_func,
  };
  
  static struct ftrace_ops test_recsafe_probe = {
  	.func			= trace_selftest_test_recursion_safe_func,
  	.flags			= FTRACE_OPS_FL_RECURSION_SAFE,
  };
  
  static int
  trace_selftest_function_recursion(void)
  {
  	int save_ftrace_enabled = ftrace_enabled;
ea701f11d   Steven Rostedt   ftrace: Add selft...
454
455
456
  	char *func_name;
  	int len;
  	int ret;
ea701f11d   Steven Rostedt   ftrace: Add selft...
457
458
459
460
461
462
463
464
465
  
  	/* The previous test PASSED */
  	pr_cont("PASSED
  ");
  	pr_info("Testing ftrace recursion: ");
  
  
  	/* enable tracing, and record the filter function */
  	ftrace_enabled = 1;
ea701f11d   Steven Rostedt   ftrace: Add selft...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
  
  	/* Handle PPC64 '.' name */
  	func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
  	len = strlen(func_name);
  
  	ret = ftrace_set_filter(&test_rec_probe, func_name, len, 1);
  	if (ret) {
  		pr_cont("*Could not set filter* ");
  		goto out;
  	}
  
  	ret = register_ftrace_function(&test_rec_probe);
  	if (ret) {
  		pr_cont("*could not register callback* ");
  		goto out;
  	}
  
  	DYN_FTRACE_TEST_NAME();
  
  	unregister_ftrace_function(&test_rec_probe);
  
  	ret = -1;
  	if (trace_selftest_recursion_cnt != 1) {
  		pr_cont("*callback not called once (%d)* ",
  			trace_selftest_recursion_cnt);
  		goto out;
  	}
  
  	trace_selftest_recursion_cnt = 1;
  
  	pr_cont("PASSED
  ");
  	pr_info("Testing ftrace recursion safe: ");
  
  	ret = ftrace_set_filter(&test_recsafe_probe, func_name, len, 1);
  	if (ret) {
  		pr_cont("*Could not set filter* ");
  		goto out;
  	}
  
  	ret = register_ftrace_function(&test_recsafe_probe);
  	if (ret) {
  		pr_cont("*could not register callback* ");
  		goto out;
  	}
  
  	DYN_FTRACE_TEST_NAME();
  
  	unregister_ftrace_function(&test_recsafe_probe);
ea701f11d   Steven Rostedt   ftrace: Add selft...
515
  	ret = -1;
05cbbf643   Steven Rostedt   tracing: Fix self...
516
517
518
  	if (trace_selftest_recursion_cnt != 2) {
  		pr_cont("*callback not called expected 2 times (%d)* ",
  			trace_selftest_recursion_cnt);
ea701f11d   Steven Rostedt   ftrace: Add selft...
519
520
521
522
523
524
  		goto out;
  	}
  
  	ret = 0;
  out:
  	ftrace_enabled = save_ftrace_enabled;
ea701f11d   Steven Rostedt   ftrace: Add selft...
525
526
527
  
  	return ret;
  }
77a2b37d2   Steven Rostedt   ftrace: startup t...
528
529
  #else
  # define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; })
ea701f11d   Steven Rostedt   ftrace: Add selft...
530
  # define trace_selftest_function_recursion() ({ 0; })
77a2b37d2   Steven Rostedt   ftrace: startup t...
531
  #endif /* CONFIG_DYNAMIC_FTRACE */
e9a22d1fb   Ingo Molnar   x86, bts: cleanups
532

ad97772ad   Steven Rostedt   ftrace: Add selft...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
  static enum {
  	TRACE_SELFTEST_REGS_START,
  	TRACE_SELFTEST_REGS_FOUND,
  	TRACE_SELFTEST_REGS_NOT_FOUND,
  } trace_selftest_regs_stat;
  
  static void trace_selftest_test_regs_func(unsigned long ip,
  					  unsigned long pip,
  					  struct ftrace_ops *op,
  					  struct pt_regs *pt_regs)
  {
  	if (pt_regs)
  		trace_selftest_regs_stat = TRACE_SELFTEST_REGS_FOUND;
  	else
  		trace_selftest_regs_stat = TRACE_SELFTEST_REGS_NOT_FOUND;
  }
  
  static struct ftrace_ops test_regs_probe = {
  	.func		= trace_selftest_test_regs_func,
  	.flags		= FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_SAVE_REGS,
  };
  
  static int
  trace_selftest_function_regs(void)
  {
  	int save_ftrace_enabled = ftrace_enabled;
ad97772ad   Steven Rostedt   ftrace: Add selft...
559
560
561
562
  	char *func_name;
  	int len;
  	int ret;
  	int supported = 0;
06aeaaeab   Masami Hiramatsu   ftrace: Move ARCH...
563
  #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
ad97772ad   Steven Rostedt   ftrace: Add selft...
564
565
566
567
568
569
570
571
572
573
574
  	supported = 1;
  #endif
  
  	/* The previous test PASSED */
  	pr_cont("PASSED
  ");
  	pr_info("Testing ftrace regs%s: ",
  		!supported ? "(no arch support)" : "");
  
  	/* enable tracing, and record the filter function */
  	ftrace_enabled = 1;
ad97772ad   Steven Rostedt   ftrace: Add selft...
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
  
  	/* Handle PPC64 '.' name */
  	func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
  	len = strlen(func_name);
  
  	ret = ftrace_set_filter(&test_regs_probe, func_name, len, 1);
  	/*
  	 * If DYNAMIC_FTRACE is not set, then we just trace all functions.
  	 * This test really doesn't care.
  	 */
  	if (ret && ret != -ENODEV) {
  		pr_cont("*Could not set filter* ");
  		goto out;
  	}
  
  	ret = register_ftrace_function(&test_regs_probe);
  	/*
  	 * Now if the arch does not support passing regs, then this should
  	 * have failed.
  	 */
  	if (!supported) {
  		if (!ret) {
  			pr_cont("*registered save-regs without arch support* ");
  			goto out;
  		}
  		test_regs_probe.flags |= FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED;
  		ret = register_ftrace_function(&test_regs_probe);
  	}
  	if (ret) {
  		pr_cont("*could not register callback* ");
  		goto out;
  	}
  
  
  	DYN_FTRACE_TEST_NAME();
  
  	unregister_ftrace_function(&test_regs_probe);
  
  	ret = -1;
  
  	switch (trace_selftest_regs_stat) {
  	case TRACE_SELFTEST_REGS_START:
  		pr_cont("*callback never called* ");
  		goto out;
  
  	case TRACE_SELFTEST_REGS_FOUND:
  		if (supported)
  			break;
  		pr_cont("*callback received regs without arch support* ");
  		goto out;
  
  	case TRACE_SELFTEST_REGS_NOT_FOUND:
  		if (!supported)
  			break;
  		pr_cont("*callback received NULL regs* ");
  		goto out;
  	}
  
  	ret = 0;
  out:
  	ftrace_enabled = save_ftrace_enabled;
ad97772ad   Steven Rostedt   ftrace: Add selft...
636
637
638
  
  	return ret;
  }
60a11774b   Steven Rostedt   ftrace: add self-...
639
640
641
642
643
  /*
   * Simple verification test of ftrace function tracer.
   * Enable ftrace, sleep 1/10 second, and then read the trace
   * buffer to see if all is in order.
   */
f1ed7c741   Steven Rostedt (Red Hat)   ftrace: Do not ru...
644
  __init int
60a11774b   Steven Rostedt   ftrace: add self-...
645
646
  trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
  {
77a2b37d2   Steven Rostedt   ftrace: startup t...
647
  	int save_ftrace_enabled = ftrace_enabled;
dd0e545f0   Steven Rostedt   ftrace: printk fo...
648
649
  	unsigned long count;
  	int ret;
60a11774b   Steven Rostedt   ftrace: add self-...
650

f1ed7c741   Steven Rostedt (Red Hat)   ftrace: Do not ru...
651
652
653
654
655
656
  #ifdef CONFIG_DYNAMIC_FTRACE
  	if (ftrace_filter_param) {
  		printk(KERN_CONT " ... kernel command line filter set: force PASS ... ");
  		return 0;
  	}
  #endif
77a2b37d2   Steven Rostedt   ftrace: startup t...
657
658
  	/* make sure msleep has been recorded */
  	msleep(1);
60a11774b   Steven Rostedt   ftrace: add self-...
659
  	/* start the tracing */
c7aafc549   Ingo Molnar   ftrace: cleanups
660
  	ftrace_enabled = 1;
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
661
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
662
663
664
665
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		goto out;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
666
667
668
  	/* Sleep for a 1/10 of a second */
  	msleep(100);
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
669
  	tracing_stop();
c7aafc549   Ingo Molnar   ftrace: cleanups
670
  	ftrace_enabled = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
671
  	/* check the trace buffer */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
672
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
3ddee63a0   Steven Rostedt (Red Hat)   ftrace: Only disa...
673
674
  
  	ftrace_enabled = 1;
60a11774b   Steven Rostedt   ftrace: add self-...
675
  	trace->reset(tr);
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
676
  	tracing_start();
60a11774b   Steven Rostedt   ftrace: add self-...
677
678
679
680
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
77a2b37d2   Steven Rostedt   ftrace: startup t...
681
  		goto out;
60a11774b   Steven Rostedt   ftrace: add self-...
682
  	}
77a2b37d2   Steven Rostedt   ftrace: startup t...
683
684
  	ret = trace_selftest_startup_dynamic_tracing(trace, tr,
  						     DYN_FTRACE_TEST_NAME);
ea701f11d   Steven Rostedt   ftrace: Add selft...
685
686
  	if (ret)
  		goto out;
77a2b37d2   Steven Rostedt   ftrace: startup t...
687

ea701f11d   Steven Rostedt   ftrace: Add selft...
688
  	ret = trace_selftest_function_recursion();
ad97772ad   Steven Rostedt   ftrace: Add selft...
689
690
691
692
  	if (ret)
  		goto out;
  
  	ret = trace_selftest_function_regs();
77a2b37d2   Steven Rostedt   ftrace: startup t...
693
694
   out:
  	ftrace_enabled = save_ftrace_enabled;
77a2b37d2   Steven Rostedt   ftrace: startup t...
695

4eebcc81a   Steven Rostedt   ftrace: disable t...
696
697
698
  	/* kill ftrace totally if we failed */
  	if (ret)
  		ftrace_kill();
60a11774b   Steven Rostedt   ftrace: add self-...
699
700
  	return ret;
  }
606576ce8   Steven Rostedt   ftrace: rename FT...
701
  #endif /* CONFIG_FUNCTION_TRACER */
60a11774b   Steven Rostedt   ftrace: add self-...
702

7447dce96   Frederic Weisbecker   tracing/function-...
703
704
  
  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
cf586b61f   Frederic Weisbecker   tracing/function-...
705
706
707
  
  /* Maximum number of functions to trace before diagnosing a hang */
  #define GRAPH_MAX_FUNC_TEST	100000000
cf586b61f   Frederic Weisbecker   tracing/function-...
708
709
710
711
712
713
714
715
716
717
  static unsigned int graph_hang_thresh;
  
  /* Wrap the real function entry probe to avoid possible hanging */
  static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
  {
  	/* This is harmlessly racy, we want to approximately detect a hang */
  	if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
  		ftrace_graph_stop();
  		printk(KERN_WARNING "BUG: Function graph tracer hang!
  ");
7fe70b579   Steven Rostedt (Red Hat)   tracing: Fix ftra...
718
719
720
721
722
  		if (ftrace_dump_on_oops) {
  			ftrace_dump(DUMP_ALL);
  			/* ftrace_dump() disables tracing */
  			tracing_on();
  		}
cf586b61f   Frederic Weisbecker   tracing/function-...
723
724
725
726
727
  		return 0;
  	}
  
  	return trace_graph_entry(trace);
  }
7447dce96   Frederic Weisbecker   tracing/function-...
728
729
730
731
  /*
   * Pretty much the same than for the function tracer from which the selftest
   * has been borrowed.
   */
f1ed7c741   Steven Rostedt (Red Hat)   ftrace: Do not ru...
732
  __init int
7447dce96   Frederic Weisbecker   tracing/function-...
733
734
735
736
737
  trace_selftest_startup_function_graph(struct tracer *trace,
  					struct trace_array *tr)
  {
  	int ret;
  	unsigned long count;
f1ed7c741   Steven Rostedt (Red Hat)   ftrace: Do not ru...
738
739
740
741
742
743
  #ifdef CONFIG_DYNAMIC_FTRACE
  	if (ftrace_filter_param) {
  		printk(KERN_CONT " ... kernel command line filter set: force PASS ... ");
  		return 0;
  	}
  #endif
cf586b61f   Frederic Weisbecker   tracing/function-...
744
745
746
747
  	/*
  	 * Simulate the init() callback but we attach a watchdog callback
  	 * to detect and recover from possible hangs
  	 */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
748
  	tracing_reset_online_cpus(&tr->trace_buffer);
1a0799a8f   Frederic Weisbecker   tracing/function-...
749
  	set_graph_array(tr);
cf586b61f   Frederic Weisbecker   tracing/function-...
750
751
  	ret = register_ftrace_graph(&trace_graph_return,
  				    &trace_graph_entry_watchdog);
7447dce96   Frederic Weisbecker   tracing/function-...
752
753
754
755
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		goto out;
  	}
cf586b61f   Frederic Weisbecker   tracing/function-...
756
  	tracing_start_cmdline_record();
7447dce96   Frederic Weisbecker   tracing/function-...
757
758
759
  
  	/* Sleep for a 1/10 of a second */
  	msleep(100);
cf586b61f   Frederic Weisbecker   tracing/function-...
760
761
  	/* Have we just recovered from a hang? */
  	if (graph_hang_thresh > GRAPH_MAX_FUNC_TEST) {
0cf53ff62   Frederic Weisbecker   tracing: keep the...
762
  		tracing_selftest_disabled = true;
cf586b61f   Frederic Weisbecker   tracing/function-...
763
764
765
  		ret = -1;
  		goto out;
  	}
7447dce96   Frederic Weisbecker   tracing/function-...
766
767
768
  	tracing_stop();
  
  	/* check the trace buffer */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
769
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
7447dce96   Frederic Weisbecker   tracing/function-...
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  
  	trace->reset(tr);
  	tracing_start();
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  		goto out;
  	}
  
  	/* Don't test dynamic tracing, the function tracer already did */
  
  out:
  	/* Stop it if we failed */
  	if (ret)
  		ftrace_graph_stop();
  
  	return ret;
  }
  #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
60a11774b   Steven Rostedt   ftrace: add self-...
790
791
792
793
  #ifdef CONFIG_IRQSOFF_TRACER
  int
  trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
  {
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
794
  	unsigned long save_max = tr->max_latency;
60a11774b   Steven Rostedt   ftrace: add self-...
795
796
797
798
  	unsigned long count;
  	int ret;
  
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
799
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
800
801
802
803
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		return ret;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
804
  	/* reset the max latency */
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
805
  	tr->max_latency = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
806
807
808
809
  	/* disable interrupts for a bit */
  	local_irq_disable();
  	udelay(100);
  	local_irq_enable();
490362003   Frederic Weisbecker   tracing/ftrace: s...
810
811
812
813
814
815
816
817
  
  	/*
  	 * Stop the tracer to avoid a warning subsequent
  	 * to buffer flipping failure because tracing_stop()
  	 * disables the tr and max buffers, making flipping impossible
  	 * in case of parallels max irqs off latencies.
  	 */
  	trace->stop(tr);
60a11774b   Steven Rostedt   ftrace: add self-...
818
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
819
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
820
  	/* check both trace buffers */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
821
  	ret = trace_test_buffer(&tr->trace_buffer, NULL);
60a11774b   Steven Rostedt   ftrace: add self-...
822
  	if (!ret)
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
823
  		ret = trace_test_buffer(&tr->max_buffer, &count);
60a11774b   Steven Rostedt   ftrace: add self-...
824
  	trace->reset(tr);
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
825
  	tracing_start();
60a11774b   Steven Rostedt   ftrace: add self-...
826
827
828
829
830
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  	}
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
831
  	tr->max_latency = save_max;
60a11774b   Steven Rostedt   ftrace: add self-...
832
833
834
835
836
837
838
839
840
  
  	return ret;
  }
  #endif /* CONFIG_IRQSOFF_TRACER */
  
  #ifdef CONFIG_PREEMPT_TRACER
  int
  trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
  {
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
841
  	unsigned long save_max = tr->max_latency;
60a11774b   Steven Rostedt   ftrace: add self-...
842
843
  	unsigned long count;
  	int ret;
769c48eb2   Steven Rostedt   ftrace: force pas...
844
845
846
847
848
849
850
851
852
853
854
855
  	/*
  	 * Now that the big kernel lock is no longer preemptable,
  	 * and this is called with the BKL held, it will always
  	 * fail. If preemption is already disabled, simply
  	 * pass the test. When the BKL is removed, or becomes
  	 * preemptible again, we will once again test this,
  	 * so keep it in.
  	 */
  	if (preempt_count()) {
  		printk(KERN_CONT "can not test ... force ");
  		return 0;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
856
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
857
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
858
859
860
861
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		return ret;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
862
  	/* reset the max latency */
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
863
  	tr->max_latency = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
864
865
866
867
  	/* disable preemption for a bit */
  	preempt_disable();
  	udelay(100);
  	preempt_enable();
490362003   Frederic Weisbecker   tracing/ftrace: s...
868
869
870
871
872
873
874
875
  
  	/*
  	 * Stop the tracer to avoid a warning subsequent
  	 * to buffer flipping failure because tracing_stop()
  	 * disables the tr and max buffers, making flipping impossible
  	 * in case of parallels max preempt off latencies.
  	 */
  	trace->stop(tr);
60a11774b   Steven Rostedt   ftrace: add self-...
876
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
877
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
878
  	/* check both trace buffers */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
879
  	ret = trace_test_buffer(&tr->trace_buffer, NULL);
60a11774b   Steven Rostedt   ftrace: add self-...
880
  	if (!ret)
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
881
  		ret = trace_test_buffer(&tr->max_buffer, &count);
60a11774b   Steven Rostedt   ftrace: add self-...
882
  	trace->reset(tr);
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
883
  	tracing_start();
60a11774b   Steven Rostedt   ftrace: add self-...
884
885
886
887
888
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  	}
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
889
  	tr->max_latency = save_max;
60a11774b   Steven Rostedt   ftrace: add self-...
890
891
892
893
894
895
896
897
898
  
  	return ret;
  }
  #endif /* CONFIG_PREEMPT_TRACER */
  
  #if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
  int
  trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *tr)
  {
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
899
  	unsigned long save_max = tr->max_latency;
60a11774b   Steven Rostedt   ftrace: add self-...
900
901
  	unsigned long count;
  	int ret;
769c48eb2   Steven Rostedt   ftrace: force pas...
902
903
904
905
906
907
908
909
910
911
912
913
  	/*
  	 * Now that the big kernel lock is no longer preemptable,
  	 * and this is called with the BKL held, it will always
  	 * fail. If preemption is already disabled, simply
  	 * pass the test. When the BKL is removed, or becomes
  	 * preemptible again, we will once again test this,
  	 * so keep it in.
  	 */
  	if (preempt_count()) {
  		printk(KERN_CONT "can not test ... force ");
  		return 0;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
914
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
915
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
916
917
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
ac1d52d0b   Frederic Weisbecker   tracing/ftrace: f...
918
  		goto out_no_start;
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
919
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
920
921
  
  	/* reset the max latency */
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
922
  	tr->max_latency = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
923
924
925
926
927
928
929
930
  
  	/* disable preemption and interrupts for a bit */
  	preempt_disable();
  	local_irq_disable();
  	udelay(100);
  	preempt_enable();
  	/* reverse the order of preempt vs irqs */
  	local_irq_enable();
490362003   Frederic Weisbecker   tracing/ftrace: s...
931
932
933
934
935
936
937
  	/*
  	 * Stop the tracer to avoid a warning subsequent
  	 * to buffer flipping failure because tracing_stop()
  	 * disables the tr and max buffers, making flipping impossible
  	 * in case of parallels max irqs/preempt off latencies.
  	 */
  	trace->stop(tr);
60a11774b   Steven Rostedt   ftrace: add self-...
938
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
939
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
940
  	/* check both trace buffers */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
941
  	ret = trace_test_buffer(&tr->trace_buffer, NULL);
ac1d52d0b   Frederic Weisbecker   tracing/ftrace: f...
942
  	if (ret)
60a11774b   Steven Rostedt   ftrace: add self-...
943
  		goto out;
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
944
  	ret = trace_test_buffer(&tr->max_buffer, &count);
ac1d52d0b   Frederic Weisbecker   tracing/ftrace: f...
945
  	if (ret)
60a11774b   Steven Rostedt   ftrace: add self-...
946
947
948
949
950
951
952
953
954
  		goto out;
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  		goto out;
  	}
  
  	/* do the test by disabling interrupts first this time */
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
955
  	tr->max_latency = 0;
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
956
  	tracing_start();
490362003   Frederic Weisbecker   tracing/ftrace: s...
957
  	trace->start(tr);
60a11774b   Steven Rostedt   ftrace: add self-...
958
959
960
961
962
963
  	preempt_disable();
  	local_irq_disable();
  	udelay(100);
  	preempt_enable();
  	/* reverse the order of preempt vs irqs */
  	local_irq_enable();
490362003   Frederic Weisbecker   tracing/ftrace: s...
964
  	trace->stop(tr);
60a11774b   Steven Rostedt   ftrace: add self-...
965
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
966
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
967
  	/* check both trace buffers */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
968
  	ret = trace_test_buffer(&tr->trace_buffer, NULL);
60a11774b   Steven Rostedt   ftrace: add self-...
969
970
  	if (ret)
  		goto out;
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
971
  	ret = trace_test_buffer(&tr->max_buffer, &count);
60a11774b   Steven Rostedt   ftrace: add self-...
972
973
974
975
976
977
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  		goto out;
  	}
ac1d52d0b   Frederic Weisbecker   tracing/ftrace: f...
978
  out:
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
979
  	tracing_start();
ac1d52d0b   Frederic Weisbecker   tracing/ftrace: f...
980
981
  out_no_start:
  	trace->reset(tr);
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
982
  	tr->max_latency = save_max;
60a11774b   Steven Rostedt   ftrace: add self-...
983
984
985
986
  
  	return ret;
  }
  #endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */
fb1b6d8b5   Steven Noonan   ftrace: add nop t...
987
988
989
990
991
992
993
994
  #ifdef CONFIG_NOP_TRACER
  int
  trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr)
  {
  	/* What could possibly go wrong? */
  	return 0;
  }
  #endif
60a11774b   Steven Rostedt   ftrace: add self-...
995
  #ifdef CONFIG_SCHED_TRACER
addff1feb   Steven Rostedt   tracing: Clean up...
996
997
998
999
1000
  
  struct wakeup_test_data {
  	struct completion	is_ready;
  	int			go;
  };
60a11774b   Steven Rostedt   ftrace: add self-...
1001
1002
  static int trace_wakeup_test_thread(void *data)
  {
af6ace764   Dario Faggioli   sched/deadline: A...
1003
1004
1005
1006
1007
1008
1009
  	/* Make this a -deadline thread */
  	static const struct sched_attr attr = {
  		.sched_policy = SCHED_DEADLINE,
  		.sched_runtime = 100000ULL,
  		.sched_deadline = 10000000ULL,
  		.sched_period = 10000000ULL
  	};
addff1feb   Steven Rostedt   tracing: Clean up...
1010
  	struct wakeup_test_data *x = data;
60a11774b   Steven Rostedt   ftrace: add self-...
1011

af6ace764   Dario Faggioli   sched/deadline: A...
1012
  	sched_setattr(current, &attr);
60a11774b   Steven Rostedt   ftrace: add self-...
1013
1014
  
  	/* Make it know we have a new prio */
addff1feb   Steven Rostedt   tracing: Clean up...
1015
  	complete(&x->is_ready);
60a11774b   Steven Rostedt   ftrace: add self-...
1016
1017
1018
  
  	/* now go to sleep and let the test wake us up */
  	set_current_state(TASK_INTERRUPTIBLE);
addff1feb   Steven Rostedt   tracing: Clean up...
1019
1020
1021
1022
  	while (!x->go) {
  		schedule();
  		set_current_state(TASK_INTERRUPTIBLE);
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
1023

addff1feb   Steven Rostedt   tracing: Clean up...
1024
1025
1026
  	complete(&x->is_ready);
  
  	set_current_state(TASK_INTERRUPTIBLE);
3c18c10bd   Steven Rostedt   tracing: Fix wake...
1027

60a11774b   Steven Rostedt   ftrace: add self-...
1028
1029
  	/* we are awake, now wait to disappear */
  	while (!kthread_should_stop()) {
addff1feb   Steven Rostedt   tracing: Clean up...
1030
1031
  		schedule();
  		set_current_state(TASK_INTERRUPTIBLE);
60a11774b   Steven Rostedt   ftrace: add self-...
1032
  	}
addff1feb   Steven Rostedt   tracing: Clean up...
1033
  	__set_current_state(TASK_RUNNING);
60a11774b   Steven Rostedt   ftrace: add self-...
1034
1035
  	return 0;
  }
60a11774b   Steven Rostedt   ftrace: add self-...
1036
1037
1038
  int
  trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
  {
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
1039
  	unsigned long save_max = tr->max_latency;
60a11774b   Steven Rostedt   ftrace: add self-...
1040
  	struct task_struct *p;
addff1feb   Steven Rostedt   tracing: Clean up...
1041
  	struct wakeup_test_data data;
60a11774b   Steven Rostedt   ftrace: add self-...
1042
1043
  	unsigned long count;
  	int ret;
addff1feb   Steven Rostedt   tracing: Clean up...
1044
1045
1046
  	memset(&data, 0, sizeof(data));
  
  	init_completion(&data.is_ready);
60a11774b   Steven Rostedt   ftrace: add self-...
1047

af6ace764   Dario Faggioli   sched/deadline: A...
1048
  	/* create a -deadline thread */
addff1feb   Steven Rostedt   tracing: Clean up...
1049
  	p = kthread_run(trace_wakeup_test_thread, &data, "ftrace-test");
c7aafc549   Ingo Molnar   ftrace: cleanups
1050
  	if (IS_ERR(p)) {
60a11774b   Steven Rostedt   ftrace: add self-...
1051
1052
1053
  		printk(KERN_CONT "Failed to create ftrace wakeup test thread ");
  		return -1;
  	}
af6ace764   Dario Faggioli   sched/deadline: A...
1054
  	/* make sure the thread is running at -deadline policy */
addff1feb   Steven Rostedt   tracing: Clean up...
1055
  	wait_for_completion(&data.is_ready);
60a11774b   Steven Rostedt   ftrace: add self-...
1056
1057
  
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
1058
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
1059
1060
1061
1062
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		return ret;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
1063
  	/* reset the max latency */
6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
1064
  	tr->max_latency = 0;
60a11774b   Steven Rostedt   ftrace: add self-...
1065

3c18c10bd   Steven Rostedt   tracing: Fix wake...
1066
1067
  	while (p->on_rq) {
  		/*
af6ace764   Dario Faggioli   sched/deadline: A...
1068
  		 * Sleep to make sure the -deadline thread is asleep too.
3c18c10bd   Steven Rostedt   tracing: Fix wake...
1069
1070
1071
1072
1073
  		 * On virtual machines we can't rely on timings,
  		 * but we want to make sure this test still works.
  		 */
  		msleep(100);
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
1074

addff1feb   Steven Rostedt   tracing: Clean up...
1075
1076
1077
1078
  	init_completion(&data.is_ready);
  
  	data.go = 1;
  	/* memory barrier is in the wake_up_process() */
60a11774b   Steven Rostedt   ftrace: add self-...
1079
1080
  
  	wake_up_process(p);
3c18c10bd   Steven Rostedt   tracing: Fix wake...
1081
  	/* Wait for the task to wake up */
addff1feb   Steven Rostedt   tracing: Clean up...
1082
  	wait_for_completion(&data.is_ready);
5aa60c607   Steven Rostedt   ftrace: give time...
1083

60a11774b   Steven Rostedt   ftrace: add self-...
1084
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
1085
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
1086
  	/* check both trace buffers */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
1087
  	ret = trace_test_buffer(&tr->trace_buffer, NULL);
60a11774b   Steven Rostedt   ftrace: add self-...
1088
  	if (!ret)
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
1089
  		ret = trace_test_buffer(&tr->max_buffer, &count);
60a11774b   Steven Rostedt   ftrace: add self-...
1090
1091
1092
  
  
  	trace->reset(tr);
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
1093
  	tracing_start();
60a11774b   Steven Rostedt   ftrace: add self-...
1094

6d9b3fa5e   Steven Rostedt (Red Hat)   tracing: Move tra...
1095
  	tr->max_latency = save_max;
60a11774b   Steven Rostedt   ftrace: add self-...
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
  
  	/* kill the thread */
  	kthread_stop(p);
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  	}
  
  	return ret;
  }
  #endif /* CONFIG_SCHED_TRACER */
  
  #ifdef CONFIG_CONTEXT_SWITCH_TRACER
  int
  trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr)
  {
  	unsigned long count;
  	int ret;
  
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
1117
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
1118
1119
1120
1121
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		return ret;
  	}
60a11774b   Steven Rostedt   ftrace: add self-...
1122
1123
1124
  	/* Sleep for a 1/10 of a second */
  	msleep(100);
  	/* stop the tracing. */
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
1125
  	tracing_stop();
60a11774b   Steven Rostedt   ftrace: add self-...
1126
  	/* check the trace buffer */
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
1127
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
60a11774b   Steven Rostedt   ftrace: add self-...
1128
  	trace->reset(tr);
bbf5b1a0c   Steven Rostedt   ftrace: remove ct...
1129
  	tracing_start();
60a11774b   Steven Rostedt   ftrace: add self-...
1130
1131
1132
1133
1134
1135
1136
1137
1138
  
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  	}
  
  	return ret;
  }
  #endif /* CONFIG_CONTEXT_SWITCH_TRACER */
a6dd24f8d   Ingo Molnar   ftrace: sysprof-p...
1139

80e5ea450   Steven Rostedt   ftrace: add trace...
1140
1141
1142
1143
1144
1145
1146
1147
  #ifdef CONFIG_BRANCH_TRACER
  int
  trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
  {
  	unsigned long count;
  	int ret;
  
  	/* start the tracing */
b6f11df26   Arnaldo Carvalho de Melo   trace: Call traci...
1148
  	ret = tracer_init(trace, tr);
1c80025a4   Frederic Weisbecker   tracing/ftrace: c...
1149
1150
1151
1152
  	if (ret) {
  		warn_failed_init_tracer(trace, ret);
  		return ret;
  	}
80e5ea450   Steven Rostedt   ftrace: add trace...
1153
1154
1155
1156
1157
  	/* Sleep for a 1/10 of a second */
  	msleep(100);
  	/* stop the tracing. */
  	tracing_stop();
  	/* check the trace buffer */
0184d50f9   Steven Rostedt (Red Hat)   tracing: Fix bad ...
1158
  	ret = trace_test_buffer(&tr->trace_buffer, &count);
80e5ea450   Steven Rostedt   ftrace: add trace...
1159
1160
  	trace->reset(tr);
  	tracing_start();
d2ef7c2f0   Wenji Huang   tracing: fix the ...
1161
1162
1163
1164
  	if (!ret && !count) {
  		printk(KERN_CONT ".. no entries found ..");
  		ret = -1;
  	}
80e5ea450   Steven Rostedt   ftrace: add trace...
1165
1166
1167
  	return ret;
  }
  #endif /* CONFIG_BRANCH_TRACER */
321bb5e1a   Markus Metzger   x86, hw-branch-tr...
1168