lkml.org 
[lkml]   [2018]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 6/6] kernel: tracepoints: add support for relative references
    Date
    To avoid the need for relocating absolute references to tracepoint
    structures at boot time when running relocatable kernels (which may
    take a disproportionate amount of space), add the option to emit
    these tables as relative references instead.

    Cc: Ingo Molnar <mingo@redhat.com>
    Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
    Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
    ---
    include/linux/tracepoint.h | 19 ++++++--
    kernel/tracepoint.c | 49 +++++++++++---------
    2 files changed, 41 insertions(+), 27 deletions(-)

    diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
    index c94f466d57ef..cdb0a9461d71 100644
    --- a/include/linux/tracepoint.h
    +++ b/include/linux/tracepoint.h
    @@ -225,6 +225,19 @@ extern void syscall_unregfunc(void);
    return static_key_false(&__tracepoint_##name.key); \
    }

    +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
    +#define __TRACEPOINT_ENTRY(name) \
    + asm(" .section \"__tracepoints_ptrs\", \"a\" \n" \
    + " .balign 4 \n" \
    + " .long " VMLINUX_SYMBOL_STR(__tracepoint_##name) " - .\n" \
    + " .previous \n")
    +#else
    +#define __TRACEPOINT_ENTRY(name) \
    + static struct tracepoint * const __tracepoint_ptr_##name __used \
    + __attribute__((section("__tracepoints_ptrs"))) = \
    + &__tracepoint_##name
    +#endif
    +
    /*
    * We have no guarantee that gcc and the linker won't up-align the tracepoint
    * structures, so we create an array of pointers that will be used for iteration
    @@ -234,11 +247,9 @@ extern void syscall_unregfunc(void);
    static const char __tpstrtab_##name[] \
    __attribute__((section("__tracepoints_strings"))) = #name; \
    struct tracepoint __tracepoint_##name \
    - __attribute__((section("__tracepoints"))) = \
    + __attribute__((section("__tracepoints"), used)) = \
    { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\
    - static struct tracepoint * const __tracepoint_ptr_##name __used \
    - __attribute__((section("__tracepoints_ptrs"))) = \
    - &__tracepoint_##name;
    + __TRACEPOINT_ENTRY(name);

    #define DEFINE_TRACE(name) \
    DEFINE_TRACE_FN(name, NULL, NULL);
    diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
    index 671b13457387..4ce8cc4bf2c3 100644
    --- a/kernel/tracepoint.c
    +++ b/kernel/tracepoint.c
    @@ -326,6 +326,27 @@ int tracepoint_probe_unregister(struct tracepoint *tp, void *probe, void *data)
    }
    EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);

    +static void for_each_tracepoint_range(struct tracepoint * const *begin,
    + struct tracepoint * const *end,
    + void (*fct)(struct tracepoint *tp, void *priv),
    + void *priv)
    +{
    + if (!begin)
    + return;
    +
    + if (IS_ENABLED(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)) {
    + const int *iter;
    +
    + for (iter = (const int *)begin; iter < (const int *)end; iter++)
    + fct(offset_to_ptr(iter), priv);
    + } else {
    + struct tracepoint * const *iter;
    +
    + for (iter = begin; iter < end; iter++)
    + fct(*iter, priv);
    + }
    +}
    +
    #ifdef CONFIG_MODULES
    bool trace_module_has_bad_taint(struct module *mod)
    {
    @@ -390,15 +411,9 @@ EXPORT_SYMBOL_GPL(unregister_tracepoint_module_notifier);
    * Ensure the tracer unregistered the module's probes before the module
    * teardown is performed. Prevents leaks of probe and data pointers.
    */
    -static void tp_module_going_check_quiescent(struct tracepoint * const *begin,
    - struct tracepoint * const *end)
    +static void tp_module_going_check_quiescent(struct tracepoint *tp, void *priv)
    {
    - struct tracepoint * const *iter;
    -
    - if (!begin)
    - return;
    - for (iter = begin; iter < end; iter++)
    - WARN_ON_ONCE((*iter)->funcs);
    + WARN_ON_ONCE(tp->funcs);
    }

    static int tracepoint_module_coming(struct module *mod)
    @@ -449,8 +464,9 @@ static void tracepoint_module_going(struct module *mod)
    * Called the going notifier before checking for
    * quiescence.
    */
    - tp_module_going_check_quiescent(mod->tracepoints_ptrs,
    - mod->tracepoints_ptrs + mod->num_tracepoints);
    + for_each_tracepoint_range(mod->tracepoints_ptrs,
    + mod->tracepoints_ptrs + mod->num_tracepoints,
    + tp_module_going_check_quiescent, NULL);
    break;
    }
    }
    @@ -502,19 +518,6 @@ static __init int init_tracepoints(void)
    __initcall(init_tracepoints);
    #endif /* CONFIG_MODULES */

    -static void for_each_tracepoint_range(struct tracepoint * const *begin,
    - struct tracepoint * const *end,
    - void (*fct)(struct tracepoint *tp, void *priv),
    - void *priv)
    -{
    - struct tracepoint * const *iter;
    -
    - if (!begin)
    - return;
    - for (iter = begin; iter < end; iter++)
    - fct(*iter, priv);
    -}
    -
    /**
    * for_each_kernel_tracepoint - iteration on all kernel tracepoints
    * @fct: callback
    --
    2.15.1
    \
     
     \ /
      Last update: 2018-03-11 13:40    [W:4.072 / U:0.516 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site