lkml.org 
[lkml]   [2011]   [Dec]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCHv2 10/10] ftrace, graph: Add global_ops filter callback for graph tracing
    Date
    The function graph tracer should depend on the global_ops filter,
    and process only functions that pass the global_ops filter.

    Currently the function graph tracer gets all the functions
    enabled for tracing no matter what ftrace_ops enabled them.

    Adding a hook for the graph entry callback, which ensures the
    function is compared against the global_ops filter and bail
    out of if it does not match.

    This hook is enabled only if there's at least one non global
    ftrace_ops registered.

    Signed-off-by: Jiri Olsa <jolsa@redhat.com>
    ---
    kernel/trace/ftrace.c | 41 +++++++++++++++++++++++++++++++++++++++++
    1 files changed, 41 insertions(+), 0 deletions(-)

    diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
    index 2dae0c7..dc49ba6 100644
    --- a/kernel/trace/ftrace.c
    +++ b/kernel/trace/ftrace.c
    @@ -95,10 +95,13 @@ ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
    ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
    static struct ftrace_ops global_ops;
    static struct ftrace_ops control_ops;
    +static int non_global_ops_registered;

    static void
    ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip);

    +static void ftrace_graph_update_filter(void);
    +
    /*
    * Traverse the ftrace_global_list, invoking all entries. The reason that we
    * can use rcu_dereference_raw() is that elements removed from this list
    @@ -330,6 +333,9 @@ static int __register_ftrace_function(struct ftrace_ops *ops)
    if (!core_kernel_data((unsigned long)ops))
    ops->flags |= FTRACE_OPS_FL_DYNAMIC;

    + if (!(ops->flags & FTRACE_OPS_FL_GLOBAL))
    + non_global_ops_registered++;
    +
    if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
    add_ftrace_ops(&ftrace_global_list, &global_ops, ops);
    ops->flags |= FTRACE_OPS_FL_ENABLED;
    @@ -359,6 +365,9 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
    if (FTRACE_WARN_ON(ops == &global_ops))
    return -EINVAL;

    + if (!(ops->flags & FTRACE_OPS_FL_GLOBAL))
    + non_global_ops_registered--;
    +
    if (ops->flags & FTRACE_OPS_FL_GLOBAL) {
    ret = remove_ftrace_ops(&ftrace_global_list, &global_ops, ops);
    if (!ret)
    @@ -1695,6 +1704,8 @@ static int __ftrace_modify_code(void *data)
    if (*command & FTRACE_UPDATE_TRACE_FUNC)
    ftrace_update_ftrace_func(ftrace_trace_function);

    + ftrace_graph_update_filter();
    +
    if (*command & FTRACE_START_FUNC_RET)
    ftrace_enable_ftrace_graph_caller();
    else if (*command & FTRACE_STOP_FUNC_RET)
    @@ -4339,4 +4350,34 @@ void ftrace_graph_stop(void)
    {
    ftrace_stop();
    }
    +
    +static trace_func_graph_ent_t ftrace_graph_entry_saved;
    +
    +int ftrace_graph_entry_filter(struct ftrace_graph_ent *ent)
    +{
    + if (ftrace_ops_test(&global_ops, ent->func))
    + return ftrace_graph_entry_saved(ent);
    +
    + return 0;
    +}
    +
    +static void ftrace_graph_update_filter(void)
    +{
    + bool installed = (ftrace_graph_entry == ftrace_graph_entry_filter);
    +
    + if (!ftrace_graph_active)
    + return;
    +
    + if (!installed && non_global_ops_registered) {
    + ftrace_graph_entry_saved = ftrace_graph_entry;
    + ftrace_graph_entry = ftrace_graph_entry_filter;
    + return;
    + }
    +
    + if (installed && !non_global_ops_registered)
    + ftrace_graph_entry = ftrace_graph_entry_saved;
    +}
    +
    +#else
    +static void ftrace_graph_update_filter(void) { }
    #endif
    --
    1.7.1


    \
     
     \ /
      Last update: 2011-12-05 18:27    [W:0.025 / U:0.848 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site