Message ID | 20171227085033.22389-6-ard.biesheuvel@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | add support for relative references in special sections | expand |
On Wed, 27 Dec 2017 08:50:30 +0000 Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > 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. > I gave this patch a quick skim over. It appears to not modify anything when CONFIG_HAVE_PREL32_RELOCATIONS is not defined. I haven't thoroughly reviewed it or tested it. But if it doesn't break anything, I'm fine giving you an ack. Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -- Steve
On 28 December 2017 at 15:42, Steven Rostedt <rostedt@goodmis.org> wrote: > On Wed, 27 Dec 2017 08:50:30 +0000 > Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote: > >> 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. >> > > I gave this patch a quick skim over. It appears to not modify anything > when CONFIG_HAVE_PREL32_RELOCATIONS is not defined. I haven't > thoroughly reviewed it or tested it. But if it doesn't break anything, > I'm fine giving you an ack. > > Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> > Thank you Steven. I should mention though (as you don't appear to recall) that an earlier version of this patch triggered an issue for you https://marc.info/?l=linux-arch&m=150584374820168&w=2 but I have never managed to reproduce it, neither at the time nor currently with this v6. ard@bezzzef:~/linux-2.6$ sudo tools/testing/selftests/ftrace/ftracetest === Ftrace unit tests === [1] Basic trace file check [PASS] [2] Basic test for tracers [PASS] [3] Basic trace clock test [PASS] [4] Basic event tracing check [PASS] [5] event tracing - enable/disable with event level files [PASS] [6] event tracing - restricts events based on pid [PASS] [7] event tracing - enable/disable with subsystem level files [PASS] [8] event tracing - enable/disable with top level files [PASS] [9] ftrace - function graph filters with stack tracer [PASS] [10] ftrace - function graph filters [PASS] [11] ftrace - test for function event triggers [PASS] [12] ftrace - function glob filters [PASS] [13] ftrace - function pid filters [PASS] [14] ftrace - function profiler with function tracing [PASS] [15] ftrace - test reading of set_ftrace_filter [PASS] [16] ftrace - test for function traceon/off triggers [PASS] [17] Test creation and deletion of trace instances while setting an event [PASS] [18] Test creation and deletion of trace instances [PASS] [19] Kprobe dynamic event - adding and removing [PASS] [20] Kprobe dynamic event - busy event check [PASS] [21] Kprobe dynamic event with arguments [PASS] [22] Kprobes event arguments with types [PASS] [23] Kprobe event auto/manual naming [PASS] [24] Kprobe dynamic event with function tracer [PASS] [25] Kprobe dynamic event - probing module [PASS] [26] Kretprobe dynamic event with arguments [PASS] [27] Kretprobe dynamic event with maxactive [PASS] [28] Register/unregister many kprobe events [PASS] [29] event trigger - test event enable/disable trigger [PASS] [30] event trigger - test trigger filter [PASS] [31] event trigger - test histogram modifiers [PASS] [32] event trigger - test histogram trigger [PASS] [33] event trigger - test multiple histogram triggers [PASS] [34] event trigger - test snapshot-trigger [PASS] [35] event trigger - test stacktrace-trigger [PASS] [36] event trigger - test traceon/off trigger [PASS] [37] (instance) Basic test for tracers [PASS] [38] (instance) Basic trace clock test [PASS] [39] (instance) event tracing - enable/disable with event level files [PASS] [40] (instance) event tracing - restricts events based on pid [PASS] [41] (instance) event tracing - enable/disable with subsystem level files [PASS] [42] (instance) ftrace - test for function event triggers [PASS] [43] (instance) ftrace - test for function traceon/off triggers [PASS] [44] (instance) event trigger - test event enable/disable trigger [PASS] [45] (instance) event trigger - test trigger filter [PASS] [46] (instance) event trigger - test histogram modifiers [PASS] [47] (instance) event trigger - test histogram trigger [PASS] [48] (instance) event trigger - test multiple histogram triggers [PASS] # of passed: 48 # of failed: 0 # of unresolved: 0 # of untested: 0 # of unsupported: 0 # of xfailed: 0 # of undefined(test bug): 0
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index a26ffbe09e71..d02bf1a695e8 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -228,6 +228,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 @@ -237,11 +250,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 685c50ae6300..05649fef106c 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -327,6 +327,28 @@ 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((struct tracepoint *)((unsigned long)iter + *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) { @@ -391,15 +413,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) @@ -450,8 +466,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; } } @@ -503,19 +520,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
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: Steven Rostedt <rostedt@goodmis.org> Cc: Ingo Molnar <mingo@redhat.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- include/linux/tracepoint.h | 19 ++++++-- kernel/tracepoint.c | 50 +++++++++++--------- 2 files changed, 42 insertions(+), 27 deletions(-) -- 2.11.0