diff options
| -rw-r--r-- | include/asm-generic/vmlinux.lds.h | 24 | ||||
| -rw-r--r-- | include/linux/module.h | 4 | ||||
| -rw-r--r-- | include/linux/syscalls.h | 28 | ||||
| -rw-r--r-- | include/linux/tracepoint.h | 35 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 24 | ||||
| -rw-r--r-- | kernel/module.c | 16 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 12 | ||||
| -rw-r--r-- | kernel/trace/trace_export.c | 6 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 19 | ||||
| -rw-r--r-- | kernel/tracepoint.c | 31 |
10 files changed, 105 insertions, 94 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 6ebb81030d2d..fe77e3395b40 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
| @@ -124,7 +124,8 @@ | |||
| 124 | #endif | 124 | #endif |
| 125 | 125 | ||
| 126 | #ifdef CONFIG_EVENT_TRACING | 126 | #ifdef CONFIG_EVENT_TRACING |
| 127 | #define FTRACE_EVENTS() VMLINUX_SYMBOL(__start_ftrace_events) = .; \ | 127 | #define FTRACE_EVENTS() . = ALIGN(8); \ |
| 128 | VMLINUX_SYMBOL(__start_ftrace_events) = .; \ | ||
| 128 | *(_ftrace_events) \ | 129 | *(_ftrace_events) \ |
| 129 | VMLINUX_SYMBOL(__stop_ftrace_events) = .; | 130 | VMLINUX_SYMBOL(__stop_ftrace_events) = .; |
| 130 | #else | 131 | #else |
| @@ -140,7 +141,8 @@ | |||
| 140 | #endif | 141 | #endif |
| 141 | 142 | ||
| 142 | #ifdef CONFIG_FTRACE_SYSCALLS | 143 | #ifdef CONFIG_FTRACE_SYSCALLS |
| 143 | #define TRACE_SYSCALLS() VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ | 144 | #define TRACE_SYSCALLS() . = ALIGN(8); \ |
| 145 | VMLINUX_SYMBOL(__start_syscalls_metadata) = .; \ | ||
| 144 | *(__syscalls_metadata) \ | 146 | *(__syscalls_metadata) \ |
| 145 | VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; | 147 | VMLINUX_SYMBOL(__stop_syscalls_metadata) = .; |
| 146 | #else | 148 | #else |
| @@ -165,10 +167,8 @@ | |||
| 165 | CPU_KEEP(exit.data) \ | 167 | CPU_KEEP(exit.data) \ |
| 166 | MEM_KEEP(init.data) \ | 168 | MEM_KEEP(init.data) \ |
| 167 | MEM_KEEP(exit.data) \ | 169 | MEM_KEEP(exit.data) \ |
| 168 | . = ALIGN(32); \ | 170 | STRUCT_ALIGN(); \ |
| 169 | VMLINUX_SYMBOL(__start___tracepoints) = .; \ | ||
| 170 | *(__tracepoints) \ | 171 | *(__tracepoints) \ |
| 171 | VMLINUX_SYMBOL(__stop___tracepoints) = .; \ | ||
| 172 | /* implement dynamic printk debug */ \ | 172 | /* implement dynamic printk debug */ \ |
| 173 | . = ALIGN(8); \ | 173 | . = ALIGN(8); \ |
| 174 | VMLINUX_SYMBOL(__start___verbose) = .; \ | 174 | VMLINUX_SYMBOL(__start___verbose) = .; \ |
| @@ -176,13 +176,7 @@ | |||
| 176 | VMLINUX_SYMBOL(__stop___verbose) = .; \ | 176 | VMLINUX_SYMBOL(__stop___verbose) = .; \ |
| 177 | LIKELY_PROFILE() \ | 177 | LIKELY_PROFILE() \ |
| 178 | BRANCH_PROFILE() \ | 178 | BRANCH_PROFILE() \ |
| 179 | TRACE_PRINTKS() \ | 179 | TRACE_PRINTKS() |
| 180 | \ | ||
| 181 | STRUCT_ALIGN(); \ | ||
| 182 | FTRACE_EVENTS() \ | ||
| 183 | \ | ||
| 184 | STRUCT_ALIGN(); \ | ||
| 185 | TRACE_SYSCALLS() | ||
| 186 | 180 | ||
| 187 | /* | 181 | /* |
| 188 | * Data section helpers | 182 | * Data section helpers |
| @@ -220,6 +214,10 @@ | |||
| 220 | VMLINUX_SYMBOL(__start_rodata) = .; \ | 214 | VMLINUX_SYMBOL(__start_rodata) = .; \ |
| 221 | *(.rodata) *(.rodata.*) \ | 215 | *(.rodata) *(.rodata.*) \ |
| 222 | *(__vermagic) /* Kernel version magic */ \ | 216 | *(__vermagic) /* Kernel version magic */ \ |
| 217 | . = ALIGN(8); \ | ||
| 218 | VMLINUX_SYMBOL(__start___tracepoints_ptrs) = .; \ | ||
| 219 | *(__tracepoints_ptrs) /* Tracepoints: pointer array */\ | ||
| 220 | VMLINUX_SYMBOL(__stop___tracepoints_ptrs) = .; \ | ||
| 223 | *(__markers_strings) /* Markers: strings */ \ | 221 | *(__markers_strings) /* Markers: strings */ \ |
| 224 | *(__tracepoints_strings)/* Tracepoints: strings */ \ | 222 | *(__tracepoints_strings)/* Tracepoints: strings */ \ |
| 225 | } \ | 223 | } \ |
| @@ -482,6 +480,8 @@ | |||
| 482 | KERNEL_CTORS() \ | 480 | KERNEL_CTORS() \ |
| 483 | *(.init.rodata) \ | 481 | *(.init.rodata) \ |
| 484 | MCOUNT_REC() \ | 482 | MCOUNT_REC() \ |
| 483 | FTRACE_EVENTS() \ | ||
| 484 | TRACE_SYSCALLS() \ | ||
| 485 | DEV_DISCARD(init.rodata) \ | 485 | DEV_DISCARD(init.rodata) \ |
| 486 | CPU_DISCARD(init.rodata) \ | 486 | CPU_DISCARD(init.rodata) \ |
| 487 | MEM_DISCARD(init.rodata) \ | 487 | MEM_DISCARD(init.rodata) \ |
diff --git a/include/linux/module.h b/include/linux/module.h index e7c6385c6683..9bdf27c7615b 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
| @@ -377,7 +377,7 @@ struct module | |||
| 377 | keeping pointers to this stuff */ | 377 | keeping pointers to this stuff */ |
| 378 | char *args; | 378 | char *args; |
| 379 | #ifdef CONFIG_TRACEPOINTS | 379 | #ifdef CONFIG_TRACEPOINTS |
| 380 | struct tracepoint *tracepoints; | 380 | struct tracepoint * const *tracepoints_ptrs; |
| 381 | unsigned int num_tracepoints; | 381 | unsigned int num_tracepoints; |
| 382 | #endif | 382 | #endif |
| 383 | #ifdef HAVE_JUMP_LABEL | 383 | #ifdef HAVE_JUMP_LABEL |
| @@ -389,7 +389,7 @@ struct module | |||
| 389 | unsigned int num_trace_bprintk_fmt; | 389 | unsigned int num_trace_bprintk_fmt; |
| 390 | #endif | 390 | #endif |
| 391 | #ifdef CONFIG_EVENT_TRACING | 391 | #ifdef CONFIG_EVENT_TRACING |
| 392 | struct ftrace_event_call *trace_events; | 392 | struct ftrace_event_call **trace_events; |
| 393 | unsigned int num_trace_events; | 393 | unsigned int num_trace_events; |
| 394 | #endif | 394 | #endif |
| 395 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 395 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 18cd0684fc4e..98664db1be47 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -125,39 +125,37 @@ extern struct trace_event_functions enter_syscall_print_funcs; | |||
| 125 | extern struct trace_event_functions exit_syscall_print_funcs; | 125 | extern struct trace_event_functions exit_syscall_print_funcs; |
| 126 | 126 | ||
| 127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 127 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
| 128 | static struct syscall_metadata \ | 128 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 129 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
| 130 | static struct ftrace_event_call __used \ | 129 | static struct ftrace_event_call __used \ |
| 131 | __attribute__((__aligned__(4))) \ | ||
| 132 | __attribute__((section("_ftrace_events"))) \ | ||
| 133 | event_enter_##sname = { \ | 130 | event_enter_##sname = { \ |
| 134 | .name = "sys_enter"#sname, \ | 131 | .name = "sys_enter"#sname, \ |
| 135 | .class = &event_class_syscall_enter, \ | 132 | .class = &event_class_syscall_enter, \ |
| 136 | .event.funcs = &enter_syscall_print_funcs, \ | 133 | .event.funcs = &enter_syscall_print_funcs, \ |
| 137 | .data = (void *)&__syscall_meta_##sname,\ | 134 | .data = (void *)&__syscall_meta_##sname,\ |
| 138 | }; \ | 135 | }; \ |
| 136 | static struct ftrace_event_call __used \ | ||
| 137 | __attribute__((section("_ftrace_events"))) \ | ||
| 138 | *__event_enter_##sname = &event_enter_##sname; \ | ||
| 139 | __TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY) | 139 | __TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY) |
| 140 | 140 | ||
| 141 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 141 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
| 142 | static struct syscall_metadata \ | 142 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 143 | __attribute__((__aligned__(4))) __syscall_meta_##sname; \ | ||
| 144 | static struct ftrace_event_call __used \ | 143 | static struct ftrace_event_call __used \ |
| 145 | __attribute__((__aligned__(4))) \ | ||
| 146 | __attribute__((section("_ftrace_events"))) \ | ||
| 147 | event_exit_##sname = { \ | 144 | event_exit_##sname = { \ |
| 148 | .name = "sys_exit"#sname, \ | 145 | .name = "sys_exit"#sname, \ |
| 149 | .class = &event_class_syscall_exit, \ | 146 | .class = &event_class_syscall_exit, \ |
| 150 | .event.funcs = &exit_syscall_print_funcs, \ | 147 | .event.funcs = &exit_syscall_print_funcs, \ |
| 151 | .data = (void *)&__syscall_meta_##sname,\ | 148 | .data = (void *)&__syscall_meta_##sname,\ |
| 152 | }; \ | 149 | }; \ |
| 150 | static struct ftrace_event_call __used \ | ||
| 151 | __attribute__((section("_ftrace_events"))) \ | ||
| 152 | *__event_exit_##sname = &event_exit_##sname; \ | ||
| 153 | __TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY) | 153 | __TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY) |
| 154 | 154 | ||
| 155 | #define SYSCALL_METADATA(sname, nb) \ | 155 | #define SYSCALL_METADATA(sname, nb) \ |
| 156 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | 156 | SYSCALL_TRACE_ENTER_EVENT(sname); \ |
| 157 | SYSCALL_TRACE_EXIT_EVENT(sname); \ | 157 | SYSCALL_TRACE_EXIT_EVENT(sname); \ |
| 158 | static struct syscall_metadata __used \ | 158 | static struct syscall_metadata __used \ |
| 159 | __attribute__((__aligned__(4))) \ | ||
| 160 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 161 | __syscall_meta_##sname = { \ | 159 | __syscall_meta_##sname = { \ |
| 162 | .name = "sys"#sname, \ | 160 | .name = "sys"#sname, \ |
| 163 | .nb_args = nb, \ | 161 | .nb_args = nb, \ |
| @@ -166,14 +164,15 @@ extern struct trace_event_functions exit_syscall_print_funcs; | |||
| 166 | .enter_event = &event_enter_##sname, \ | 164 | .enter_event = &event_enter_##sname, \ |
| 167 | .exit_event = &event_exit_##sname, \ | 165 | .exit_event = &event_exit_##sname, \ |
| 168 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ | 166 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ |
| 169 | }; | 167 | }; \ |
| 168 | static struct syscall_metadata __used \ | ||
| 169 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 170 | *__p_syscall_meta_##sname = &__syscall_meta_##sname; | ||
| 170 | 171 | ||
| 171 | #define SYSCALL_DEFINE0(sname) \ | 172 | #define SYSCALL_DEFINE0(sname) \ |
| 172 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | 173 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ |
| 173 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | 174 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ |
| 174 | static struct syscall_metadata __used \ | 175 | static struct syscall_metadata __used \ |
| 175 | __attribute__((__aligned__(4))) \ | ||
| 176 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 177 | __syscall_meta__##sname = { \ | 176 | __syscall_meta__##sname = { \ |
| 178 | .name = "sys_"#sname, \ | 177 | .name = "sys_"#sname, \ |
| 179 | .nb_args = 0, \ | 178 | .nb_args = 0, \ |
| @@ -181,6 +180,9 @@ extern struct trace_event_functions exit_syscall_print_funcs; | |||
| 181 | .exit_event = &event_exit__##sname, \ | 180 | .exit_event = &event_exit__##sname, \ |
| 182 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ | 181 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ |
| 183 | }; \ | 182 | }; \ |
| 183 | static struct syscall_metadata __used \ | ||
| 184 | __attribute__((section("__syscalls_metadata"))) \ | ||
| 185 | *__p_syscall_meta_##sname = &__syscall_meta__##sname; \ | ||
| 184 | asmlinkage long sys_##sname(void) | 186 | asmlinkage long sys_##sname(void) |
| 185 | #else | 187 | #else |
| 186 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) | 188 | #define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void) |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index c6814616653b..97c84a58efb8 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -33,12 +33,7 @@ struct tracepoint { | |||
| 33 | void (*regfunc)(void); | 33 | void (*regfunc)(void); |
| 34 | void (*unregfunc)(void); | 34 | void (*unregfunc)(void); |
| 35 | struct tracepoint_func __rcu *funcs; | 35 | struct tracepoint_func __rcu *funcs; |
| 36 | } __attribute__((aligned(32))); /* | 36 | }; |
| 37 | * Aligned on 32 bytes because it is | ||
| 38 | * globally visible and gcc happily | ||
| 39 | * align these on the structure size. | ||
| 40 | * Keep in sync with vmlinux.lds.h. | ||
| 41 | */ | ||
| 42 | 37 | ||
| 43 | /* | 38 | /* |
| 44 | * Connect a probe to a tracepoint. | 39 | * Connect a probe to a tracepoint. |
| @@ -61,15 +56,15 @@ extern void tracepoint_probe_update_all(void); | |||
| 61 | 56 | ||
| 62 | struct tracepoint_iter { | 57 | struct tracepoint_iter { |
| 63 | struct module *module; | 58 | struct module *module; |
| 64 | struct tracepoint *tracepoint; | 59 | struct tracepoint * const *tracepoint; |
| 65 | }; | 60 | }; |
| 66 | 61 | ||
| 67 | extern void tracepoint_iter_start(struct tracepoint_iter *iter); | 62 | extern void tracepoint_iter_start(struct tracepoint_iter *iter); |
| 68 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); | 63 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); |
| 69 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); | 64 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); |
| 70 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); | 65 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); |
| 71 | extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, | 66 | extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, |
| 72 | struct tracepoint *begin, struct tracepoint *end); | 67 | struct tracepoint * const *begin, struct tracepoint * const *end); |
| 73 | 68 | ||
| 74 | /* | 69 | /* |
| 75 | * tracepoint_synchronize_unregister must be called between the last tracepoint | 70 | * tracepoint_synchronize_unregister must be called between the last tracepoint |
| @@ -84,11 +79,13 @@ static inline void tracepoint_synchronize_unregister(void) | |||
| 84 | #define PARAMS(args...) args | 79 | #define PARAMS(args...) args |
| 85 | 80 | ||
| 86 | #ifdef CONFIG_TRACEPOINTS | 81 | #ifdef CONFIG_TRACEPOINTS |
| 87 | extern void tracepoint_update_probe_range(struct tracepoint *begin, | 82 | extern |
| 88 | struct tracepoint *end); | 83 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 84 | struct tracepoint * const *end); | ||
| 89 | #else | 85 | #else |
| 90 | static inline void tracepoint_update_probe_range(struct tracepoint *begin, | 86 | static inline |
| 91 | struct tracepoint *end) | 87 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 88 | struct tracepoint * const *end) | ||
| 92 | { } | 89 | { } |
| 93 | #endif /* CONFIG_TRACEPOINTS */ | 90 | #endif /* CONFIG_TRACEPOINTS */ |
| 94 | 91 | ||
| @@ -174,12 +171,20 @@ do_trace: \ | |||
| 174 | { \ | 171 | { \ |
| 175 | } | 172 | } |
| 176 | 173 | ||
| 174 | /* | ||
| 175 | * We have no guarantee that gcc and the linker won't up-align the tracepoint | ||
| 176 | * structures, so we create an array of pointers that will be used for iteration | ||
| 177 | * on the tracepoints. | ||
| 178 | */ | ||
| 177 | #define DEFINE_TRACE_FN(name, reg, unreg) \ | 179 | #define DEFINE_TRACE_FN(name, reg, unreg) \ |
| 178 | static const char __tpstrtab_##name[] \ | 180 | static const char __tpstrtab_##name[] \ |
| 179 | __attribute__((section("__tracepoints_strings"))) = #name; \ | 181 | __attribute__((section("__tracepoints_strings"))) = #name; \ |
| 180 | struct tracepoint __tracepoint_##name \ | 182 | struct tracepoint __tracepoint_##name \ |
| 181 | __attribute__((section("__tracepoints"), aligned(32))) = \ | 183 | __attribute__((section("__tracepoints"))) = \ |
| 182 | { __tpstrtab_##name, 0, reg, unreg, NULL } | 184 | { __tpstrtab_##name, 0, reg, unreg, NULL }; \ |
| 185 | static struct tracepoint * const __tracepoint_ptr_##name __used \ | ||
| 186 | __attribute__((section("__tracepoints_ptrs"))) = \ | ||
| 187 | &__tracepoint_##name; | ||
| 183 | 188 | ||
| 184 | #define DEFINE_TRACE(name) \ | 189 | #define DEFINE_TRACE(name) \ |
| 185 | DEFINE_TRACE_FN(name, NULL, NULL); | 190 | DEFINE_TRACE_FN(name, NULL, NULL); |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index e16610c208c9..3e68366d485a 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -446,14 +446,16 @@ static inline notrace int ftrace_get_offsets_##call( \ | |||
| 446 | * .reg = ftrace_event_reg, | 446 | * .reg = ftrace_event_reg, |
| 447 | * }; | 447 | * }; |
| 448 | * | 448 | * |
| 449 | * static struct ftrace_event_call __used | 449 | * static struct ftrace_event_call event_<call> = { |
| 450 | * __attribute__((__aligned__(4))) | ||
| 451 | * __attribute__((section("_ftrace_events"))) event_<call> = { | ||
| 452 | * .name = "<call>", | 450 | * .name = "<call>", |
| 453 | * .class = event_class_<template>, | 451 | * .class = event_class_<template>, |
| 454 | * .event = &ftrace_event_type_<call>, | 452 | * .event = &ftrace_event_type_<call>, |
| 455 | * .print_fmt = print_fmt_<call>, | 453 | * .print_fmt = print_fmt_<call>, |
| 456 | * }; | 454 | * }; |
| 455 | * // its only safe to use pointers when doing linker tricks to | ||
| 456 | * // create an array. | ||
| 457 | * static struct ftrace_event_call __used | ||
| 458 | * __attribute__((section("_ftrace_events"))) *__event_<call> = &event_<call>; | ||
| 457 | * | 459 | * |
| 458 | */ | 460 | */ |
| 459 | 461 | ||
| @@ -579,28 +581,28 @@ static struct ftrace_event_class __used event_class_##call = { \ | |||
| 579 | #undef DEFINE_EVENT | 581 | #undef DEFINE_EVENT |
| 580 | #define DEFINE_EVENT(template, call, proto, args) \ | 582 | #define DEFINE_EVENT(template, call, proto, args) \ |
| 581 | \ | 583 | \ |
| 582 | static struct ftrace_event_call __used \ | 584 | static struct ftrace_event_call __used event_##call = { \ |
| 583 | __attribute__((__aligned__(4))) \ | ||
| 584 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 585 | .name = #call, \ | 585 | .name = #call, \ |
| 586 | .class = &event_class_##template, \ | 586 | .class = &event_class_##template, \ |
| 587 | .event.funcs = &ftrace_event_type_funcs_##template, \ | 587 | .event.funcs = &ftrace_event_type_funcs_##template, \ |
| 588 | .print_fmt = print_fmt_##template, \ | 588 | .print_fmt = print_fmt_##template, \ |
| 589 | }; | 589 | }; \ |
| 590 | static struct ftrace_event_call __used \ | ||
| 591 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | ||
| 590 | 592 | ||
| 591 | #undef DEFINE_EVENT_PRINT | 593 | #undef DEFINE_EVENT_PRINT |
| 592 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 594 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
| 593 | \ | 595 | \ |
| 594 | static const char print_fmt_##call[] = print; \ | 596 | static const char print_fmt_##call[] = print; \ |
| 595 | \ | 597 | \ |
| 596 | static struct ftrace_event_call __used \ | 598 | static struct ftrace_event_call __used event_##call = { \ |
| 597 | __attribute__((__aligned__(4))) \ | ||
| 598 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 599 | .name = #call, \ | 599 | .name = #call, \ |
| 600 | .class = &event_class_##template, \ | 600 | .class = &event_class_##template, \ |
| 601 | .event.funcs = &ftrace_event_type_funcs_##call, \ | 601 | .event.funcs = &ftrace_event_type_funcs_##call, \ |
| 602 | .print_fmt = print_fmt_##call, \ | 602 | .print_fmt = print_fmt_##call, \ |
| 603 | } | 603 | }; \ |
| 604 | static struct ftrace_event_call __used \ | ||
| 605 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | ||
| 604 | 606 | ||
| 605 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 607 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 606 | 608 | ||
diff --git a/kernel/module.c b/kernel/module.c index 34e00b708fad..efa290ea94bf 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -2460,9 +2460,9 @@ static void find_module_sections(struct module *mod, struct load_info *info) | |||
| 2460 | #endif | 2460 | #endif |
| 2461 | 2461 | ||
| 2462 | #ifdef CONFIG_TRACEPOINTS | 2462 | #ifdef CONFIG_TRACEPOINTS |
| 2463 | mod->tracepoints = section_objs(info, "__tracepoints", | 2463 | mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs", |
| 2464 | sizeof(*mod->tracepoints), | 2464 | sizeof(*mod->tracepoints_ptrs), |
| 2465 | &mod->num_tracepoints); | 2465 | &mod->num_tracepoints); |
| 2466 | #endif | 2466 | #endif |
| 2467 | #ifdef HAVE_JUMP_LABEL | 2467 | #ifdef HAVE_JUMP_LABEL |
| 2468 | mod->jump_entries = section_objs(info, "__jump_table", | 2468 | mod->jump_entries = section_objs(info, "__jump_table", |
| @@ -3393,7 +3393,7 @@ void module_layout(struct module *mod, | |||
| 3393 | struct modversion_info *ver, | 3393 | struct modversion_info *ver, |
| 3394 | struct kernel_param *kp, | 3394 | struct kernel_param *kp, |
| 3395 | struct kernel_symbol *ks, | 3395 | struct kernel_symbol *ks, |
| 3396 | struct tracepoint *tp) | 3396 | struct tracepoint * const *tp) |
| 3397 | { | 3397 | { |
| 3398 | } | 3398 | } |
| 3399 | EXPORT_SYMBOL(module_layout); | 3399 | EXPORT_SYMBOL(module_layout); |
| @@ -3407,8 +3407,8 @@ void module_update_tracepoints(void) | |||
| 3407 | mutex_lock(&module_mutex); | 3407 | mutex_lock(&module_mutex); |
| 3408 | list_for_each_entry(mod, &modules, list) | 3408 | list_for_each_entry(mod, &modules, list) |
| 3409 | if (!mod->taints) | 3409 | if (!mod->taints) |
| 3410 | tracepoint_update_probe_range(mod->tracepoints, | 3410 | tracepoint_update_probe_range(mod->tracepoints_ptrs, |
| 3411 | mod->tracepoints + mod->num_tracepoints); | 3411 | mod->tracepoints_ptrs + mod->num_tracepoints); |
| 3412 | mutex_unlock(&module_mutex); | 3412 | mutex_unlock(&module_mutex); |
| 3413 | } | 3413 | } |
| 3414 | 3414 | ||
| @@ -3432,8 +3432,8 @@ int module_get_iter_tracepoints(struct tracepoint_iter *iter) | |||
| 3432 | else if (iter_mod > iter->module) | 3432 | else if (iter_mod > iter->module) |
| 3433 | iter->tracepoint = NULL; | 3433 | iter->tracepoint = NULL; |
| 3434 | found = tracepoint_get_iter_range(&iter->tracepoint, | 3434 | found = tracepoint_get_iter_range(&iter->tracepoint, |
| 3435 | iter_mod->tracepoints, | 3435 | iter_mod->tracepoints_ptrs, |
| 3436 | iter_mod->tracepoints | 3436 | iter_mod->tracepoints_ptrs |
| 3437 | + iter_mod->num_tracepoints); | 3437 | + iter_mod->num_tracepoints); |
| 3438 | if (found) { | 3438 | if (found) { |
| 3439 | iter->module = iter_mod; | 3439 | iter->module = iter_mod; |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 35fde09b81de..5f499e0438a4 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -1284,7 +1284,7 @@ trace_create_file_ops(struct module *mod) | |||
| 1284 | static void trace_module_add_events(struct module *mod) | 1284 | static void trace_module_add_events(struct module *mod) |
| 1285 | { | 1285 | { |
| 1286 | struct ftrace_module_file_ops *file_ops = NULL; | 1286 | struct ftrace_module_file_ops *file_ops = NULL; |
| 1287 | struct ftrace_event_call *call, *start, *end; | 1287 | struct ftrace_event_call **call, **start, **end; |
| 1288 | 1288 | ||
| 1289 | start = mod->trace_events; | 1289 | start = mod->trace_events; |
| 1290 | end = mod->trace_events + mod->num_trace_events; | 1290 | end = mod->trace_events + mod->num_trace_events; |
| @@ -1297,7 +1297,7 @@ static void trace_module_add_events(struct module *mod) | |||
| 1297 | return; | 1297 | return; |
| 1298 | 1298 | ||
| 1299 | for_each_event(call, start, end) { | 1299 | for_each_event(call, start, end) { |
| 1300 | __trace_add_event_call(call, mod, | 1300 | __trace_add_event_call(*call, mod, |
| 1301 | &file_ops->id, &file_ops->enable, | 1301 | &file_ops->id, &file_ops->enable, |
| 1302 | &file_ops->filter, &file_ops->format); | 1302 | &file_ops->filter, &file_ops->format); |
| 1303 | } | 1303 | } |
| @@ -1367,8 +1367,8 @@ static struct notifier_block trace_module_nb = { | |||
| 1367 | .priority = 0, | 1367 | .priority = 0, |
| 1368 | }; | 1368 | }; |
| 1369 | 1369 | ||
| 1370 | extern struct ftrace_event_call __start_ftrace_events[]; | 1370 | extern struct ftrace_event_call *__start_ftrace_events[]; |
| 1371 | extern struct ftrace_event_call __stop_ftrace_events[]; | 1371 | extern struct ftrace_event_call *__stop_ftrace_events[]; |
| 1372 | 1372 | ||
| 1373 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; | 1373 | static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; |
| 1374 | 1374 | ||
| @@ -1384,7 +1384,7 @@ __setup("trace_event=", setup_trace_event); | |||
| 1384 | 1384 | ||
| 1385 | static __init int event_trace_init(void) | 1385 | static __init int event_trace_init(void) |
| 1386 | { | 1386 | { |
| 1387 | struct ftrace_event_call *call; | 1387 | struct ftrace_event_call **call; |
| 1388 | struct dentry *d_tracer; | 1388 | struct dentry *d_tracer; |
| 1389 | struct dentry *entry; | 1389 | struct dentry *entry; |
| 1390 | struct dentry *d_events; | 1390 | struct dentry *d_events; |
| @@ -1430,7 +1430,7 @@ static __init int event_trace_init(void) | |||
| 1430 | pr_warning("tracing: Failed to allocate common fields"); | 1430 | pr_warning("tracing: Failed to allocate common fields"); |
| 1431 | 1431 | ||
| 1432 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { | 1432 | for_each_event(call, __start_ftrace_events, __stop_ftrace_events) { |
| 1433 | __trace_add_event_call(call, NULL, &ftrace_event_id_fops, | 1433 | __trace_add_event_call(*call, NULL, &ftrace_event_id_fops, |
| 1434 | &ftrace_enable_fops, | 1434 | &ftrace_enable_fops, |
| 1435 | &ftrace_event_filter_fops, | 1435 | &ftrace_event_filter_fops, |
| 1436 | &ftrace_event_format_fops); | 1436 | &ftrace_event_format_fops); |
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index 4b74d71705c0..bbeec31e0ae3 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
| @@ -161,13 +161,13 @@ struct ftrace_event_class event_class_ftrace_##call = { \ | |||
| 161 | .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ | 161 | .fields = LIST_HEAD_INIT(event_class_ftrace_##call.fields),\ |
| 162 | }; \ | 162 | }; \ |
| 163 | \ | 163 | \ |
| 164 | struct ftrace_event_call __used \ | 164 | struct ftrace_event_call __used event_##call = { \ |
| 165 | __attribute__((__aligned__(4))) \ | ||
| 166 | __attribute__((section("_ftrace_events"))) event_##call = { \ | ||
| 167 | .name = #call, \ | 165 | .name = #call, \ |
| 168 | .event.type = etype, \ | 166 | .event.type = etype, \ |
| 169 | .class = &event_class_ftrace_##call, \ | 167 | .class = &event_class_ftrace_##call, \ |
| 170 | .print_fmt = print, \ | 168 | .print_fmt = print, \ |
| 171 | }; \ | 169 | }; \ |
| 170 | struct ftrace_event_call __used \ | ||
| 171 | __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call; | ||
| 172 | 172 | ||
| 173 | #include "trace_entries.h" | 173 | #include "trace_entries.h" |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index b706529b4fc7..5c9fe08d2093 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -55,20 +55,21 @@ struct ftrace_event_class event_class_syscall_exit = { | |||
| 55 | .raw_init = init_syscall_trace, | 55 | .raw_init = init_syscall_trace, |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | extern unsigned long __start_syscalls_metadata[]; | 58 | extern struct syscall_metadata *__start_syscalls_metadata[]; |
| 59 | extern unsigned long __stop_syscalls_metadata[]; | 59 | extern struct syscall_metadata *__stop_syscalls_metadata[]; |
| 60 | 60 | ||
| 61 | static struct syscall_metadata **syscalls_metadata; | 61 | static struct syscall_metadata **syscalls_metadata; |
| 62 | 62 | ||
| 63 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | 63 | static __init struct syscall_metadata * |
| 64 | find_syscall_meta(unsigned long syscall) | ||
| 64 | { | 65 | { |
| 65 | struct syscall_metadata *start; | 66 | struct syscall_metadata **start; |
| 66 | struct syscall_metadata *stop; | 67 | struct syscall_metadata **stop; |
| 67 | char str[KSYM_SYMBOL_LEN]; | 68 | char str[KSYM_SYMBOL_LEN]; |
| 68 | 69 | ||
| 69 | 70 | ||
| 70 | start = (struct syscall_metadata *)__start_syscalls_metadata; | 71 | start = __start_syscalls_metadata; |
| 71 | stop = (struct syscall_metadata *)__stop_syscalls_metadata; | 72 | stop = __stop_syscalls_metadata; |
| 72 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); | 73 | kallsyms_lookup(syscall, NULL, NULL, NULL, str); |
| 73 | 74 | ||
| 74 | for ( ; start < stop; start++) { | 75 | for ( ; start < stop; start++) { |
| @@ -78,8 +79,8 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | |||
| 78 | * with "SyS" instead of "sys", leading to an unwanted | 79 | * with "SyS" instead of "sys", leading to an unwanted |
| 79 | * mismatch. | 80 | * mismatch. |
| 80 | */ | 81 | */ |
| 81 | if (start->name && !strcmp(start->name + 3, str + 3)) | 82 | if ((*start)->name && !strcmp((*start)->name + 3, str + 3)) |
| 82 | return start; | 83 | return *start; |
| 83 | } | 84 | } |
| 84 | return NULL; | 85 | return NULL; |
| 85 | } | 86 | } |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index e95ee7f31d43..68187af4889e 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -27,8 +27,8 @@ | |||
| 27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/jump_label.h> | 28 | #include <linux/jump_label.h> |
| 29 | 29 | ||
| 30 | extern struct tracepoint __start___tracepoints[]; | 30 | extern struct tracepoint * const __start___tracepoints_ptrs[]; |
| 31 | extern struct tracepoint __stop___tracepoints[]; | 31 | extern struct tracepoint * const __stop___tracepoints_ptrs[]; |
| 32 | 32 | ||
| 33 | /* Set to 1 to enable tracepoint debug output */ | 33 | /* Set to 1 to enable tracepoint debug output */ |
| 34 | static const int tracepoint_debug; | 34 | static const int tracepoint_debug; |
| @@ -298,10 +298,10 @@ static void disable_tracepoint(struct tracepoint *elem) | |||
| 298 | * | 298 | * |
| 299 | * Updates the probe callback corresponding to a range of tracepoints. | 299 | * Updates the probe callback corresponding to a range of tracepoints. |
| 300 | */ | 300 | */ |
| 301 | void | 301 | void tracepoint_update_probe_range(struct tracepoint * const *begin, |
| 302 | tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | 302 | struct tracepoint * const *end) |
| 303 | { | 303 | { |
| 304 | struct tracepoint *iter; | 304 | struct tracepoint * const *iter; |
| 305 | struct tracepoint_entry *mark_entry; | 305 | struct tracepoint_entry *mark_entry; |
| 306 | 306 | ||
| 307 | if (!begin) | 307 | if (!begin) |
| @@ -309,12 +309,12 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | |||
| 309 | 309 | ||
| 310 | mutex_lock(&tracepoints_mutex); | 310 | mutex_lock(&tracepoints_mutex); |
| 311 | for (iter = begin; iter < end; iter++) { | 311 | for (iter = begin; iter < end; iter++) { |
| 312 | mark_entry = get_tracepoint(iter->name); | 312 | mark_entry = get_tracepoint((*iter)->name); |
| 313 | if (mark_entry) { | 313 | if (mark_entry) { |
| 314 | set_tracepoint(&mark_entry, iter, | 314 | set_tracepoint(&mark_entry, *iter, |
| 315 | !!mark_entry->refcount); | 315 | !!mark_entry->refcount); |
| 316 | } else { | 316 | } else { |
| 317 | disable_tracepoint(iter); | 317 | disable_tracepoint(*iter); |
| 318 | } | 318 | } |
| 319 | } | 319 | } |
| 320 | mutex_unlock(&tracepoints_mutex); | 320 | mutex_unlock(&tracepoints_mutex); |
| @@ -326,8 +326,8 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) | |||
| 326 | static void tracepoint_update_probes(void) | 326 | static void tracepoint_update_probes(void) |
| 327 | { | 327 | { |
| 328 | /* Core kernel tracepoints */ | 328 | /* Core kernel tracepoints */ |
| 329 | tracepoint_update_probe_range(__start___tracepoints, | 329 | tracepoint_update_probe_range(__start___tracepoints_ptrs, |
| 330 | __stop___tracepoints); | 330 | __stop___tracepoints_ptrs); |
| 331 | /* tracepoints in modules. */ | 331 | /* tracepoints in modules. */ |
| 332 | module_update_tracepoints(); | 332 | module_update_tracepoints(); |
| 333 | } | 333 | } |
| @@ -514,8 +514,8 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_update_all); | |||
| 514 | * Will return the first tracepoint in the range if the input tracepoint is | 514 | * Will return the first tracepoint in the range if the input tracepoint is |
| 515 | * NULL. | 515 | * NULL. |
| 516 | */ | 516 | */ |
| 517 | int tracepoint_get_iter_range(struct tracepoint **tracepoint, | 517 | int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, |
| 518 | struct tracepoint *begin, struct tracepoint *end) | 518 | struct tracepoint * const *begin, struct tracepoint * const *end) |
| 519 | { | 519 | { |
| 520 | if (!*tracepoint && begin != end) { | 520 | if (!*tracepoint && begin != end) { |
| 521 | *tracepoint = begin; | 521 | *tracepoint = begin; |
| @@ -534,7 +534,8 @@ static void tracepoint_get_iter(struct tracepoint_iter *iter) | |||
| 534 | /* Core kernel tracepoints */ | 534 | /* Core kernel tracepoints */ |
| 535 | if (!iter->module) { | 535 | if (!iter->module) { |
| 536 | found = tracepoint_get_iter_range(&iter->tracepoint, | 536 | found = tracepoint_get_iter_range(&iter->tracepoint, |
| 537 | __start___tracepoints, __stop___tracepoints); | 537 | __start___tracepoints_ptrs, |
| 538 | __stop___tracepoints_ptrs); | ||
| 538 | if (found) | 539 | if (found) |
| 539 | goto end; | 540 | goto end; |
| 540 | } | 541 | } |
| @@ -585,8 +586,8 @@ int tracepoint_module_notify(struct notifier_block *self, | |||
| 585 | switch (val) { | 586 | switch (val) { |
| 586 | case MODULE_STATE_COMING: | 587 | case MODULE_STATE_COMING: |
| 587 | case MODULE_STATE_GOING: | 588 | case MODULE_STATE_GOING: |
| 588 | tracepoint_update_probe_range(mod->tracepoints, | 589 | tracepoint_update_probe_range(mod->tracepoints_ptrs, |
| 589 | mod->tracepoints + mod->num_tracepoints); | 590 | mod->tracepoints_ptrs + mod->num_tracepoints); |
| 590 | break; | 591 | break; |
| 591 | } | 592 | } |
| 592 | return 0; | 593 | return 0; |
