1 /* Include in trace.c */
3 #include <linux/kthread.h>
4 #include <linux/delay.h>
6 static inline int trace_valid_entry(struct trace_entry
*entry
)
17 trace_test_buffer_cpu(struct trace_array
*tr
, struct trace_array_cpu
*data
)
19 struct trace_entry
*entries
;
24 BUG_ON(list_empty(&data
->trace_pages
));
25 page
= list_entry(data
->trace_pages
.next
, struct page
, lru
);
26 entries
= page_address(page
);
28 if (head_page(data
) != entries
)
32 * The starting trace buffer always has valid elements,
33 * if any element exists.
35 entries
= head_page(data
);
37 for (i
= 0; i
< tr
->entries
; i
++) {
39 if (i
< data
->trace_idx
&& !trace_valid_entry(&entries
[idx
])) {
40 printk(KERN_CONT
".. invalid entry %d ",
46 if (idx
>= ENTRIES_PER_PAGE
) {
47 page
= virt_to_page(entries
);
48 if (page
->lru
.next
== &data
->trace_pages
) {
49 if (i
!= tr
->entries
- 1) {
50 printk(KERN_CONT
".. entries buffer mismatch");
54 page
= list_entry(page
->lru
.next
, struct page
, lru
);
55 entries
= page_address(page
);
61 page
= virt_to_page(entries
);
62 if (page
->lru
.next
!= &data
->trace_pages
) {
63 printk(KERN_CONT
".. too many entries");
72 printk(KERN_CONT
".. corrupted trace buffer .. ");
77 * Test the trace buffer to see if all the elements
80 static int trace_test_buffer(struct trace_array
*tr
, unsigned long *count
)
82 unsigned long cnt
= 0;
86 for_each_possible_cpu(cpu
) {
87 if (!head_page(tr
->data
[cpu
]))
90 cnt
+= tr
->data
[cpu
]->trace_idx
;
92 ret
= trace_test_buffer_cpu(tr
, tr
->data
[cpu
]);
105 #ifdef CONFIG_DYNAMIC_FTRACE
107 #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
109 #define STR(x) __STR(x)
110 static int DYN_FTRACE_TEST_NAME(void)
112 /* used to call mcount */
116 /* Test dynamic code modification and ftrace filters */
117 int trace_selftest_startup_dynamic_tracing(struct tracer
*trace
,
118 struct trace_array
*tr
,
123 int save_ftrace_enabled
= ftrace_enabled
;
124 int save_tracer_enabled
= tracer_enabled
;
126 /* The ftrace test PASSED */
127 printk(KERN_CONT
"PASSED\n");
128 pr_info("Testing dynamic ftrace: ");
130 /* enable tracing, and record the filter function */
134 /* passed in by parameter to fool gcc from optimizing */
137 /* update the records */
138 ret
= ftrace_force_update();
140 printk(KERN_CONT
".. ftraced failed .. ");
144 /* filter only on our function */
145 ftrace_set_filter(STR(DYN_FTRACE_TEST_NAME
),
146 sizeof(STR(DYN_FTRACE_TEST_NAME
)), 1);
151 /* Sleep for a 1/10 of a second */
154 /* we should have nothing in the buffer */
155 ret
= trace_test_buffer(tr
, &count
);
161 printk(KERN_CONT
".. filter did not filter .. ");
165 /* call our function again */
171 /* stop the tracing. */
173 trace
->ctrl_update(tr
);
176 /* check the trace buffer */
177 ret
= trace_test_buffer(tr
, &count
);
180 /* we should only have one item */
181 if (!ret
&& count
!= 1) {
182 printk(KERN_CONT
".. filter failed ..");
187 ftrace_enabled
= save_ftrace_enabled
;
188 tracer_enabled
= save_tracer_enabled
;
190 /* Enable tracing on all functions again */
191 ftrace_set_filter(NULL
, 0, 1);
196 # define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; })
197 #endif /* CONFIG_DYNAMIC_FTRACE */
199 * Simple verification test of ftrace function tracer.
200 * Enable ftrace, sleep 1/10 second, and then read the trace
201 * buffer to see if all is in order.
204 trace_selftest_startup_function(struct tracer
*trace
, struct trace_array
*tr
)
208 int save_ftrace_enabled
= ftrace_enabled
;
209 int save_tracer_enabled
= tracer_enabled
;
211 /* make sure msleep has been recorded */
214 /* force the recorded functions to be traced */
215 ret
= ftrace_force_update();
217 printk(KERN_CONT
".. ftraced failed .. ");
221 /* start the tracing */
227 /* Sleep for a 1/10 of a second */
229 /* stop the tracing. */
231 trace
->ctrl_update(tr
);
234 /* check the trace buffer */
235 ret
= trace_test_buffer(tr
, &count
);
238 if (!ret
&& !count
) {
239 printk(KERN_CONT
".. no entries found ..");
244 ret
= trace_selftest_startup_dynamic_tracing(trace
, tr
,
245 DYN_FTRACE_TEST_NAME
);
248 ftrace_enabled
= save_ftrace_enabled
;
249 tracer_enabled
= save_tracer_enabled
;
253 #endif /* CONFIG_FTRACE */
255 #ifdef CONFIG_IRQSOFF_TRACER
257 trace_selftest_startup_irqsoff(struct tracer
*trace
, struct trace_array
*tr
)
259 unsigned long save_max
= tracing_max_latency
;
263 /* start the tracing */
266 /* reset the max latency */
267 tracing_max_latency
= 0;
268 /* disable interrupts for a bit */
272 /* stop the tracing. */
274 trace
->ctrl_update(tr
);
275 /* check both trace buffers */
276 ret
= trace_test_buffer(tr
, NULL
);
278 ret
= trace_test_buffer(&max_tr
, &count
);
281 if (!ret
&& !count
) {
282 printk(KERN_CONT
".. no entries found ..");
286 tracing_max_latency
= save_max
;
290 #endif /* CONFIG_IRQSOFF_TRACER */
292 #ifdef CONFIG_PREEMPT_TRACER
294 trace_selftest_startup_preemptoff(struct tracer
*trace
, struct trace_array
*tr
)
296 unsigned long save_max
= tracing_max_latency
;
300 /* start the tracing */
303 /* reset the max latency */
304 tracing_max_latency
= 0;
305 /* disable preemption for a bit */
309 /* stop the tracing. */
311 trace
->ctrl_update(tr
);
312 /* check both trace buffers */
313 ret
= trace_test_buffer(tr
, NULL
);
315 ret
= trace_test_buffer(&max_tr
, &count
);
318 if (!ret
&& !count
) {
319 printk(KERN_CONT
".. no entries found ..");
323 tracing_max_latency
= save_max
;
327 #endif /* CONFIG_PREEMPT_TRACER */
329 #if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
331 trace_selftest_startup_preemptirqsoff(struct tracer
*trace
, struct trace_array
*tr
)
333 unsigned long save_max
= tracing_max_latency
;
337 /* start the tracing */
341 /* reset the max latency */
342 tracing_max_latency
= 0;
344 /* disable preemption and interrupts for a bit */
349 /* reverse the order of preempt vs irqs */
352 /* stop the tracing. */
354 trace
->ctrl_update(tr
);
355 /* check both trace buffers */
356 ret
= trace_test_buffer(tr
, NULL
);
360 ret
= trace_test_buffer(&max_tr
, &count
);
364 if (!ret
&& !count
) {
365 printk(KERN_CONT
".. no entries found ..");
370 /* do the test by disabling interrupts first this time */
371 tracing_max_latency
= 0;
373 trace
->ctrl_update(tr
);
378 /* reverse the order of preempt vs irqs */
381 /* stop the tracing. */
383 trace
->ctrl_update(tr
);
384 /* check both trace buffers */
385 ret
= trace_test_buffer(tr
, NULL
);
389 ret
= trace_test_buffer(&max_tr
, &count
);
391 if (!ret
&& !count
) {
392 printk(KERN_CONT
".. no entries found ..");
399 tracing_max_latency
= save_max
;
403 #endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */
405 #ifdef CONFIG_SCHED_TRACER
406 static int trace_wakeup_test_thread(void *data
)
408 struct completion
*x
= data
;
410 /* Make this a RT thread, doesn't need to be too high */
412 rt_mutex_setprio(current
, MAX_RT_PRIO
- 5);
414 /* Make it know we have a new prio */
417 /* now go to sleep and let the test wake us up */
418 set_current_state(TASK_INTERRUPTIBLE
);
421 /* we are awake, now wait to disappear */
422 while (!kthread_should_stop()) {
424 * This is an RT task, do short sleeps to let
434 trace_selftest_startup_wakeup(struct tracer
*trace
, struct trace_array
*tr
)
436 unsigned long save_max
= tracing_max_latency
;
437 struct task_struct
*p
;
438 struct completion isrt
;
442 init_completion(&isrt
);
444 /* create a high prio thread */
445 p
= kthread_run(trace_wakeup_test_thread
, &isrt
, "ftrace-test");
447 printk(KERN_CONT
"Failed to create ftrace wakeup test thread ");
451 /* make sure the thread is running at an RT prio */
452 wait_for_completion(&isrt
);
454 /* start the tracing */
457 /* reset the max latency */
458 tracing_max_latency
= 0;
460 /* sleep to let the RT thread sleep too */
464 * Yes this is slightly racy. It is possible that for some
465 * strange reason that the RT thread we created, did not
466 * call schedule for 100ms after doing the completion,
467 * and we do a wakeup on a task that already is awake.
468 * But that is extremely unlikely, and the worst thing that
469 * happens in such a case, is that we disable tracing.
470 * Honestly, if this race does happen something is horrible
471 * wrong with the system.
476 /* stop the tracing. */
478 trace
->ctrl_update(tr
);
479 /* check both trace buffers */
480 ret
= trace_test_buffer(tr
, NULL
);
482 ret
= trace_test_buffer(&max_tr
, &count
);
487 tracing_max_latency
= save_max
;
489 /* kill the thread */
492 if (!ret
&& !count
) {
493 printk(KERN_CONT
".. no entries found ..");
499 #endif /* CONFIG_SCHED_TRACER */
501 #ifdef CONFIG_CONTEXT_SWITCH_TRACER
503 trace_selftest_startup_sched_switch(struct tracer
*trace
, struct trace_array
*tr
)
508 /* start the tracing */
511 /* Sleep for a 1/10 of a second */
513 /* stop the tracing. */
515 trace
->ctrl_update(tr
);
516 /* check the trace buffer */
517 ret
= trace_test_buffer(tr
, &count
);
520 if (!ret
&& !count
) {
521 printk(KERN_CONT
".. no entries found ..");
527 #endif /* CONFIG_CONTEXT_SWITCH_TRACER */