aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2008-11-25 18:57:25 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-25 19:59:45 -0500
commit287b6e68ca7209caec40b2f44f837c580a413bae (patch)
treeb0867d75868f6049dc5747bd39fdae2d477dde66 /include/linux
parentfb52607afcd0629776f1dc9e657647ceae81dd50 (diff)
tracing/function-return-tracer: set a more human readable output
Impact: feature This patch sets a C-like output for the function graph tracing. For this aim, we now call two handler for each function: one on the entry and one other on return. This way we can draw a well-ordered call stack. The pid of the previous trace is loosely stored to be compared against the one of the current trace to see if there were a context switch. Without this little feature, the call tree would seem broken at some locations. We could use the sched_tracer to capture these sched_events but this way of processing is much more simpler. 2 spaces have been chosen for indentation to fit the screen while deep calls. The time of execution in nanosecs is printed just after closed braces, it seems more easy this way to find the corresponding function. If the time was printed as a first column, it would be not so easy to find the corresponding function if it is called on a deep depth. I plan to output the return value but on 32 bits CPU, the return value can be 32 or 64, and its difficult to guess on which case we are. I don't know what would be the better solution on X86-32: only print eax (low-part) or even edx (high-part). Actually it's thee same problem when a function return a 8 bits value, the high part of eax could contain junk values... Here is an example of trace: sys_read() { fget_light() { } 526 vfs_read() { rw_verify_area() { security_file_permission() { cap_file_permission() { } 519 } 1564 } 2640 do_sync_read() { pipe_read() { __might_sleep() { } 511 pipe_wait() { prepare_to_wait() { } 760 deactivate_task() { dequeue_task() { dequeue_task_fair() { dequeue_entity() { update_curr() { update_min_vruntime() { } 504 } 1587 clear_buddies() { } 512 add_cfs_task_weight() { } 519 update_min_vruntime() { } 511 } 5602 dequeue_entity() { update_curr() { update_min_vruntime() { } 496 } 1631 clear_buddies() { } 496 update_min_vruntime() { } 527 } 4580 hrtick_update() { hrtick_start_fair() { } 488 } 1489 } 13700 } 14949 } 16016 msecs_to_jiffies() { } 496 put_prev_task_fair() { } 504 pick_next_task_fair() { } 489 pick_next_task_rt() { } 496 pick_next_task_fair() { } 489 pick_next_task_idle() { } 489 ------------8<---------- thread 4 ------------8<---------- finish_task_switch() { } 1203 do_softirq() { __do_softirq() { __local_bh_disable() { } 669 rcu_process_callbacks() { __rcu_process_callbacks() { cpu_quiet() { rcu_start_batch() { } 503 } 1647 } 3128 __rcu_process_callbacks() { } 542 } 5362 _local_bh_enable() { } 587 } 8880 } 9986 kthread_should_stop() { } 669 deactivate_task() { dequeue_task() { dequeue_task_fair() { dequeue_entity() { update_curr() { calc_delta_mine() { } 511 update_min_vruntime() { } 511 } 2813 Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ftrace.h25
1 files changed, 19 insertions, 6 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index b4ac734ad8d6..fc2d54987198 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -313,26 +313,39 @@ ftrace_init_module(struct module *mod,
313 313
314 314
315/* 315/*
316 * Structure that defines an entry function trace.
317 */
318struct ftrace_graph_ent {
319 unsigned long func; /* Current function */
320 int depth;
321};
322
323/*
316 * Structure that defines a return function trace. 324 * Structure that defines a return function trace.
317 */ 325 */
318struct ftrace_graph_ret { 326struct ftrace_graph_ret {
319 unsigned long ret; /* Return address */
320 unsigned long func; /* Current function */ 327 unsigned long func; /* Current function */
321 unsigned long long calltime; 328 unsigned long long calltime;
322 unsigned long long rettime; 329 unsigned long long rettime;
323 /* Number of functions that overran the depth limit for current task */ 330 /* Number of functions that overran the depth limit for current task */
324 unsigned long overrun; 331 unsigned long overrun;
332 int depth;
325}; 333};
326 334
327#ifdef CONFIG_FUNCTION_GRAPH_TRACER 335#ifdef CONFIG_FUNCTION_GRAPH_TRACER
328#define FTRACE_RETFUNC_DEPTH 50 336#define FTRACE_RETFUNC_DEPTH 50
329#define FTRACE_RETSTACK_ALLOC_SIZE 32 337#define FTRACE_RETSTACK_ALLOC_SIZE 32
330/* Type of a callback handler of tracing return function */ 338/* Type of the callback handlers for tracing function graph*/
331typedef void (*trace_function_graph_t)(struct ftrace_graph_ret *); 339typedef void (*trace_func_graph_ret_t)(struct ftrace_graph_ret *); /* return */
340typedef void (*trace_func_graph_ent_t)(struct ftrace_graph_ent *); /* entry */
341
342extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
343 trace_func_graph_ent_t entryfunc);
344
345/* The current handlers in use */
346extern trace_func_graph_ret_t ftrace_graph_return;
347extern trace_func_graph_ent_t ftrace_graph_entry;
332 348
333extern int register_ftrace_graph(trace_function_graph_t func);
334/* The current handler in use */
335extern trace_function_graph_t ftrace_graph_function;
336extern void unregister_ftrace_graph(void); 349extern void unregister_ftrace_graph(void);
337 350
338extern void ftrace_graph_init_task(struct task_struct *t); 351extern void ftrace_graph_init_task(struct task_struct *t);