ftrace: Consolidate arch dependent functions with 'list' function
[deliverable/linux.git] / kernel / trace / trace_selftest.c
CommitLineData
60a11774
SR
1/* Include in trace.c */
2
9cc26a26 3#include <linux/stringify.h>
60a11774 4#include <linux/kthread.h>
c7aafc54 5#include <linux/delay.h>
5a0e3ad6 6#include <linux/slab.h>
60a11774 7
e309b41d 8static inline int trace_valid_entry(struct trace_entry *entry)
60a11774
SR
9{
10 switch (entry->type) {
11 case TRACE_FN:
12 case TRACE_CTX:
57422797 13 case TRACE_WAKE:
06fa75ab 14 case TRACE_STACK:
dd0e545f 15 case TRACE_PRINT:
80e5ea45 16 case TRACE_BRANCH:
7447dce9
FW
17 case TRACE_GRAPH_ENT:
18 case TRACE_GRAPH_RET:
60a11774
SR
19 return 1;
20 }
21 return 0;
22}
23
3928a8a2 24static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
60a11774 25{
3928a8a2
SR
26 struct ring_buffer_event *event;
27 struct trace_entry *entry;
4b3e3d22 28 unsigned int loops = 0;
60a11774 29
66a8cb95 30 while ((event = ring_buffer_consume(tr->buffer, cpu, NULL, NULL))) {
3928a8a2 31 entry = ring_buffer_event_data(event);
60a11774 32
4b3e3d22
SR
33 /*
34 * The ring buffer is a size of trace_buf_size, if
35 * we loop more than the size, there's something wrong
36 * with the ring buffer.
37 */
38 if (loops++ > trace_buf_size) {
39 printk(KERN_CONT ".. bad ring buffer ");
40 goto failed;
41 }
3928a8a2 42 if (!trace_valid_entry(entry)) {
c7aafc54 43 printk(KERN_CONT ".. invalid entry %d ",
3928a8a2 44 entry->type);
60a11774
SR
45 goto failed;
46 }
60a11774 47 }
60a11774
SR
48 return 0;
49
50 failed:
08bafa0e
SR
51 /* disable tracing */
52 tracing_disabled = 1;
60a11774
SR
53 printk(KERN_CONT ".. corrupted trace buffer .. ");
54 return -1;
55}
56
57/*
58 * Test the trace buffer to see if all the elements
59 * are still sane.
60 */
61static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
62{
30afdcb1
SR
63 unsigned long flags, cnt = 0;
64 int cpu, ret = 0;
60a11774 65
30afdcb1 66 /* Don't allow flipping of max traces now */
d51ad7ac 67 local_irq_save(flags);
0199c4e6 68 arch_spin_lock(&ftrace_max_lock);
60a11774 69
3928a8a2 70 cnt = ring_buffer_entries(tr->buffer);
60a11774 71
0c5119c1
SR
72 /*
73 * The trace_test_buffer_cpu runs a while loop to consume all data.
74 * If the calling tracer is broken, and is constantly filling
75 * the buffer, this will run forever, and hard lock the box.
76 * We disable the ring buffer while we do this test to prevent
77 * a hard lock up.
78 */
79 tracing_off();
3928a8a2
SR
80 for_each_possible_cpu(cpu) {
81 ret = trace_test_buffer_cpu(tr, cpu);
60a11774
SR
82 if (ret)
83 break;
84 }
0c5119c1 85 tracing_on();
0199c4e6 86 arch_spin_unlock(&ftrace_max_lock);
d51ad7ac 87 local_irq_restore(flags);
60a11774
SR
88
89 if (count)
90 *count = cnt;
91
92 return ret;
93}
94
1c80025a
FW
95static inline void warn_failed_init_tracer(struct tracer *trace, int init_ret)
96{
97 printk(KERN_WARNING "Failed to init %s tracer, init returned %d\n",
98 trace->name, init_ret);
99}
606576ce 100#ifdef CONFIG_FUNCTION_TRACER
77a2b37d
SR
101
102#ifdef CONFIG_DYNAMIC_FTRACE
103
95950c2e
SR
104static int trace_selftest_test_probe1_cnt;
105static void trace_selftest_test_probe1_func(unsigned long ip,
2f5f6ad9
SR
106 unsigned long pip,
107 struct ftrace_ops *op)
95950c2e
SR
108{
109 trace_selftest_test_probe1_cnt++;
110}
111
112static int trace_selftest_test_probe2_cnt;
113static void trace_selftest_test_probe2_func(unsigned long ip,
2f5f6ad9
SR
114 unsigned long pip,
115 struct ftrace_ops *op)
95950c2e
SR
116{
117 trace_selftest_test_probe2_cnt++;
118}
119
120static int trace_selftest_test_probe3_cnt;
121static void trace_selftest_test_probe3_func(unsigned long ip,
2f5f6ad9
SR
122 unsigned long pip,
123 struct ftrace_ops *op)
95950c2e
SR
124{
125 trace_selftest_test_probe3_cnt++;
126}
127
128static int trace_selftest_test_global_cnt;
129static void trace_selftest_test_global_func(unsigned long ip,
2f5f6ad9
SR
130 unsigned long pip,
131 struct ftrace_ops *op)
95950c2e
SR
132{
133 trace_selftest_test_global_cnt++;
134}
135
136static int trace_selftest_test_dyn_cnt;
137static void trace_selftest_test_dyn_func(unsigned long ip,
2f5f6ad9
SR
138 unsigned long pip,
139 struct ftrace_ops *op)
95950c2e
SR
140{
141 trace_selftest_test_dyn_cnt++;
142}
143
144static struct ftrace_ops test_probe1 = {
145 .func = trace_selftest_test_probe1_func,
146};
147
148static struct ftrace_ops test_probe2 = {
149 .func = trace_selftest_test_probe2_func,
150};
151
152static struct ftrace_ops test_probe3 = {
153 .func = trace_selftest_test_probe3_func,
154};
155
156static struct ftrace_ops test_global = {
157 .func = trace_selftest_test_global_func,
158 .flags = FTRACE_OPS_FL_GLOBAL,
159};
160
161static void print_counts(void)
162{
163 printk("(%d %d %d %d %d) ",
164 trace_selftest_test_probe1_cnt,
165 trace_selftest_test_probe2_cnt,
166 trace_selftest_test_probe3_cnt,
167 trace_selftest_test_global_cnt,
168 trace_selftest_test_dyn_cnt);
169}
170
171static void reset_counts(void)
172{
173 trace_selftest_test_probe1_cnt = 0;
174 trace_selftest_test_probe2_cnt = 0;
175 trace_selftest_test_probe3_cnt = 0;
176 trace_selftest_test_global_cnt = 0;
177 trace_selftest_test_dyn_cnt = 0;
178}
179
180static int trace_selftest_ops(int cnt)
181{
182 int save_ftrace_enabled = ftrace_enabled;
183 struct ftrace_ops *dyn_ops;
184 char *func1_name;
185 char *func2_name;
186 int len1;
187 int len2;
188 int ret = -1;
189
190 printk(KERN_CONT "PASSED\n");
191 pr_info("Testing dynamic ftrace ops #%d: ", cnt);
192
193 ftrace_enabled = 1;
194 reset_counts();
195
196 /* Handle PPC64 '.' name */
197 func1_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
198 func2_name = "*" __stringify(DYN_FTRACE_TEST_NAME2);
199 len1 = strlen(func1_name);
200 len2 = strlen(func2_name);
201
202 /*
203 * Probe 1 will trace function 1.
204 * Probe 2 will trace function 2.
205 * Probe 3 will trace functions 1 and 2.
206 */
207 ftrace_set_filter(&test_probe1, func1_name, len1, 1);
208 ftrace_set_filter(&test_probe2, func2_name, len2, 1);
209 ftrace_set_filter(&test_probe3, func1_name, len1, 1);
210 ftrace_set_filter(&test_probe3, func2_name, len2, 0);
211
212 register_ftrace_function(&test_probe1);
213 register_ftrace_function(&test_probe2);
214 register_ftrace_function(&test_probe3);
215 register_ftrace_function(&test_global);
216
217 DYN_FTRACE_TEST_NAME();
218
219 print_counts();
220
221 if (trace_selftest_test_probe1_cnt != 1)
222 goto out;
223 if (trace_selftest_test_probe2_cnt != 0)
224 goto out;
225 if (trace_selftest_test_probe3_cnt != 1)
226 goto out;
227 if (trace_selftest_test_global_cnt == 0)
228 goto out;
229
230 DYN_FTRACE_TEST_NAME2();
231
232 print_counts();
233
234 if (trace_selftest_test_probe1_cnt != 1)
235 goto out;
236 if (trace_selftest_test_probe2_cnt != 1)
237 goto out;
238 if (trace_selftest_test_probe3_cnt != 2)
239 goto out;
240
241 /* Add a dynamic probe */
242 dyn_ops = kzalloc(sizeof(*dyn_ops), GFP_KERNEL);
243 if (!dyn_ops) {
244 printk("MEMORY ERROR ");
245 goto out;
246 }
247
248 dyn_ops->func = trace_selftest_test_dyn_func;
249
250 register_ftrace_function(dyn_ops);
251
252 trace_selftest_test_global_cnt = 0;
253
254 DYN_FTRACE_TEST_NAME();
255
256 print_counts();
257
258 if (trace_selftest_test_probe1_cnt != 2)
259 goto out_free;
260 if (trace_selftest_test_probe2_cnt != 1)
261 goto out_free;
262 if (trace_selftest_test_probe3_cnt != 3)
263 goto out_free;
264 if (trace_selftest_test_global_cnt == 0)
265 goto out;
266 if (trace_selftest_test_dyn_cnt == 0)
267 goto out_free;
268
269 DYN_FTRACE_TEST_NAME2();
270
271 print_counts();
272
273 if (trace_selftest_test_probe1_cnt != 2)
274 goto out_free;
275 if (trace_selftest_test_probe2_cnt != 2)
276 goto out_free;
277 if (trace_selftest_test_probe3_cnt != 4)
278 goto out_free;
279
280 ret = 0;
281 out_free:
282 unregister_ftrace_function(dyn_ops);
283 kfree(dyn_ops);
284
285 out:
286 /* Purposely unregister in the same order */
287 unregister_ftrace_function(&test_probe1);
288 unregister_ftrace_function(&test_probe2);
289 unregister_ftrace_function(&test_probe3);
290 unregister_ftrace_function(&test_global);
291
292 /* Make sure everything is off */
293 reset_counts();
294 DYN_FTRACE_TEST_NAME();
295 DYN_FTRACE_TEST_NAME();
296
297 if (trace_selftest_test_probe1_cnt ||
298 trace_selftest_test_probe2_cnt ||
299 trace_selftest_test_probe3_cnt ||
300 trace_selftest_test_global_cnt ||
301 trace_selftest_test_dyn_cnt)
302 ret = -1;
303
304 ftrace_enabled = save_ftrace_enabled;
305
306 return ret;
307}
308
77a2b37d
SR
309/* Test dynamic code modification and ftrace filters */
310int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
311 struct trace_array *tr,
312 int (*func)(void))
313{
77a2b37d
SR
314 int save_ftrace_enabled = ftrace_enabled;
315 int save_tracer_enabled = tracer_enabled;
dd0e545f 316 unsigned long count;
4e491d14 317 char *func_name;
dd0e545f 318 int ret;
77a2b37d
SR
319
320 /* The ftrace test PASSED */
321 printk(KERN_CONT "PASSED\n");
322 pr_info("Testing dynamic ftrace: ");
323
324 /* enable tracing, and record the filter function */
325 ftrace_enabled = 1;
326 tracer_enabled = 1;
327
328 /* passed in by parameter to fool gcc from optimizing */
329 func();
330
4e491d14 331 /*
73d8b8bc 332 * Some archs *cough*PowerPC*cough* add characters to the
4e491d14 333 * start of the function names. We simply put a '*' to
73d8b8bc 334 * accommodate them.
4e491d14 335 */
9cc26a26 336 func_name = "*" __stringify(DYN_FTRACE_TEST_NAME);
4e491d14 337
77a2b37d 338 /* filter only on our function */
936e074b 339 ftrace_set_global_filter(func_name, strlen(func_name), 1);
77a2b37d
SR
340
341 /* enable tracing */
b6f11df2 342 ret = tracer_init(trace, tr);
1c80025a
FW
343 if (ret) {
344 warn_failed_init_tracer(trace, ret);
345 goto out;
346 }
dd0e545f 347
77a2b37d
SR
348 /* Sleep for a 1/10 of a second */
349 msleep(100);
350
351 /* we should have nothing in the buffer */
352 ret = trace_test_buffer(tr, &count);
353 if (ret)
354 goto out;
355
356 if (count) {
357 ret = -1;
358 printk(KERN_CONT ".. filter did not filter .. ");
359 goto out;
360 }
361
362 /* call our function again */
363 func();
364
365 /* sleep again */
366 msleep(100);
367
368 /* stop the tracing. */
bbf5b1a0 369 tracing_stop();
77a2b37d
SR
370 ftrace_enabled = 0;
371
372 /* check the trace buffer */
373 ret = trace_test_buffer(tr, &count);
bbf5b1a0 374 tracing_start();
77a2b37d
SR
375
376 /* we should only have one item */
377 if (!ret && count != 1) {
95950c2e 378 trace->reset(tr);
06fa75ab 379 printk(KERN_CONT ".. filter failed count=%ld ..", count);
77a2b37d
SR
380 ret = -1;
381 goto out;
382 }
bbf5b1a0 383
95950c2e
SR
384 /* Test the ops with global tracing running */
385 ret = trace_selftest_ops(1);
386 trace->reset(tr);
387
77a2b37d
SR
388 out:
389 ftrace_enabled = save_ftrace_enabled;
390 tracer_enabled = save_tracer_enabled;
391
392 /* Enable tracing on all functions again */
936e074b 393 ftrace_set_global_filter(NULL, 0, 1);
77a2b37d 394
95950c2e
SR
395 /* Test the ops with global tracing off */
396 if (!ret)
397 ret = trace_selftest_ops(2);
398
77a2b37d
SR
399 return ret;
400}
401#else
402# define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; })
403#endif /* CONFIG_DYNAMIC_FTRACE */
e9a22d1f 404
60a11774
SR
405/*
406 * Simple verification test of ftrace function tracer.
407 * Enable ftrace, sleep 1/10 second, and then read the trace
408 * buffer to see if all is in order.
409 */
410int
411trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
412{
77a2b37d
SR
413 int save_ftrace_enabled = ftrace_enabled;
414 int save_tracer_enabled = tracer_enabled;
dd0e545f
SR
415 unsigned long count;
416 int ret;
60a11774 417
77a2b37d
SR
418 /* make sure msleep has been recorded */
419 msleep(1);
420
60a11774 421 /* start the tracing */
c7aafc54 422 ftrace_enabled = 1;
77a2b37d 423 tracer_enabled = 1;
c7aafc54 424
b6f11df2 425 ret = tracer_init(trace, tr);
1c80025a
FW
426 if (ret) {
427 warn_failed_init_tracer(trace, ret);
428 goto out;
429 }
430
60a11774
SR
431 /* Sleep for a 1/10 of a second */
432 msleep(100);
433 /* stop the tracing. */
bbf5b1a0 434 tracing_stop();
c7aafc54
IM
435 ftrace_enabled = 0;
436
60a11774
SR
437 /* check the trace buffer */
438 ret = trace_test_buffer(tr, &count);
439 trace->reset(tr);
bbf5b1a0 440 tracing_start();
60a11774
SR
441
442 if (!ret && !count) {
443 printk(KERN_CONT ".. no entries found ..");
444 ret = -1;
77a2b37d 445 goto out;
60a11774
SR
446 }
447
77a2b37d
SR
448 ret = trace_selftest_startup_dynamic_tracing(trace, tr,
449 DYN_FTRACE_TEST_NAME);
450
451 out:
452 ftrace_enabled = save_ftrace_enabled;
453 tracer_enabled = save_tracer_enabled;
454
4eebcc81
SR
455 /* kill ftrace totally if we failed */
456 if (ret)
457 ftrace_kill();
458
60a11774
SR
459 return ret;
460}
606576ce 461#endif /* CONFIG_FUNCTION_TRACER */
60a11774 462
7447dce9
FW
463
464#ifdef CONFIG_FUNCTION_GRAPH_TRACER
cf586b61
FW
465
466/* Maximum number of functions to trace before diagnosing a hang */
467#define GRAPH_MAX_FUNC_TEST 100000000
468
cecbca96
FW
469static void
470__ftrace_dump(bool disable_tracing, enum ftrace_dump_mode oops_dump_mode);
cf586b61
FW
471static unsigned int graph_hang_thresh;
472
473/* Wrap the real function entry probe to avoid possible hanging */
474static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace)
475{
476 /* This is harmlessly racy, we want to approximately detect a hang */
477 if (unlikely(++graph_hang_thresh > GRAPH_MAX_FUNC_TEST)) {
478 ftrace_graph_stop();
479 printk(KERN_WARNING "BUG: Function graph tracer hang!\n");
480 if (ftrace_dump_on_oops)
cecbca96 481 __ftrace_dump(false, DUMP_ALL);
cf586b61
FW
482 return 0;
483 }
484
485 return trace_graph_entry(trace);
486}
487
7447dce9
FW
488/*
489 * Pretty much the same than for the function tracer from which the selftest
490 * has been borrowed.
491 */
492int
493trace_selftest_startup_function_graph(struct tracer *trace,
494 struct trace_array *tr)
495{
496 int ret;
497 unsigned long count;
498
cf586b61
FW
499 /*
500 * Simulate the init() callback but we attach a watchdog callback
501 * to detect and recover from possible hangs
502 */
503 tracing_reset_online_cpus(tr);
1a0799a8 504 set_graph_array(tr);
cf586b61
FW
505 ret = register_ftrace_graph(&trace_graph_return,
506 &trace_graph_entry_watchdog);
7447dce9
FW
507 if (ret) {
508 warn_failed_init_tracer(trace, ret);
509 goto out;
510 }
cf586b61 511 tracing_start_cmdline_record();
7447dce9
FW
512
513 /* Sleep for a 1/10 of a second */
514 msleep(100);
515
cf586b61
FW
516 /* Have we just recovered from a hang? */
517 if (graph_hang_thresh > GRAPH_MAX_FUNC_TEST) {
0cf53ff6 518 tracing_selftest_disabled = true;
cf586b61
FW
519 ret = -1;
520 goto out;
521 }
522
7447dce9
FW
523 tracing_stop();
524
525 /* check the trace buffer */
526 ret = trace_test_buffer(tr, &count);
527
528 trace->reset(tr);
529 tracing_start();
530
531 if (!ret && !count) {
532 printk(KERN_CONT ".. no entries found ..");
533 ret = -1;
534 goto out;
535 }
536
537 /* Don't test dynamic tracing, the function tracer already did */
538
539out:
540 /* Stop it if we failed */
541 if (ret)
542 ftrace_graph_stop();
543
544 return ret;
545}
546#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
547
548
60a11774
SR
549#ifdef CONFIG_IRQSOFF_TRACER
550int
551trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
552{
553 unsigned long save_max = tracing_max_latency;
554 unsigned long count;
555 int ret;
556
557 /* start the tracing */
b6f11df2 558 ret = tracer_init(trace, tr);
1c80025a
FW
559 if (ret) {
560 warn_failed_init_tracer(trace, ret);
561 return ret;
562 }
563
60a11774
SR
564 /* reset the max latency */
565 tracing_max_latency = 0;
566 /* disable interrupts for a bit */
567 local_irq_disable();
568 udelay(100);
569 local_irq_enable();
49036200
FW
570
571 /*
572 * Stop the tracer to avoid a warning subsequent
573 * to buffer flipping failure because tracing_stop()
574 * disables the tr and max buffers, making flipping impossible
575 * in case of parallels max irqs off latencies.
576 */
577 trace->stop(tr);
60a11774 578 /* stop the tracing. */
bbf5b1a0 579 tracing_stop();
60a11774
SR
580 /* check both trace buffers */
581 ret = trace_test_buffer(tr, NULL);
582 if (!ret)
583 ret = trace_test_buffer(&max_tr, &count);
584 trace->reset(tr);
bbf5b1a0 585 tracing_start();
60a11774
SR
586
587 if (!ret && !count) {
588 printk(KERN_CONT ".. no entries found ..");
589 ret = -1;
590 }
591
592 tracing_max_latency = save_max;
593
594 return ret;
595}
596#endif /* CONFIG_IRQSOFF_TRACER */
597
598#ifdef CONFIG_PREEMPT_TRACER
599int
600trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
601{
602 unsigned long save_max = tracing_max_latency;
603 unsigned long count;
604 int ret;
605
769c48eb
SR
606 /*
607 * Now that the big kernel lock is no longer preemptable,
608 * and this is called with the BKL held, it will always
609 * fail. If preemption is already disabled, simply
610 * pass the test. When the BKL is removed, or becomes
611 * preemptible again, we will once again test this,
612 * so keep it in.
613 */
614 if (preempt_count()) {
615 printk(KERN_CONT "can not test ... force ");
616 return 0;
617 }
618
60a11774 619 /* start the tracing */
b6f11df2 620 ret = tracer_init(trace, tr);
1c80025a
FW
621 if (ret) {
622 warn_failed_init_tracer(trace, ret);
623 return ret;
624 }
625
60a11774
SR
626 /* reset the max latency */
627 tracing_max_latency = 0;
628 /* disable preemption for a bit */
629 preempt_disable();
630 udelay(100);
631 preempt_enable();
49036200
FW
632
633 /*
634 * Stop the tracer to avoid a warning subsequent
635 * to buffer flipping failure because tracing_stop()
636 * disables the tr and max buffers, making flipping impossible
637 * in case of parallels max preempt off latencies.
638 */
639 trace->stop(tr);
60a11774 640 /* stop the tracing. */
bbf5b1a0 641 tracing_stop();
60a11774
SR
642 /* check both trace buffers */
643 ret = trace_test_buffer(tr, NULL);
644 if (!ret)
645 ret = trace_test_buffer(&max_tr, &count);
646 trace->reset(tr);
bbf5b1a0 647 tracing_start();
60a11774
SR
648
649 if (!ret && !count) {
650 printk(KERN_CONT ".. no entries found ..");
651 ret = -1;
652 }
653
654 tracing_max_latency = save_max;
655
656 return ret;
657}
658#endif /* CONFIG_PREEMPT_TRACER */
659
660#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
661int
662trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *tr)
663{
664 unsigned long save_max = tracing_max_latency;
665 unsigned long count;
666 int ret;
667
769c48eb
SR
668 /*
669 * Now that the big kernel lock is no longer preemptable,
670 * and this is called with the BKL held, it will always
671 * fail. If preemption is already disabled, simply
672 * pass the test. When the BKL is removed, or becomes
673 * preemptible again, we will once again test this,
674 * so keep it in.
675 */
676 if (preempt_count()) {
677 printk(KERN_CONT "can not test ... force ");
678 return 0;
679 }
680
60a11774 681 /* start the tracing */
b6f11df2 682 ret = tracer_init(trace, tr);
1c80025a
FW
683 if (ret) {
684 warn_failed_init_tracer(trace, ret);
ac1d52d0 685 goto out_no_start;
1c80025a 686 }
60a11774
SR
687
688 /* reset the max latency */
689 tracing_max_latency = 0;
690
691 /* disable preemption and interrupts for a bit */
692 preempt_disable();
693 local_irq_disable();
694 udelay(100);
695 preempt_enable();
696 /* reverse the order of preempt vs irqs */
697 local_irq_enable();
698
49036200
FW
699 /*
700 * Stop the tracer to avoid a warning subsequent
701 * to buffer flipping failure because tracing_stop()
702 * disables the tr and max buffers, making flipping impossible
703 * in case of parallels max irqs/preempt off latencies.
704 */
705 trace->stop(tr);
60a11774 706 /* stop the tracing. */
bbf5b1a0 707 tracing_stop();
60a11774
SR
708 /* check both trace buffers */
709 ret = trace_test_buffer(tr, NULL);
ac1d52d0 710 if (ret)
60a11774
SR
711 goto out;
712
713 ret = trace_test_buffer(&max_tr, &count);
ac1d52d0 714 if (ret)
60a11774
SR
715 goto out;
716
717 if (!ret && !count) {
718 printk(KERN_CONT ".. no entries found ..");
719 ret = -1;
720 goto out;
721 }
722
723 /* do the test by disabling interrupts first this time */
724 tracing_max_latency = 0;
bbf5b1a0 725 tracing_start();
49036200
FW
726 trace->start(tr);
727
60a11774
SR
728 preempt_disable();
729 local_irq_disable();
730 udelay(100);
731 preempt_enable();
732 /* reverse the order of preempt vs irqs */
733 local_irq_enable();
734
49036200 735 trace->stop(tr);
60a11774 736 /* stop the tracing. */
bbf5b1a0 737 tracing_stop();
60a11774
SR
738 /* check both trace buffers */
739 ret = trace_test_buffer(tr, NULL);
740 if (ret)
741 goto out;
742
743 ret = trace_test_buffer(&max_tr, &count);
744
745 if (!ret && !count) {
746 printk(KERN_CONT ".. no entries found ..");
747 ret = -1;
748 goto out;
749 }
750
ac1d52d0 751out:
bbf5b1a0 752 tracing_start();
ac1d52d0
FW
753out_no_start:
754 trace->reset(tr);
60a11774
SR
755 tracing_max_latency = save_max;
756
757 return ret;
758}
759#endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */
760
fb1b6d8b
SN
761#ifdef CONFIG_NOP_TRACER
762int
763trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr)
764{
765 /* What could possibly go wrong? */
766 return 0;
767}
768#endif
769
60a11774
SR
770#ifdef CONFIG_SCHED_TRACER
771static int trace_wakeup_test_thread(void *data)
772{
60a11774 773 /* Make this a RT thread, doesn't need to be too high */
c9b5f501 774 static const struct sched_param param = { .sched_priority = 5 };
05bd68c5 775 struct completion *x = data;
60a11774 776
05bd68c5 777 sched_setscheduler(current, SCHED_FIFO, &param);
60a11774
SR
778
779 /* Make it know we have a new prio */
780 complete(x);
781
782 /* now go to sleep and let the test wake us up */
783 set_current_state(TASK_INTERRUPTIBLE);
784 schedule();
785
786 /* we are awake, now wait to disappear */
787 while (!kthread_should_stop()) {
788 /*
789 * This is an RT task, do short sleeps to let
790 * others run.
791 */
792 msleep(100);
793 }
794
795 return 0;
796}
797
798int
799trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
800{
801 unsigned long save_max = tracing_max_latency;
802 struct task_struct *p;
803 struct completion isrt;
804 unsigned long count;
805 int ret;
806
807 init_completion(&isrt);
808
809 /* create a high prio thread */
810 p = kthread_run(trace_wakeup_test_thread, &isrt, "ftrace-test");
c7aafc54 811 if (IS_ERR(p)) {
60a11774
SR
812 printk(KERN_CONT "Failed to create ftrace wakeup test thread ");
813 return -1;
814 }
815
816 /* make sure the thread is running at an RT prio */
817 wait_for_completion(&isrt);
818
819 /* start the tracing */
b6f11df2 820 ret = tracer_init(trace, tr);
1c80025a
FW
821 if (ret) {
822 warn_failed_init_tracer(trace, ret);
823 return ret;
824 }
825
60a11774
SR
826 /* reset the max latency */
827 tracing_max_latency = 0;
828
829 /* sleep to let the RT thread sleep too */
830 msleep(100);
831
832 /*
833 * Yes this is slightly racy. It is possible that for some
834 * strange reason that the RT thread we created, did not
835 * call schedule for 100ms after doing the completion,
836 * and we do a wakeup on a task that already is awake.
837 * But that is extremely unlikely, and the worst thing that
838 * happens in such a case, is that we disable tracing.
839 * Honestly, if this race does happen something is horrible
840 * wrong with the system.
841 */
842
843 wake_up_process(p);
844
5aa60c60
SR
845 /* give a little time to let the thread wake up */
846 msleep(100);
847
60a11774 848 /* stop the tracing. */
bbf5b1a0 849 tracing_stop();
60a11774
SR
850 /* check both trace buffers */
851 ret = trace_test_buffer(tr, NULL);
852 if (!ret)
853 ret = trace_test_buffer(&max_tr, &count);
854
855
856 trace->reset(tr);
bbf5b1a0 857 tracing_start();
60a11774
SR
858
859 tracing_max_latency = save_max;
860
861 /* kill the thread */
862 kthread_stop(p);
863
864 if (!ret && !count) {
865 printk(KERN_CONT ".. no entries found ..");
866 ret = -1;
867 }
868
869 return ret;
870}
871#endif /* CONFIG_SCHED_TRACER */
872
873#ifdef CONFIG_CONTEXT_SWITCH_TRACER
874int
875trace_selftest_startup_sched_switch(struct tracer *trace, struct trace_array *tr)
876{
877 unsigned long count;
878 int ret;
879
880 /* start the tracing */
b6f11df2 881 ret = tracer_init(trace, tr);
1c80025a
FW
882 if (ret) {
883 warn_failed_init_tracer(trace, ret);
884 return ret;
885 }
886
60a11774
SR
887 /* Sleep for a 1/10 of a second */
888 msleep(100);
889 /* stop the tracing. */
bbf5b1a0 890 tracing_stop();
60a11774
SR
891 /* check the trace buffer */
892 ret = trace_test_buffer(tr, &count);
893 trace->reset(tr);
bbf5b1a0 894 tracing_start();
60a11774
SR
895
896 if (!ret && !count) {
897 printk(KERN_CONT ".. no entries found ..");
898 ret = -1;
899 }
900
901 return ret;
902}
903#endif /* CONFIG_CONTEXT_SWITCH_TRACER */
a6dd24f8 904
80e5ea45
SR
905#ifdef CONFIG_BRANCH_TRACER
906int
907trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
908{
909 unsigned long count;
910 int ret;
911
912 /* start the tracing */
b6f11df2 913 ret = tracer_init(trace, tr);
1c80025a
FW
914 if (ret) {
915 warn_failed_init_tracer(trace, ret);
916 return ret;
917 }
918
80e5ea45
SR
919 /* Sleep for a 1/10 of a second */
920 msleep(100);
921 /* stop the tracing. */
922 tracing_stop();
923 /* check the trace buffer */
924 ret = trace_test_buffer(tr, &count);
925 trace->reset(tr);
926 tracing_start();
927
d2ef7c2f
WH
928 if (!ret && !count) {
929 printk(KERN_CONT ".. no entries found ..");
930 ret = -1;
931 }
932
80e5ea45
SR
933 return ret;
934}
935#endif /* CONFIG_BRANCH_TRACER */
321bb5e1 936
This page took 0.267503 seconds and 5 git commands to generate.