diff options
Diffstat (limited to 'kernel/trace/fgraph.c')
| -rw-r--r-- | kernel/trace/fgraph.c | 41 | 
1 files changed, 26 insertions, 15 deletions
diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index d7d4fb403f6f..69e226a48daa 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -1160,19 +1160,14 @@ void fgraph_update_pid_func(void)  static int start_graph_tracing(void)  {  	unsigned long **ret_stack_list; -	int ret, cpu; +	int ret; -	ret_stack_list = kmalloc(SHADOW_STACK_SIZE, GFP_KERNEL); +	ret_stack_list = kcalloc(FTRACE_RETSTACK_ALLOC_SIZE, +				 sizeof(*ret_stack_list), GFP_KERNEL);  	if (!ret_stack_list)  		return -ENOMEM; -	/* The cpu_boot init_task->ret_stack will never be freed */ -	for_each_online_cpu(cpu) { -		if (!idle_task(cpu)->ret_stack) -			ftrace_graph_init_idle_task(idle_task(cpu), cpu); -	} -  	do {  		ret = alloc_retstack_tasklist(ret_stack_list);  	} while (ret == -EAGAIN); @@ -1242,13 +1237,33 @@ static void ftrace_graph_disable_direct(bool disable_branch)  	fgraph_direct_gops = &fgraph_stub;  } +/* The cpu_boot init_task->ret_stack will never be freed */ +static int fgraph_cpu_init(unsigned int cpu) +{ +	if (!idle_task(cpu)->ret_stack) +		ftrace_graph_init_idle_task(idle_task(cpu), cpu); +	return 0; +} +  int register_ftrace_graph(struct fgraph_ops *gops)  { +	static bool fgraph_initialized;  	int command = 0;  	int ret = 0;  	int i = -1; -	mutex_lock(&ftrace_lock); +	guard(mutex)(&ftrace_lock); + +	if (!fgraph_initialized) { +		ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "fgraph:online", +					fgraph_cpu_init, NULL); +		if (ret < 0) { +			pr_warn("fgraph: Error to init cpu hotplug support\n"); +			return ret; +		} +		fgraph_initialized = true; +		ret = 0; +	}  	if (!fgraph_array[0]) {  		/* The array must always have real data on it */ @@ -1258,10 +1273,8 @@ int register_ftrace_graph(struct fgraph_ops *gops)  	}  	i = fgraph_lru_alloc_index(); -	if (i < 0 || WARN_ON_ONCE(fgraph_array[i] != &fgraph_stub)) { -		ret = -ENOSPC; -		goto out; -	} +	if (i < 0 || WARN_ON_ONCE(fgraph_array[i] != &fgraph_stub)) +		return -ENOSPC;  	gops->idx = i;  	ftrace_graph_active++; @@ -1298,8 +1311,6 @@ error:  		gops->saved_func = NULL;  		fgraph_lru_release_index(i);  	} -out: -	mutex_unlock(&ftrace_lock);  	return ret;  }  | 
