• F
    tracing/urgent: fix unbalanced ftrace_start_up · c85a17e2
    Frederic Weisbecker 提交于
    Perfcounter reports the following stats for a wide system
    profiling:
    
     #
     # (2364 samples)
     #
     # Overhead  Symbol
     # ........  ......
     #
        15.40%  [k] mwait_idle_with_hints
         8.29%  [k] read_hpet
         5.75%  [k] ftrace_caller
         3.60%  [k] ftrace_call
         [...]
    
    This snapshot has been taken while neither the function tracer nor
    the function graph tracer was running.
    With dynamic ftrace, such results show a wrong ftrace behaviour
    because all calls to ftrace_caller or ftrace_graph_caller (the patched
    calls to mcount) are supposed to be patched into nop if none of those
    tracers are running.
    
    The problem occurs after the first run of the function tracer. Once we
    launch it a second time, the callsites will never be nopped back,
    unless you set custom filters.
    For example it happens during the self tests at boot time.
    The function tracer selftest runs, and then the dynamic tracing is
    tested too. After that, the callsites are left un-nopped.
    
    This is because the reset callback of the function tracer tries to
    unregister two ftrace callbacks in once: the common function tracer
    and the function tracer with stack backtrace, regardless of which
    one is currently in use.
    It then creates an unbalance on ftrace_start_up value which is expected
    to be zero when the last ftrace callback is unregistered. When it
    reaches zero, the FTRACE_DISABLE_CALLS is set on the next ftrace
    command, triggering the patching into nop. But since it becomes
    unbalanced, ie becomes lower than zero, if the kernel functions
    are patched again (as in every further function tracer runs), they
    won't ever be nopped back.
    
    Note that ftrace_call and ftrace_graph_call are still patched back
    to ftrace_stub in the off case, but not the callers of ftrace_call
    and ftrace_graph_caller. It means that the tracing is well deactivated
    but we waste a useless call into every kernel function.
    
    This patch just unregisters the right ftrace_ops for the function
    tracer on its reset callback and ignores the other one which is
    not registered, fixing the unbalance. The problem also happens
    is .30
    Signed-off-by: NFrederic Weisbecker <fweisbec@gmail.com>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: stable@kernel.org
    c85a17e2
trace_functions.c 8.2 KB