mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 22:40:53 +07:00
ftrace: Fix en(dis)able graph caller when en(dis)abling record via sysctl
When ftrace is enabled globally through the proc interface, we must check if ftrace_graph_active is set. If it is set, then we should also pass the FTRACE_START_FUNC_RET command to ftrace_run_update_code(). Similarly, when ftrace is disabled globally through the proc interface, we must check if ftrace_graph_active is set. If it is set, then we should also pass the FTRACE_STOP_FUNC_RET command to ftrace_run_update_code(). Consider the following situation. # echo 0 > /proc/sys/kernel/ftrace_enabled After this ftrace_enabled = 0. # echo function_graph > /sys/kernel/debug/tracing/current_tracer Since ftrace_enabled = 0, ftrace_enable_ftrace_graph_caller() is never called. # echo 1 > /proc/sys/kernel/ftrace_enabled Now ftrace_enabled will be set to true, but still ftrace_enable_ftrace_graph_caller() will not be called, which is not desired. Further if we execute the following after this: # echo nop > /sys/kernel/debug/tracing/current_tracer Now since ftrace_enabled is set it will call ftrace_disable_ftrace_graph_caller(), which causes a kernel warning on the ARM platform. On the ARM platform, when ftrace_enable_ftrace_graph_caller() is called, it checks whether the old instruction is a nop or not. If it's not a nop, then it returns an error. If it is a nop then it replaces instruction at that address with a branch to ftrace_graph_caller. ftrace_disable_ftrace_graph_caller() behaves just the opposite. Therefore, if generic ftrace code ever calls either ftrace_enable_ftrace_graph_caller() or ftrace_disable_ftrace_graph_caller() consecutively two times in a row, then it will return an error, which will cause the generic ftrace code to raise a warning. Note, x86 does not have an issue with this because the architecture specific code for ftrace_enable_ftrace_graph_caller() and ftrace_disable_ftrace_graph_caller() does not check the previous state, and calling either of these functions twice in a row has no ill effect. Link: http://lkml.kernel.org/r/e4fbe64cdac0dd0e86a3bf914b0f83c0b419f146.1425666454.git.panand@redhat.com Cc: stable@vger.kernel.org # 2.6.31+ Signed-off-by: Pratyush Anand <panand@redhat.com> [ removed extra if (ftrace_start_up) and defined ftrace_graph_active as 0 if CONFIG_FUNCTION_GRAPH_TRACER is not set. ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
b24d443b8f
commit
1619dc3f8f
@ -1059,6 +1059,12 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
|
||||
|
||||
static struct pid * const ftrace_swapper_pid = &init_struct_pid;
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
static int ftrace_graph_active;
|
||||
#else
|
||||
# define ftrace_graph_active 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
static struct ftrace_ops *removed_ops;
|
||||
@ -2692,24 +2698,36 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
|
||||
|
||||
static void ftrace_startup_sysctl(void)
|
||||
{
|
||||
int command;
|
||||
|
||||
if (unlikely(ftrace_disabled))
|
||||
return;
|
||||
|
||||
/* Force update next time */
|
||||
saved_ftrace_func = NULL;
|
||||
/* ftrace_start_up is true if we want ftrace running */
|
||||
if (ftrace_start_up)
|
||||
ftrace_run_update_code(FTRACE_UPDATE_CALLS);
|
||||
if (ftrace_start_up) {
|
||||
command = FTRACE_UPDATE_CALLS;
|
||||
if (ftrace_graph_active)
|
||||
command |= FTRACE_START_FUNC_RET;
|
||||
ftrace_run_update_code(command);
|
||||
}
|
||||
}
|
||||
|
||||
static void ftrace_shutdown_sysctl(void)
|
||||
{
|
||||
int command;
|
||||
|
||||
if (unlikely(ftrace_disabled))
|
||||
return;
|
||||
|
||||
/* ftrace_start_up is true if ftrace is running */
|
||||
if (ftrace_start_up)
|
||||
ftrace_run_update_code(FTRACE_DISABLE_CALLS);
|
||||
if (ftrace_start_up) {
|
||||
command = FTRACE_DISABLE_CALLS;
|
||||
if (ftrace_graph_active)
|
||||
command |= FTRACE_STOP_FUNC_RET;
|
||||
ftrace_run_update_code(command);
|
||||
}
|
||||
}
|
||||
|
||||
static cycle_t ftrace_update_time;
|
||||
@ -5594,8 +5612,6 @@ static struct ftrace_ops graph_ops = {
|
||||
ASSIGN_OPS_HASH(graph_ops, &global_ops.local_hash)
|
||||
};
|
||||
|
||||
static int ftrace_graph_active;
|
||||
|
||||
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
|
||||
{
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user