lkml.org 
[lkml]   [2021]   [Oct]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[for-next][PATCH 28/40] ftrace: Add multi direct modify interface
    From: Jiri Olsa <jolsa@redhat.com>

    Adding interface to modify registered direct function
    for ftrace_ops. Adding following function:

    modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)

    The function changes the currently registered direct
    function for all attached functions.

    Link: https://lkml.kernel.org/r/20211008091336.33616-8-jolsa@kernel.org

    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    ---
    include/linux/ftrace.h | 6 ++++
    kernel/trace/ftrace.c | 62 ++++++++++++++++++++++++++++++++++++++++++
    2 files changed, 68 insertions(+)

    diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
    index 0158261cac9f..9999e29187de 100644
    --- a/include/linux/ftrace.h
    +++ b/include/linux/ftrace.h
    @@ -326,6 +326,8 @@ int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
    unsigned long ftrace_find_rec_direct(unsigned long ip);
    int register_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
    int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
    +int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr);
    +
    #else
    struct ftrace_ops;
    # define ftrace_direct_func_count 0
    @@ -365,6 +367,10 @@ static inline int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigne
    {
    return -ENODEV;
    }
    +static inline int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
    +{
    + return -ENODEV;
    +}
    #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */

    #ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
    diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
    index a05b25fb77d8..30120342176e 100644
    --- a/kernel/trace/ftrace.c
    +++ b/kernel/trace/ftrace.c
    @@ -5543,6 +5543,68 @@ int unregister_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
    return err;
    }
    EXPORT_SYMBOL_GPL(unregister_ftrace_direct_multi);
    +
    +/**
    + * modify_ftrace_direct_multi - Modify an existing direct 'multi' call
    + * to call something else
    + * @ops: The address of the struct ftrace_ops object
    + * @addr: The address of the new trampoline to call at @ops functions
    + *
    + * This is used to unregister currently registered direct caller and
    + * register new one @addr on functions registered in @ops object.
    + *
    + * Note there's window between ftrace_shutdown and ftrace_startup calls
    + * where there will be no callbacks called.
    + *
    + * Returns: zero on success. Non zero on error, which includes:
    + * -EINVAL - The @ops object was not properly registered.
    + */
    +int modify_ftrace_direct_multi(struct ftrace_ops *ops, unsigned long addr)
    +{
    + struct ftrace_hash *hash = ops->func_hash->filter_hash;
    + struct ftrace_func_entry *entry, *iter;
    + int i, size;
    + int err;
    +
    + if (check_direct_multi(ops))
    + return -EINVAL;
    + if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
    + return -EINVAL;
    +
    + mutex_lock(&direct_mutex);
    + mutex_lock(&ftrace_lock);
    +
    + /*
    + * Shutdown the ops, change 'direct' pointer for each
    + * ops entry in direct_functions hash and startup the
    + * ops back again.
    + *
    + * Note there is no callback called for @ops object after
    + * this ftrace_shutdown call until ftrace_startup is called
    + * later on.
    + */
    + err = ftrace_shutdown(ops, 0);
    + if (err)
    + goto out_unlock;
    +
    + size = 1 << hash->size_bits;
    + for (i = 0; i < size; i++) {
    + hlist_for_each_entry(iter, &hash->buckets[i], hlist) {
    + entry = __ftrace_lookup_ip(direct_functions, iter->ip);
    + if (!entry)
    + continue;
    + entry->direct = addr;
    + }
    + }
    +
    + err = ftrace_startup(ops, 0);
    +
    + out_unlock:
    + mutex_unlock(&ftrace_lock);
    + mutex_unlock(&direct_mutex);
    + return err;
    +}
    +EXPORT_SYMBOL_GPL(modify_ftrace_direct_multi);
    #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */

    /**
    --
    2.33.0
    \
     
     \ /
      Last update: 2021-10-22 22:52    [W:5.175 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site