• Steven Rostedt's avatar
    ftrace: Fix dynamic selftest failure on some archs · 6331c28c
    Steven Rostedt authored
    Archs that do not implement CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST, will
    fail the dynamic ftrace selftest.
    
    The function tracer has a quick 'off' variable that will prevent
    the call back functions from being called. This variable is called
    function_trace_stop. In x86, this is implemented directly in the mcount
    assembly, but for other archs, an intermediate function is used called
    ftrace_test_stop_func().
    
    In dynamic ftrace, the function pointer variable ftrace_trace_function is
    used to update the caller code in the mcount caller. But for archs that
    do not have CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST set, it only calls
    ftrace_test_stop_func() instead, which in turn calls __ftrace_trace_function.
    
    When more than one ftrace_ops is registered, the function it calls is
    ftrace_ops_list_func(), which will iterate over all registered ftrace_ops
    and call the callbacks that have their hash matching.
    
    The issue happens when two ftrace_ops are registered for different functions
    and one is then unregistered. The __ftrace_trace_function is then pointed
    to the remaining ftrace_ops callback function directly. This mean it will
    be called for all functions that were registered to trace by both ftrace_ops
    that were registered.
    
    This is not an issue for archs with CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST,
    because the update of ftrace_trace_function doesn't happen until after all
    functions have been updated, and then the mcount caller is updated. But
    for those archs that do use the ftrace_test_stop_func(), the update is
    immediate.
    
    The dynamic selftest fails because it hits this situation, and the
    ftrace_ops that it registers fails to only trace what it was suppose to
    and instead traces all other functions.
    
    The solution is to delay the setting of __ftrace_trace_function until
    after all the functions have been updated according to the registered
    ftrace_ops. Also, function_trace_stop is set during the update to prevent
    function tracing from calling code that is caused by the function tracer
    itself.
    Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    6331c28c
ftrace.c 89.3 KB