浏览代码

ftrace: Warn on error when modifying ftrace function

We should print some warning and kill ftrace functionality when the ftrace
function is not set correctly. Otherwise, ftrace might do crazy things without
an explanation. The error value has been ignored so far.

Note that an error that happens during updating all the traced calls is handled
in ftrace_replace_code(). We print more details about the particular
failing address via ftrace_bug() there.

Link: http://lkml.kernel.org/r/1393258342-29978-3-git-send-email-pmladek@suse.cz

Signed-off-by: Petr Mladek <pmladek@suse.cz>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Petr Mladek 11 年之前
父节点
当前提交
cd21067f69
共有 1 个文件被更改,包括 12 次插入5 次删除
  1. 12 5
      kernel/trace/ftrace.c

+ 12 - 5
kernel/trace/ftrace.c

@@ -1994,6 +1994,7 @@ int __weak ftrace_arch_code_modify_post_process(void)
 void ftrace_modify_all_code(int command)
 void ftrace_modify_all_code(int command)
 {
 {
 	int update = command & FTRACE_UPDATE_TRACE_FUNC;
 	int update = command & FTRACE_UPDATE_TRACE_FUNC;
+	int err = 0;
 
 
 	/*
 	/*
 	 * If the ftrace_caller calls a ftrace_ops func directly,
 	 * If the ftrace_caller calls a ftrace_ops func directly,
@@ -2005,8 +2006,11 @@ void ftrace_modify_all_code(int command)
 	 * to make sure the ops are having the right functions
 	 * to make sure the ops are having the right functions
 	 * traced.
 	 * traced.
 	 */
 	 */
-	if (update)
-		ftrace_update_ftrace_func(ftrace_ops_list_func);
+	if (update) {
+		err = ftrace_update_ftrace_func(ftrace_ops_list_func);
+		if (FTRACE_WARN_ON(err))
+			return;
+	}
 
 
 	if (command & FTRACE_UPDATE_CALLS)
 	if (command & FTRACE_UPDATE_CALLS)
 		ftrace_replace_code(1);
 		ftrace_replace_code(1);
@@ -2019,13 +2023,16 @@ void ftrace_modify_all_code(int command)
 		/* If irqs are disabled, we are in stop machine */
 		/* If irqs are disabled, we are in stop machine */
 		if (!irqs_disabled())
 		if (!irqs_disabled())
 			smp_call_function(ftrace_sync_ipi, NULL, 1);
 			smp_call_function(ftrace_sync_ipi, NULL, 1);
-		ftrace_update_ftrace_func(ftrace_trace_function);
+		err = ftrace_update_ftrace_func(ftrace_trace_function);
+		if (FTRACE_WARN_ON(err))
+			return;
 	}
 	}
 
 
 	if (command & FTRACE_START_FUNC_RET)
 	if (command & FTRACE_START_FUNC_RET)
-		ftrace_enable_ftrace_graph_caller();
+		err = ftrace_enable_ftrace_graph_caller();
 	else if (command & FTRACE_STOP_FUNC_RET)
 	else if (command & FTRACE_STOP_FUNC_RET)
-		ftrace_disable_ftrace_graph_caller();
+		err = ftrace_disable_ftrace_graph_caller();
+	FTRACE_WARN_ON(err);
 }
 }
 
 
 static int __ftrace_modify_code(void *data)
 static int __ftrace_modify_code(void *data)