This is a note to let you know that I've just added the patch titled ftrace: Fix synchronization location disabling and freeing ftrace_ops to the 3.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: ftrace-fix-synchronization-location-disabling-and-freeing-ftrace_ops.patch and it can be found in the queue-3.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From rostedt@xxxxxxxxxxx Tue Feb 18 14:19:05 2014 From: Steven Rostedt <rostedt@xxxxxxxxxxx> Date: Tue, 11 Feb 2014 14:49:37 -0500 Subject: ftrace: Fix synchronization location disabling and freeing ftrace_ops To: Steven Rostedt <rostedt@xxxxxxxxxxx> Cc: Greg KH <gregkh@xxxxxxxxxxxxxxxxxxx>, stable@xxxxxxxxxxxxxxx, stable-commits@xxxxxxxxxxxxxxx Message-ID: <20140211144937.43d87cf8@xxxxxxxxxxxxxxxxxx> From: Steven Rostedt <rostedt@xxxxxxxxxxx> commit a4c35ed241129dd142be4cadb1e5a474a56d5464 upstream. The synchronization needed after ftrace_ops are unregistered must happen after the callback is disabled from becing called by functions. The current location happens after the function is being removed from the internal lists, but not after the function callbacks were disabled, leaving the functions susceptible of being called after their callbacks are freed. This affects perf and any externel users of function tracing (LTTng and SystemTap). Fixes: cdbe61bfe704 "ftrace: Allow dynamically allocated function tracers" Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- kernel/trace/ftrace.c | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -376,16 +376,6 @@ static int __unregister_ftrace_function( } else if (ops->flags & FTRACE_OPS_FL_CONTROL) { ret = remove_ftrace_list_ops(&ftrace_control_list, &control_ops, ops); - if (!ret) { - /* - * The ftrace_ops is now removed from the list, - * so there'll be no new users. We must ensure - * all current users are done before we free - * the control data. - */ - synchronize_sched(); - control_ops_free(ops); - } } else ret = remove_ftrace_ops(&ftrace_ops_list, ops); @@ -395,13 +385,6 @@ static int __unregister_ftrace_function( if (ftrace_enabled) update_ftrace_function(); - /* - * Dynamic ops may be freed, we must make sure that all - * callers are done before leaving this function. - */ - if (ops->flags & FTRACE_OPS_FL_DYNAMIC) - synchronize_sched(); - return 0; } @@ -2025,10 +2008,41 @@ static int ftrace_shutdown(struct ftrace command |= FTRACE_UPDATE_TRACE_FUNC; } - if (!command || !ftrace_enabled) + if (!command || !ftrace_enabled) { + /* + * If these are control ops, they still need their + * per_cpu field freed. Since, function tracing is + * not currently active, we can just free them + * without synchronizing all CPUs. + */ + if (ops->flags & FTRACE_OPS_FL_CONTROL) + control_ops_free(ops); return 0; + } ftrace_run_update_code(command); + + /* + * Dynamic ops may be freed, we must make sure that all + * callers are done before leaving this function. + * The same goes for freeing the per_cpu data of the control + * ops. + * + * Again, normal synchronize_sched() is not good enough. + * We need to do a hard force of sched synchronization. + * This is because we use preempt_disable() to do RCU, but + * the function tracers can be called where RCU is not watching + * (like before user_exit()). We can not rely on the RCU + * infrastructure to do the synchronization, thus we must do it + * ourselves. + */ + if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) { + schedule_on_each_cpu(ftrace_sync); + + if (ops->flags & FTRACE_OPS_FL_CONTROL) + control_ops_free(ops); + } + return 0; } Patches currently in stable-queue which might be from rostedt@xxxxxxxxxxx are queue-3.4/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch queue-3.4/ftrace-synchronize-setting-function_trace_op-with-ftrace_trace_function.patch queue-3.4/ftrace-fix-synchronization-location-disabling-and-freeing-ftrace_ops.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html