aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-06-02 12:03:19 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-06-02 12:03:19 -0400
commit179c498ae2998461fe436437a74dc29036fc7dcc (patch)
tree7794227a9cc45c2ec22d3e3b3062a96d34e8b0b9
parent88fc86c283d9c3854e67e4155808027bc2519eb6 (diff)
function-graph: only allocate init tasks if it was not already done
When the function graph tracer is enabled, it calls the initialization needed for the init tasks that would be called on all created tasks. The problem is that this is called every time the function graph tracer is enabled, and the ret_stack is allocated for the idle tasks each time. Thus, the old ret_stack is lost and a memory leak is created. This is also dangerous because if an interrupt happened on another CPU with the init task and the ret_stack is replaced, we then lose all the return pointers for the interrupt, and a crash would take place. [ Impact: fix memory leak and possible crash due to race ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--kernel/trace/ftrace.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f1ed080406c3..ebff62ef40be 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2643,8 +2643,10 @@ static int start_graph_tracing(void)
2643 return -ENOMEM; 2643 return -ENOMEM;
2644 2644
2645 /* The cpu_boot init_task->ret_stack will never be freed */ 2645 /* The cpu_boot init_task->ret_stack will never be freed */
2646 for_each_online_cpu(cpu) 2646 for_each_online_cpu(cpu) {
2647 ftrace_graph_init_task(idle_task(cpu)); 2647 if (!idle_task(cpu)->ret_stack)
2648 ftrace_graph_init_task(idle_task(cpu));
2649 }
2648 2650
2649 do { 2651 do {
2650 ret = alloc_retstack_tasklist(ret_stack_list); 2652 ret = alloc_retstack_tasklist(ret_stack_list);