diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-05-21 11:53:06 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-05-21 11:53:46 -0400 |
| commit | f80836c86ebd44bf8f90882283a1618e09dfaed2 (patch) | |
| tree | be28455ff20df71fcebc3e59b2575721ab099ba3 | |
| parent | 598357eba6a55d27ddc7ead80ebb83fe1aad9b83 (diff) | |
| parent | ff5f149b6aec8edbfa3698721667acd043009a33 (diff) | |
Merge branch 'tip/tracing/core-7' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
28 files changed, 907 insertions, 611 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 7024b7d1126f..ee8a8411b055 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
| @@ -70,18 +70,25 @@ struct trace_iterator { | |||
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | struct trace_event; | ||
| 74 | |||
| 73 | typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, | 75 | typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, |
| 74 | int flags); | 76 | int flags, struct trace_event *event); |
| 75 | struct trace_event { | 77 | |
| 76 | struct hlist_node node; | 78 | struct trace_event_functions { |
| 77 | struct list_head list; | ||
| 78 | int type; | ||
| 79 | trace_print_func trace; | 79 | trace_print_func trace; |
| 80 | trace_print_func raw; | 80 | trace_print_func raw; |
| 81 | trace_print_func hex; | 81 | trace_print_func hex; |
| 82 | trace_print_func binary; | 82 | trace_print_func binary; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | struct trace_event { | ||
| 86 | struct hlist_node node; | ||
| 87 | struct list_head list; | ||
| 88 | int type; | ||
| 89 | struct trace_event_functions *funcs; | ||
| 90 | }; | ||
| 91 | |||
| 85 | extern int register_ftrace_event(struct trace_event *event); | 92 | extern int register_ftrace_event(struct trace_event *event); |
| 86 | extern int unregister_ftrace_event(struct trace_event *event); | 93 | extern int unregister_ftrace_event(struct trace_event *event); |
| 87 | 94 | ||
| @@ -113,29 +120,70 @@ void tracing_record_cmdline(struct task_struct *tsk); | |||
| 113 | 120 | ||
| 114 | struct event_filter; | 121 | struct event_filter; |
| 115 | 122 | ||
| 123 | enum trace_reg { | ||
| 124 | TRACE_REG_REGISTER, | ||
| 125 | TRACE_REG_UNREGISTER, | ||
| 126 | TRACE_REG_PERF_REGISTER, | ||
| 127 | TRACE_REG_PERF_UNREGISTER, | ||
| 128 | }; | ||
| 129 | |||
| 130 | struct ftrace_event_call; | ||
| 131 | |||
| 132 | struct ftrace_event_class { | ||
| 133 | char *system; | ||
| 134 | void *probe; | ||
| 135 | #ifdef CONFIG_PERF_EVENTS | ||
| 136 | void *perf_probe; | ||
| 137 | #endif | ||
| 138 | int (*reg)(struct ftrace_event_call *event, | ||
| 139 | enum trace_reg type); | ||
| 140 | int (*define_fields)(struct ftrace_event_call *); | ||
| 141 | struct list_head *(*get_fields)(struct ftrace_event_call *); | ||
| 142 | struct list_head fields; | ||
| 143 | int (*raw_init)(struct ftrace_event_call *); | ||
| 144 | }; | ||
| 145 | |||
| 146 | enum { | ||
| 147 | TRACE_EVENT_FL_ENABLED_BIT, | ||
| 148 | TRACE_EVENT_FL_FILTERED_BIT, | ||
| 149 | }; | ||
| 150 | |||
| 151 | enum { | ||
| 152 | TRACE_EVENT_FL_ENABLED = (1 << TRACE_EVENT_FL_ENABLED_BIT), | ||
| 153 | TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT), | ||
| 154 | }; | ||
| 155 | |||
| 116 | struct ftrace_event_call { | 156 | struct ftrace_event_call { |
| 117 | struct list_head list; | 157 | struct list_head list; |
| 158 | struct ftrace_event_class *class; | ||
| 118 | char *name; | 159 | char *name; |
| 119 | char *system; | ||
| 120 | struct dentry *dir; | 160 | struct dentry *dir; |
| 121 | struct trace_event *event; | 161 | struct trace_event event; |
| 122 | int enabled; | ||
| 123 | int (*regfunc)(struct ftrace_event_call *); | ||
| 124 | void (*unregfunc)(struct ftrace_event_call *); | ||
| 125 | int id; | ||
| 126 | const char *print_fmt; | 162 | const char *print_fmt; |
| 127 | int (*raw_init)(struct ftrace_event_call *); | ||
| 128 | int (*define_fields)(struct ftrace_event_call *); | ||
| 129 | struct list_head fields; | ||
| 130 | int filter_active; | ||
| 131 | struct event_filter *filter; | 163 | struct event_filter *filter; |
| 132 | void *mod; | 164 | void *mod; |
| 133 | void *data; | 165 | void *data; |
| 134 | 166 | ||
| 167 | /* | ||
| 168 | * 32 bit flags: | ||
| 169 | * bit 1: enabled | ||
| 170 | * bit 2: filter_active | ||
| 171 | * | ||
| 172 | * Changes to flags must hold the event_mutex. | ||
| 173 | * | ||
| 174 | * Note: Reads of flags do not hold the event_mutex since | ||
| 175 | * they occur in critical sections. But the way flags | ||
| 176 | * is currently used, these changes do no affect the code | ||
| 177 | * except that when a change is made, it may have a slight | ||
| 178 | * delay in propagating the changes to other CPUs due to | ||
| 179 | * caching and such. | ||
| 180 | */ | ||
| 181 | unsigned int flags; | ||
| 182 | |||
| 183 | #ifdef CONFIG_PERF_EVENTS | ||
| 135 | int perf_refcount; | 184 | int perf_refcount; |
| 136 | struct hlist_head *perf_events; | 185 | struct hlist_head *perf_events; |
| 137 | int (*perf_event_enable)(struct ftrace_event_call *); | 186 | #endif |
| 138 | void (*perf_event_disable)(struct ftrace_event_call *); | ||
| 139 | }; | 187 | }; |
| 140 | 188 | ||
| 141 | #define PERF_MAX_TRACE_SIZE 2048 | 189 | #define PERF_MAX_TRACE_SIZE 2048 |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 057929b0a651..a1a86a53bc73 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -103,22 +103,6 @@ struct perf_event_attr; | |||
| 103 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) | 103 | #define __SC_TEST5(t5, a5, ...) __SC_TEST(t5); __SC_TEST4(__VA_ARGS__) |
| 104 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) | 104 | #define __SC_TEST6(t6, a6, ...) __SC_TEST(t6); __SC_TEST5(__VA_ARGS__) |
| 105 | 105 | ||
| 106 | #ifdef CONFIG_PERF_EVENTS | ||
| 107 | |||
| 108 | #define TRACE_SYS_ENTER_PERF_INIT(sname) \ | ||
| 109 | .perf_event_enable = perf_sysenter_enable, \ | ||
| 110 | .perf_event_disable = perf_sysenter_disable, | ||
| 111 | |||
| 112 | #define TRACE_SYS_EXIT_PERF_INIT(sname) \ | ||
| 113 | .perf_event_enable = perf_sysexit_enable, \ | ||
| 114 | .perf_event_disable = perf_sysexit_disable, | ||
| 115 | #else | ||
| 116 | #define TRACE_SYS_ENTER_PERF(sname) | ||
| 117 | #define TRACE_SYS_ENTER_PERF_INIT(sname) | ||
| 118 | #define TRACE_SYS_EXIT_PERF(sname) | ||
| 119 | #define TRACE_SYS_EXIT_PERF_INIT(sname) | ||
| 120 | #endif /* CONFIG_PERF_EVENTS */ | ||
| 121 | |||
| 122 | #ifdef CONFIG_FTRACE_SYSCALLS | 106 | #ifdef CONFIG_FTRACE_SYSCALLS |
| 123 | #define __SC_STR_ADECL1(t, a) #a | 107 | #define __SC_STR_ADECL1(t, a) #a |
| 124 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) | 108 | #define __SC_STR_ADECL2(t, a, ...) #a, __SC_STR_ADECL1(__VA_ARGS__) |
| @@ -134,54 +118,43 @@ struct perf_event_attr; | |||
| 134 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) | 118 | #define __SC_STR_TDECL5(t, a, ...) #t, __SC_STR_TDECL4(__VA_ARGS__) |
| 135 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) | 119 | #define __SC_STR_TDECL6(t, a, ...) #t, __SC_STR_TDECL5(__VA_ARGS__) |
| 136 | 120 | ||
| 121 | extern struct ftrace_event_class event_class_syscall_enter; | ||
| 122 | extern struct ftrace_event_class event_class_syscall_exit; | ||
| 123 | extern struct trace_event_functions enter_syscall_print_funcs; | ||
| 124 | extern struct trace_event_functions exit_syscall_print_funcs; | ||
| 125 | |||
| 137 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ | 126 | #define SYSCALL_TRACE_ENTER_EVENT(sname) \ |
| 138 | static const struct syscall_metadata __syscall_meta_##sname; \ | 127 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 139 | static struct ftrace_event_call \ | 128 | static struct ftrace_event_call \ |
| 140 | __attribute__((__aligned__(4))) event_enter_##sname; \ | 129 | __attribute__((__aligned__(4))) event_enter_##sname; \ |
| 141 | static struct trace_event enter_syscall_print_##sname = { \ | ||
| 142 | .trace = print_syscall_enter, \ | ||
| 143 | }; \ | ||
| 144 | static struct ftrace_event_call __used \ | 130 | static struct ftrace_event_call __used \ |
| 145 | __attribute__((__aligned__(4))) \ | 131 | __attribute__((__aligned__(4))) \ |
| 146 | __attribute__((section("_ftrace_events"))) \ | 132 | __attribute__((section("_ftrace_events"))) \ |
| 147 | event_enter_##sname = { \ | 133 | event_enter_##sname = { \ |
| 148 | .name = "sys_enter"#sname, \ | 134 | .name = "sys_enter"#sname, \ |
| 149 | .system = "syscalls", \ | 135 | .class = &event_class_syscall_enter, \ |
| 150 | .event = &enter_syscall_print_##sname, \ | 136 | .event.funcs = &enter_syscall_print_funcs, \ |
| 151 | .raw_init = init_syscall_trace, \ | ||
| 152 | .define_fields = syscall_enter_define_fields, \ | ||
| 153 | .regfunc = reg_event_syscall_enter, \ | ||
| 154 | .unregfunc = unreg_event_syscall_enter, \ | ||
| 155 | .data = (void *)&__syscall_meta_##sname,\ | 137 | .data = (void *)&__syscall_meta_##sname,\ |
| 156 | TRACE_SYS_ENTER_PERF_INIT(sname) \ | ||
| 157 | } | 138 | } |
| 158 | 139 | ||
| 159 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ | 140 | #define SYSCALL_TRACE_EXIT_EVENT(sname) \ |
| 160 | static const struct syscall_metadata __syscall_meta_##sname; \ | 141 | static struct syscall_metadata __syscall_meta_##sname; \ |
| 161 | static struct ftrace_event_call \ | 142 | static struct ftrace_event_call \ |
| 162 | __attribute__((__aligned__(4))) event_exit_##sname; \ | 143 | __attribute__((__aligned__(4))) event_exit_##sname; \ |
| 163 | static struct trace_event exit_syscall_print_##sname = { \ | ||
| 164 | .trace = print_syscall_exit, \ | ||
| 165 | }; \ | ||
| 166 | static struct ftrace_event_call __used \ | 144 | static struct ftrace_event_call __used \ |
| 167 | __attribute__((__aligned__(4))) \ | 145 | __attribute__((__aligned__(4))) \ |
| 168 | __attribute__((section("_ftrace_events"))) \ | 146 | __attribute__((section("_ftrace_events"))) \ |
| 169 | event_exit_##sname = { \ | 147 | event_exit_##sname = { \ |
| 170 | .name = "sys_exit"#sname, \ | 148 | .name = "sys_exit"#sname, \ |
| 171 | .system = "syscalls", \ | 149 | .class = &event_class_syscall_exit, \ |
| 172 | .event = &exit_syscall_print_##sname, \ | 150 | .event.funcs = &exit_syscall_print_funcs, \ |
| 173 | .raw_init = init_syscall_trace, \ | ||
| 174 | .define_fields = syscall_exit_define_fields, \ | ||
| 175 | .regfunc = reg_event_syscall_exit, \ | ||
| 176 | .unregfunc = unreg_event_syscall_exit, \ | ||
| 177 | .data = (void *)&__syscall_meta_##sname,\ | 151 | .data = (void *)&__syscall_meta_##sname,\ |
| 178 | TRACE_SYS_EXIT_PERF_INIT(sname) \ | ||
| 179 | } | 152 | } |
| 180 | 153 | ||
| 181 | #define SYSCALL_METADATA(sname, nb) \ | 154 | #define SYSCALL_METADATA(sname, nb) \ |
| 182 | SYSCALL_TRACE_ENTER_EVENT(sname); \ | 155 | SYSCALL_TRACE_ENTER_EVENT(sname); \ |
| 183 | SYSCALL_TRACE_EXIT_EVENT(sname); \ | 156 | SYSCALL_TRACE_EXIT_EVENT(sname); \ |
| 184 | static const struct syscall_metadata __used \ | 157 | static struct syscall_metadata __used \ |
| 185 | __attribute__((__aligned__(4))) \ | 158 | __attribute__((__aligned__(4))) \ |
| 186 | __attribute__((section("__syscalls_metadata"))) \ | 159 | __attribute__((section("__syscalls_metadata"))) \ |
| 187 | __syscall_meta_##sname = { \ | 160 | __syscall_meta_##sname = { \ |
| @@ -191,12 +164,14 @@ struct perf_event_attr; | |||
| 191 | .args = args_##sname, \ | 164 | .args = args_##sname, \ |
| 192 | .enter_event = &event_enter_##sname, \ | 165 | .enter_event = &event_enter_##sname, \ |
| 193 | .exit_event = &event_exit_##sname, \ | 166 | .exit_event = &event_exit_##sname, \ |
| 167 | .enter_fields = LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \ | ||
| 168 | .exit_fields = LIST_HEAD_INIT(__syscall_meta_##sname.exit_fields), \ | ||
| 194 | }; | 169 | }; |
| 195 | 170 | ||
| 196 | #define SYSCALL_DEFINE0(sname) \ | 171 | #define SYSCALL_DEFINE0(sname) \ |
| 197 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ | 172 | SYSCALL_TRACE_ENTER_EVENT(_##sname); \ |
| 198 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ | 173 | SYSCALL_TRACE_EXIT_EVENT(_##sname); \ |
| 199 | static const struct syscall_metadata __used \ | 174 | static struct syscall_metadata __used \ |
| 200 | __attribute__((__aligned__(4))) \ | 175 | __attribute__((__aligned__(4))) \ |
| 201 | __attribute__((section("__syscalls_metadata"))) \ | 176 | __attribute__((section("__syscalls_metadata"))) \ |
| 202 | __syscall_meta__##sname = { \ | 177 | __syscall_meta__##sname = { \ |
| @@ -204,6 +179,8 @@ struct perf_event_attr; | |||
| 204 | .nb_args = 0, \ | 179 | .nb_args = 0, \ |
| 205 | .enter_event = &event_enter__##sname, \ | 180 | .enter_event = &event_enter__##sname, \ |
| 206 | .exit_event = &event_exit__##sname, \ | 181 | .exit_event = &event_exit__##sname, \ |
| 182 | .enter_fields = LIST_HEAD_INIT(__syscall_meta__##sname.enter_fields), \ | ||
| 183 | .exit_fields = LIST_HEAD_INIT(__syscall_meta__##sname.exit_fields), \ | ||
| 207 | }; \ | 184 | }; \ |
| 208 | asmlinkage long sys_##sname(void) | 185 | asmlinkage long sys_##sname(void) |
| 209 | #else | 186 | #else |
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 1d85f9a6a199..9a59d1f98cd4 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -20,12 +20,17 @@ | |||
| 20 | struct module; | 20 | struct module; |
| 21 | struct tracepoint; | 21 | struct tracepoint; |
| 22 | 22 | ||
| 23 | struct tracepoint_func { | ||
| 24 | void *func; | ||
| 25 | void *data; | ||
| 26 | }; | ||
| 27 | |||
| 23 | struct tracepoint { | 28 | struct tracepoint { |
| 24 | const char *name; /* Tracepoint name */ | 29 | const char *name; /* Tracepoint name */ |
| 25 | int state; /* State. */ | 30 | int state; /* State. */ |
| 26 | void (*regfunc)(void); | 31 | void (*regfunc)(void); |
| 27 | void (*unregfunc)(void); | 32 | void (*unregfunc)(void); |
| 28 | void **funcs; | 33 | struct tracepoint_func *funcs; |
| 29 | } __attribute__((aligned(32))); /* | 34 | } __attribute__((aligned(32))); /* |
| 30 | * Aligned on 32 bytes because it is | 35 | * Aligned on 32 bytes because it is |
| 31 | * globally visible and gcc happily | 36 | * globally visible and gcc happily |
| @@ -37,16 +42,19 @@ struct tracepoint { | |||
| 37 | * Connect a probe to a tracepoint. | 42 | * Connect a probe to a tracepoint. |
| 38 | * Internal API, should not be used directly. | 43 | * Internal API, should not be used directly. |
| 39 | */ | 44 | */ |
| 40 | extern int tracepoint_probe_register(const char *name, void *probe); | 45 | extern int tracepoint_probe_register(const char *name, void *probe, void *data); |
| 41 | 46 | ||
| 42 | /* | 47 | /* |
| 43 | * Disconnect a probe from a tracepoint. | 48 | * Disconnect a probe from a tracepoint. |
| 44 | * Internal API, should not be used directly. | 49 | * Internal API, should not be used directly. |
| 45 | */ | 50 | */ |
| 46 | extern int tracepoint_probe_unregister(const char *name, void *probe); | 51 | extern int |
| 52 | tracepoint_probe_unregister(const char *name, void *probe, void *data); | ||
| 47 | 53 | ||
| 48 | extern int tracepoint_probe_register_noupdate(const char *name, void *probe); | 54 | extern int tracepoint_probe_register_noupdate(const char *name, void *probe, |
| 49 | extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe); | 55 | void *data); |
| 56 | extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe, | ||
| 57 | void *data); | ||
| 50 | extern void tracepoint_probe_update_all(void); | 58 | extern void tracepoint_probe_update_all(void); |
| 51 | 59 | ||
| 52 | struct tracepoint_iter { | 60 | struct tracepoint_iter { |
| @@ -102,17 +110,27 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
| 102 | /* | 110 | /* |
| 103 | * it_func[0] is never NULL because there is at least one element in the array | 111 | * it_func[0] is never NULL because there is at least one element in the array |
| 104 | * when the array itself is non NULL. | 112 | * when the array itself is non NULL. |
| 113 | * | ||
| 114 | * Note, the proto and args passed in includes "__data" as the first parameter. | ||
| 115 | * The reason for this is to handle the "void" prototype. If a tracepoint | ||
| 116 | * has a "void" prototype, then it is invalid to declare a function | ||
| 117 | * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just | ||
| 118 | * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto". | ||
| 105 | */ | 119 | */ |
| 106 | #define __DO_TRACE(tp, proto, args) \ | 120 | #define __DO_TRACE(tp, proto, args) \ |
| 107 | do { \ | 121 | do { \ |
| 108 | void **it_func; \ | 122 | struct tracepoint_func *it_func_ptr; \ |
| 123 | void *it_func; \ | ||
| 124 | void *__data; \ | ||
| 109 | \ | 125 | \ |
| 110 | rcu_read_lock_sched_notrace(); \ | 126 | rcu_read_lock_sched_notrace(); \ |
| 111 | it_func = rcu_dereference_sched((tp)->funcs); \ | 127 | it_func_ptr = rcu_dereference_sched((tp)->funcs); \ |
| 112 | if (it_func) { \ | 128 | if (it_func_ptr) { \ |
| 113 | do { \ | 129 | do { \ |
| 114 | ((void(*)(proto))(*it_func))(args); \ | 130 | it_func = (it_func_ptr)->func; \ |
| 115 | } while (*(++it_func)); \ | 131 | __data = (it_func_ptr)->data; \ |
| 132 | ((void(*)(proto))(it_func))(args); \ | ||
| 133 | } while ((++it_func_ptr)->func); \ | ||
| 116 | } \ | 134 | } \ |
| 117 | rcu_read_unlock_sched_notrace(); \ | 135 | rcu_read_unlock_sched_notrace(); \ |
| 118 | } while (0) | 136 | } while (0) |
| @@ -122,24 +140,32 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
| 122 | * not add unwanted padding between the beginning of the section and the | 140 | * not add unwanted padding between the beginning of the section and the |
| 123 | * structure. Force alignment to the same alignment as the section start. | 141 | * structure. Force alignment to the same alignment as the section start. |
| 124 | */ | 142 | */ |
| 125 | #define DECLARE_TRACE(name, proto, args) \ | 143 | #define __DECLARE_TRACE(name, proto, args, data_proto, data_args) \ |
| 126 | extern struct tracepoint __tracepoint_##name; \ | 144 | extern struct tracepoint __tracepoint_##name; \ |
| 127 | static inline void trace_##name(proto) \ | 145 | static inline void trace_##name(proto) \ |
| 128 | { \ | 146 | { \ |
| 129 | if (unlikely(__tracepoint_##name.state)) \ | 147 | if (unlikely(__tracepoint_##name.state)) \ |
| 130 | __DO_TRACE(&__tracepoint_##name, \ | 148 | __DO_TRACE(&__tracepoint_##name, \ |
| 131 | TP_PROTO(proto), TP_ARGS(args)); \ | 149 | TP_PROTO(data_proto), \ |
| 150 | TP_ARGS(data_args)); \ | ||
| 151 | } \ | ||
| 152 | static inline int \ | ||
| 153 | register_trace_##name(void (*probe)(data_proto), void *data) \ | ||
| 154 | { \ | ||
| 155 | return tracepoint_probe_register(#name, (void *)probe, \ | ||
| 156 | data); \ | ||
| 132 | } \ | 157 | } \ |
| 133 | static inline int register_trace_##name(void (*probe)(proto)) \ | 158 | static inline int \ |
| 159 | unregister_trace_##name(void (*probe)(data_proto), void *data) \ | ||
| 134 | { \ | 160 | { \ |
| 135 | return tracepoint_probe_register(#name, (void *)probe); \ | 161 | return tracepoint_probe_unregister(#name, (void *)probe, \ |
| 162 | data); \ | ||
| 136 | } \ | 163 | } \ |
| 137 | static inline int unregister_trace_##name(void (*probe)(proto)) \ | 164 | static inline void \ |
| 165 | check_trace_callback_type_##name(void (*cb)(data_proto)) \ | ||
| 138 | { \ | 166 | { \ |
| 139 | return tracepoint_probe_unregister(#name, (void *)probe);\ | ||
| 140 | } | 167 | } |
| 141 | 168 | ||
| 142 | |||
| 143 | #define DEFINE_TRACE_FN(name, reg, unreg) \ | 169 | #define DEFINE_TRACE_FN(name, reg, unreg) \ |
| 144 | static const char __tpstrtab_##name[] \ | 170 | static const char __tpstrtab_##name[] \ |
| 145 | __attribute__((section("__tracepoints_strings"))) = #name; \ | 171 | __attribute__((section("__tracepoints_strings"))) = #name; \ |
| @@ -156,18 +182,23 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
| 156 | EXPORT_SYMBOL(__tracepoint_##name) | 182 | EXPORT_SYMBOL(__tracepoint_##name) |
| 157 | 183 | ||
| 158 | #else /* !CONFIG_TRACEPOINTS */ | 184 | #else /* !CONFIG_TRACEPOINTS */ |
| 159 | #define DECLARE_TRACE(name, proto, args) \ | 185 | #define __DECLARE_TRACE(name, proto, args, data_proto, data_args) \ |
| 160 | static inline void _do_trace_##name(struct tracepoint *tp, proto) \ | ||
| 161 | { } \ | ||
| 162 | static inline void trace_##name(proto) \ | 186 | static inline void trace_##name(proto) \ |
| 163 | { } \ | 187 | { } \ |
| 164 | static inline int register_trace_##name(void (*probe)(proto)) \ | 188 | static inline int \ |
| 189 | register_trace_##name(void (*probe)(data_proto), \ | ||
| 190 | void *data) \ | ||
| 165 | { \ | 191 | { \ |
| 166 | return -ENOSYS; \ | 192 | return -ENOSYS; \ |
| 167 | } \ | 193 | } \ |
| 168 | static inline int unregister_trace_##name(void (*probe)(proto)) \ | 194 | static inline int \ |
| 195 | unregister_trace_##name(void (*probe)(data_proto), \ | ||
| 196 | void *data) \ | ||
| 169 | { \ | 197 | { \ |
| 170 | return -ENOSYS; \ | 198 | return -ENOSYS; \ |
| 199 | } \ | ||
| 200 | static inline void check_trace_callback_type_##name(void (*cb)(data_proto)) \ | ||
| 201 | { \ | ||
| 171 | } | 202 | } |
| 172 | 203 | ||
| 173 | #define DEFINE_TRACE_FN(name, reg, unreg) | 204 | #define DEFINE_TRACE_FN(name, reg, unreg) |
| @@ -176,6 +207,29 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
| 176 | #define EXPORT_TRACEPOINT_SYMBOL(name) | 207 | #define EXPORT_TRACEPOINT_SYMBOL(name) |
| 177 | 208 | ||
| 178 | #endif /* CONFIG_TRACEPOINTS */ | 209 | #endif /* CONFIG_TRACEPOINTS */ |
| 210 | |||
| 211 | /* | ||
| 212 | * The need for the DECLARE_TRACE_NOARGS() is to handle the prototype | ||
| 213 | * (void). "void" is a special value in a function prototype and can | ||
| 214 | * not be combined with other arguments. Since the DECLARE_TRACE() | ||
| 215 | * macro adds a data element at the beginning of the prototype, | ||
| 216 | * we need a way to differentiate "(void *data, proto)" from | ||
| 217 | * "(void *data, void)". The second prototype is invalid. | ||
| 218 | * | ||
| 219 | * DECLARE_TRACE_NOARGS() passes "void" as the tracepoint prototype | ||
| 220 | * and "void *__data" as the callback prototype. | ||
| 221 | * | ||
| 222 | * DECLARE_TRACE() passes "proto" as the tracepoint protoype and | ||
| 223 | * "void *__data, proto" as the callback prototype. | ||
| 224 | */ | ||
| 225 | #define DECLARE_TRACE_NOARGS(name) \ | ||
| 226 | __DECLARE_TRACE(name, void, , void *__data, __data) | ||
| 227 | |||
| 228 | #define DECLARE_TRACE(name, proto, args) \ | ||
| 229 | __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ | ||
| 230 | PARAMS(void *__data, proto), \ | ||
| 231 | PARAMS(__data, args)) | ||
| 232 | |||
| 179 | #endif /* DECLARE_TRACE */ | 233 | #endif /* DECLARE_TRACE */ |
| 180 | 234 | ||
| 181 | #ifndef TRACE_EVENT | 235 | #ifndef TRACE_EVENT |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 4eb2148f1321..0152b8673bd7 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
| @@ -62,7 +62,10 @@ | |||
| 62 | struct trace_entry ent; \ | 62 | struct trace_entry ent; \ |
| 63 | tstruct \ | 63 | tstruct \ |
| 64 | char __data[0]; \ | 64 | char __data[0]; \ |
| 65 | }; | 65 | }; \ |
| 66 | \ | ||
| 67 | static struct ftrace_event_class event_class_##name; | ||
| 68 | |||
| 66 | #undef DEFINE_EVENT | 69 | #undef DEFINE_EVENT |
| 67 | #define DEFINE_EVENT(template, name, proto, args) \ | 70 | #define DEFINE_EVENT(template, name, proto, args) \ |
| 68 | static struct ftrace_event_call \ | 71 | static struct ftrace_event_call \ |
| @@ -147,7 +150,7 @@ | |||
| 147 | * | 150 | * |
| 148 | * entry = iter->ent; | 151 | * entry = iter->ent; |
| 149 | * | 152 | * |
| 150 | * if (entry->type != event_<call>.id) { | 153 | * if (entry->type != event_<call>->event.type) { |
| 151 | * WARN_ON_ONCE(1); | 154 | * WARN_ON_ONCE(1); |
| 152 | * return TRACE_TYPE_UNHANDLED; | 155 | * return TRACE_TYPE_UNHANDLED; |
| 153 | * } | 156 | * } |
| @@ -203,18 +206,22 @@ | |||
| 203 | #undef DECLARE_EVENT_CLASS | 206 | #undef DECLARE_EVENT_CLASS |
| 204 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 207 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 205 | static notrace enum print_line_t \ | 208 | static notrace enum print_line_t \ |
| 206 | ftrace_raw_output_id_##call(int event_id, const char *name, \ | 209 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ |
| 207 | struct trace_iterator *iter, int flags) \ | 210 | struct trace_event *trace_event) \ |
| 208 | { \ | 211 | { \ |
| 212 | struct ftrace_event_call *event; \ | ||
| 209 | struct trace_seq *s = &iter->seq; \ | 213 | struct trace_seq *s = &iter->seq; \ |
| 210 | struct ftrace_raw_##call *field; \ | 214 | struct ftrace_raw_##call *field; \ |
| 211 | struct trace_entry *entry; \ | 215 | struct trace_entry *entry; \ |
| 212 | struct trace_seq *p; \ | 216 | struct trace_seq *p; \ |
| 213 | int ret; \ | 217 | int ret; \ |
| 214 | \ | 218 | \ |
| 219 | event = container_of(trace_event, struct ftrace_event_call, \ | ||
| 220 | event); \ | ||
| 221 | \ | ||
| 215 | entry = iter->ent; \ | 222 | entry = iter->ent; \ |
| 216 | \ | 223 | \ |
| 217 | if (entry->type != event_id) { \ | 224 | if (entry->type != event->event.type) { \ |
| 218 | WARN_ON_ONCE(1); \ | 225 | WARN_ON_ONCE(1); \ |
| 219 | return TRACE_TYPE_UNHANDLED; \ | 226 | return TRACE_TYPE_UNHANDLED; \ |
| 220 | } \ | 227 | } \ |
| @@ -223,7 +230,7 @@ ftrace_raw_output_id_##call(int event_id, const char *name, \ | |||
| 223 | \ | 230 | \ |
| 224 | p = &get_cpu_var(ftrace_event_seq); \ | 231 | p = &get_cpu_var(ftrace_event_seq); \ |
| 225 | trace_seq_init(p); \ | 232 | trace_seq_init(p); \ |
| 226 | ret = trace_seq_printf(s, "%s: ", name); \ | 233 | ret = trace_seq_printf(s, "%s: ", event->name); \ |
| 227 | if (ret) \ | 234 | if (ret) \ |
| 228 | ret = trace_seq_printf(s, print); \ | 235 | ret = trace_seq_printf(s, print); \ |
| 229 | put_cpu(); \ | 236 | put_cpu(); \ |
| @@ -231,21 +238,16 @@ ftrace_raw_output_id_##call(int event_id, const char *name, \ | |||
| 231 | return TRACE_TYPE_PARTIAL_LINE; \ | 238 | return TRACE_TYPE_PARTIAL_LINE; \ |
| 232 | \ | 239 | \ |
| 233 | return TRACE_TYPE_HANDLED; \ | 240 | return TRACE_TYPE_HANDLED; \ |
| 234 | } | 241 | } \ |
| 235 | 242 | static struct trace_event_functions ftrace_event_type_funcs_##call = { \ | |
| 236 | #undef DEFINE_EVENT | 243 | .trace = ftrace_raw_output_##call, \ |
| 237 | #define DEFINE_EVENT(template, name, proto, args) \ | 244 | }; |
| 238 | static notrace enum print_line_t \ | ||
| 239 | ftrace_raw_output_##name(struct trace_iterator *iter, int flags) \ | ||
| 240 | { \ | ||
| 241 | return ftrace_raw_output_id_##template(event_##name.id, \ | ||
| 242 | #name, iter, flags); \ | ||
| 243 | } | ||
| 244 | 245 | ||
| 245 | #undef DEFINE_EVENT_PRINT | 246 | #undef DEFINE_EVENT_PRINT |
| 246 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 247 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
| 247 | static notrace enum print_line_t \ | 248 | static notrace enum print_line_t \ |
| 248 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | 249 | ftrace_raw_output_##call(struct trace_iterator *iter, int flags, \ |
| 250 | struct trace_event *event) \ | ||
| 249 | { \ | 251 | { \ |
| 250 | struct trace_seq *s = &iter->seq; \ | 252 | struct trace_seq *s = &iter->seq; \ |
| 251 | struct ftrace_raw_##template *field; \ | 253 | struct ftrace_raw_##template *field; \ |
| @@ -255,7 +257,7 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
| 255 | \ | 257 | \ |
| 256 | entry = iter->ent; \ | 258 | entry = iter->ent; \ |
| 257 | \ | 259 | \ |
| 258 | if (entry->type != event_##call.id) { \ | 260 | if (entry->type != event_##call.event.type) { \ |
| 259 | WARN_ON_ONCE(1); \ | 261 | WARN_ON_ONCE(1); \ |
| 260 | return TRACE_TYPE_UNHANDLED; \ | 262 | return TRACE_TYPE_UNHANDLED; \ |
| 261 | } \ | 263 | } \ |
| @@ -272,7 +274,10 @@ ftrace_raw_output_##call(struct trace_iterator *iter, int flags) \ | |||
| 272 | return TRACE_TYPE_PARTIAL_LINE; \ | 274 | return TRACE_TYPE_PARTIAL_LINE; \ |
| 273 | \ | 275 | \ |
| 274 | return TRACE_TYPE_HANDLED; \ | 276 | return TRACE_TYPE_HANDLED; \ |
| 275 | } | 277 | } \ |
| 278 | static struct trace_event_functions ftrace_event_type_funcs_##call = { \ | ||
| 279 | .trace = ftrace_raw_output_##call, \ | ||
| 280 | }; | ||
| 276 | 281 | ||
| 277 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 282 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 278 | 283 | ||
| @@ -378,80 +383,18 @@ static inline notrace int ftrace_get_offsets_##call( \ | |||
| 378 | 383 | ||
| 379 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 384 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 380 | 385 | ||
| 381 | #ifdef CONFIG_PERF_EVENTS | ||
| 382 | |||
| 383 | /* | ||
| 384 | * Generate the functions needed for tracepoint perf_event support. | ||
| 385 | * | ||
| 386 | * NOTE: The insertion profile callback (ftrace_profile_<call>) is defined later | ||
| 387 | * | ||
| 388 | * static int ftrace_profile_enable_<call>(void) | ||
| 389 | * { | ||
| 390 | * return register_trace_<call>(ftrace_profile_<call>); | ||
| 391 | * } | ||
| 392 | * | ||
| 393 | * static void ftrace_profile_disable_<call>(void) | ||
| 394 | * { | ||
| 395 | * unregister_trace_<call>(ftrace_profile_<call>); | ||
| 396 | * } | ||
| 397 | * | ||
| 398 | */ | ||
| 399 | |||
| 400 | #undef DECLARE_EVENT_CLASS | ||
| 401 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) | ||
| 402 | |||
| 403 | #undef DEFINE_EVENT | ||
| 404 | #define DEFINE_EVENT(template, name, proto, args) \ | ||
| 405 | \ | ||
| 406 | static void perf_trace_##name(proto); \ | ||
| 407 | \ | ||
| 408 | static notrace int \ | ||
| 409 | perf_trace_enable_##name(struct ftrace_event_call *unused) \ | ||
| 410 | { \ | ||
| 411 | return register_trace_##name(perf_trace_##name); \ | ||
| 412 | } \ | ||
| 413 | \ | ||
| 414 | static notrace void \ | ||
| 415 | perf_trace_disable_##name(struct ftrace_event_call *unused) \ | ||
| 416 | { \ | ||
| 417 | unregister_trace_##name(perf_trace_##name); \ | ||
| 418 | } | ||
| 419 | |||
| 420 | #undef DEFINE_EVENT_PRINT | ||
| 421 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | ||
| 422 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | ||
| 423 | |||
| 424 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | ||
| 425 | |||
| 426 | #endif /* CONFIG_PERF_EVENTS */ | ||
| 427 | |||
| 428 | /* | 386 | /* |
| 429 | * Stage 4 of the trace events. | 387 | * Stage 4 of the trace events. |
| 430 | * | 388 | * |
| 431 | * Override the macros in <trace/trace_events.h> to include the following: | 389 | * Override the macros in <trace/trace_events.h> to include the following: |
| 432 | * | 390 | * |
| 433 | * static void ftrace_event_<call>(proto) | ||
| 434 | * { | ||
| 435 | * event_trace_printk(_RET_IP_, "<call>: " <fmt>); | ||
| 436 | * } | ||
| 437 | * | ||
| 438 | * static int ftrace_reg_event_<call>(struct ftrace_event_call *unused) | ||
| 439 | * { | ||
| 440 | * return register_trace_<call>(ftrace_event_<call>); | ||
| 441 | * } | ||
| 442 | * | ||
| 443 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) | ||
| 444 | * { | ||
| 445 | * unregister_trace_<call>(ftrace_event_<call>); | ||
| 446 | * } | ||
| 447 | * | ||
| 448 | * | ||
| 449 | * For those macros defined with TRACE_EVENT: | 391 | * For those macros defined with TRACE_EVENT: |
| 450 | * | 392 | * |
| 451 | * static struct ftrace_event_call event_<call>; | 393 | * static struct ftrace_event_call event_<call>; |
| 452 | * | 394 | * |
| 453 | * static void ftrace_raw_event_<call>(proto) | 395 | * static void ftrace_raw_event_<call>(void *__data, proto) |
| 454 | * { | 396 | * { |
| 397 | * struct ftrace_event_call *event_call = __data; | ||
| 455 | * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; | 398 | * struct ftrace_data_offsets_<call> __maybe_unused __data_offsets; |
| 456 | * struct ring_buffer_event *event; | 399 | * struct ring_buffer_event *event; |
| 457 | * struct ftrace_raw_<call> *entry; <-- defined in stage 1 | 400 | * struct ftrace_raw_<call> *entry; <-- defined in stage 1 |
| @@ -466,7 +409,7 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
| 466 | * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); | 409 | * __data_size = ftrace_get_offsets_<call>(&__data_offsets, args); |
| 467 | * | 410 | * |
| 468 | * event = trace_current_buffer_lock_reserve(&buffer, | 411 | * event = trace_current_buffer_lock_reserve(&buffer, |
| 469 | * event_<call>.id, | 412 | * event_<call>->event.type, |
| 470 | * sizeof(*entry) + __data_size, | 413 | * sizeof(*entry) + __data_size, |
| 471 | * irq_flags, pc); | 414 | * irq_flags, pc); |
| 472 | * if (!event) | 415 | * if (!event) |
| @@ -481,43 +424,42 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
| 481 | * event, irq_flags, pc); | 424 | * event, irq_flags, pc); |
| 482 | * } | 425 | * } |
| 483 | * | 426 | * |
| 484 | * static int ftrace_raw_reg_event_<call>(struct ftrace_event_call *unused) | ||
| 485 | * { | ||
| 486 | * return register_trace_<call>(ftrace_raw_event_<call>); | ||
| 487 | * } | ||
| 488 | * | ||
| 489 | * static void ftrace_unreg_event_<call>(struct ftrace_event_call *unused) | ||
| 490 | * { | ||
| 491 | * unregister_trace_<call>(ftrace_raw_event_<call>); | ||
| 492 | * } | ||
| 493 | * | ||
| 494 | * static struct trace_event ftrace_event_type_<call> = { | 427 | * static struct trace_event ftrace_event_type_<call> = { |
| 495 | * .trace = ftrace_raw_output_<call>, <-- stage 2 | 428 | * .trace = ftrace_raw_output_<call>, <-- stage 2 |
| 496 | * }; | 429 | * }; |
| 497 | * | 430 | * |
| 498 | * static const char print_fmt_<call>[] = <TP_printk>; | 431 | * static const char print_fmt_<call>[] = <TP_printk>; |
| 499 | * | 432 | * |
| 433 | * static struct ftrace_event_class __used event_class_<template> = { | ||
| 434 | * .system = "<system>", | ||
| 435 | * .define_fields = ftrace_define_fields_<call>, | ||
| 436 | * .fields = LIST_HEAD_INIT(event_class_##call.fields), | ||
| 437 | * .raw_init = trace_event_raw_init, | ||
| 438 | * .probe = ftrace_raw_event_##call, | ||
| 439 | * }; | ||
| 440 | * | ||
| 500 | * static struct ftrace_event_call __used | 441 | * static struct ftrace_event_call __used |
| 501 | * __attribute__((__aligned__(4))) | 442 | * __attribute__((__aligned__(4))) |
| 502 | * __attribute__((section("_ftrace_events"))) event_<call> = { | 443 | * __attribute__((section("_ftrace_events"))) event_<call> = { |
| 503 | * .name = "<call>", | 444 | * .name = "<call>", |
| 504 | * .system = "<system>", | 445 | * .class = event_class_<template>, |
| 505 | * .raw_init = trace_event_raw_init, | 446 | * .event = &ftrace_event_type_<call>, |
| 506 | * .regfunc = ftrace_reg_event_<call>, | ||
| 507 | * .unregfunc = ftrace_unreg_event_<call>, | ||
| 508 | * .print_fmt = print_fmt_<call>, | 447 | * .print_fmt = print_fmt_<call>, |
| 509 | * .define_fields = ftrace_define_fields_<call>, | 448 | * }; |
| 510 | * } | ||
| 511 | * | 449 | * |
| 512 | */ | 450 | */ |
| 513 | 451 | ||
| 514 | #ifdef CONFIG_PERF_EVENTS | 452 | #ifdef CONFIG_PERF_EVENTS |
| 515 | 453 | ||
| 454 | #define _TRACE_PERF_PROTO(call, proto) \ | ||
| 455 | static notrace void \ | ||
| 456 | perf_trace_##call(void *__data, proto); | ||
| 457 | |||
| 516 | #define _TRACE_PERF_INIT(call) \ | 458 | #define _TRACE_PERF_INIT(call) \ |
| 517 | .perf_event_enable = perf_trace_enable_##call, \ | 459 | .perf_probe = perf_trace_##call, |
| 518 | .perf_event_disable = perf_trace_disable_##call, | ||
| 519 | 460 | ||
| 520 | #else | 461 | #else |
| 462 | #define _TRACE_PERF_PROTO(call, proto) | ||
| 521 | #define _TRACE_PERF_INIT(call) | 463 | #define _TRACE_PERF_INIT(call) |
| 522 | #endif /* CONFIG_PERF_EVENTS */ | 464 | #endif /* CONFIG_PERF_EVENTS */ |
| 523 | 465 | ||
| @@ -551,9 +493,9 @@ perf_trace_disable_##name(struct ftrace_event_call *unused) \ | |||
| 551 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 493 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 552 | \ | 494 | \ |
| 553 | static notrace void \ | 495 | static notrace void \ |
| 554 | ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | 496 | ftrace_raw_event_##call(void *__data, proto) \ |
| 555 | proto) \ | ||
| 556 | { \ | 497 | { \ |
| 498 | struct ftrace_event_call *event_call = __data; \ | ||
| 557 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 499 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
| 558 | struct ring_buffer_event *event; \ | 500 | struct ring_buffer_event *event; \ |
| 559 | struct ftrace_raw_##call *entry; \ | 501 | struct ftrace_raw_##call *entry; \ |
| @@ -568,7 +510,7 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | |||
| 568 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 510 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
| 569 | \ | 511 | \ |
| 570 | event = trace_current_buffer_lock_reserve(&buffer, \ | 512 | event = trace_current_buffer_lock_reserve(&buffer, \ |
| 571 | event_call->id, \ | 513 | event_call->event.type, \ |
| 572 | sizeof(*entry) + __data_size, \ | 514 | sizeof(*entry) + __data_size, \ |
| 573 | irq_flags, pc); \ | 515 | irq_flags, pc); \ |
| 574 | if (!event) \ | 516 | if (!event) \ |
| @@ -583,34 +525,21 @@ ftrace_raw_event_id_##call(struct ftrace_event_call *event_call, \ | |||
| 583 | trace_nowake_buffer_unlock_commit(buffer, \ | 525 | trace_nowake_buffer_unlock_commit(buffer, \ |
| 584 | event, irq_flags, pc); \ | 526 | event, irq_flags, pc); \ |
| 585 | } | 527 | } |
| 528 | /* | ||
| 529 | * The ftrace_test_probe is compiled out, it is only here as a build time check | ||
| 530 | * to make sure that if the tracepoint handling changes, the ftrace probe will | ||
| 531 | * fail to compile unless it too is updated. | ||
| 532 | */ | ||
| 586 | 533 | ||
| 587 | #undef DEFINE_EVENT | 534 | #undef DEFINE_EVENT |
| 588 | #define DEFINE_EVENT(template, call, proto, args) \ | 535 | #define DEFINE_EVENT(template, call, proto, args) \ |
| 589 | \ | 536 | static inline void ftrace_test_probe_##call(void) \ |
| 590 | static notrace void ftrace_raw_event_##call(proto) \ | ||
| 591 | { \ | ||
| 592 | ftrace_raw_event_id_##template(&event_##call, args); \ | ||
| 593 | } \ | ||
| 594 | \ | ||
| 595 | static notrace int \ | ||
| 596 | ftrace_raw_reg_event_##call(struct ftrace_event_call *unused) \ | ||
| 597 | { \ | ||
| 598 | return register_trace_##call(ftrace_raw_event_##call); \ | ||
| 599 | } \ | ||
| 600 | \ | ||
| 601 | static notrace void \ | ||
| 602 | ftrace_raw_unreg_event_##call(struct ftrace_event_call *unused) \ | ||
| 603 | { \ | 537 | { \ |
| 604 | unregister_trace_##call(ftrace_raw_event_##call); \ | 538 | check_trace_callback_type_##call(ftrace_raw_event_##template); \ |
| 605 | } \ | 539 | } |
| 606 | \ | ||
| 607 | static struct trace_event ftrace_event_type_##call = { \ | ||
| 608 | .trace = ftrace_raw_output_##call, \ | ||
| 609 | }; | ||
| 610 | 540 | ||
| 611 | #undef DEFINE_EVENT_PRINT | 541 | #undef DEFINE_EVENT_PRINT |
| 612 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 542 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) |
| 613 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | ||
| 614 | 543 | ||
| 615 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 544 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| 616 | 545 | ||
| @@ -627,7 +556,16 @@ static struct trace_event ftrace_event_type_##call = { \ | |||
| 627 | 556 | ||
| 628 | #undef DECLARE_EVENT_CLASS | 557 | #undef DECLARE_EVENT_CLASS |
| 629 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 558 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 630 | static const char print_fmt_##call[] = print; | 559 | _TRACE_PERF_PROTO(call, PARAMS(proto)); \ |
| 560 | static const char print_fmt_##call[] = print; \ | ||
| 561 | static struct ftrace_event_class __used event_class_##call = { \ | ||
| 562 | .system = __stringify(TRACE_SYSTEM), \ | ||
| 563 | .define_fields = ftrace_define_fields_##call, \ | ||
| 564 | .fields = LIST_HEAD_INIT(event_class_##call.fields),\ | ||
| 565 | .raw_init = trace_event_raw_init, \ | ||
| 566 | .probe = ftrace_raw_event_##call, \ | ||
| 567 | _TRACE_PERF_INIT(call) \ | ||
| 568 | }; | ||
| 631 | 569 | ||
| 632 | #undef DEFINE_EVENT | 570 | #undef DEFINE_EVENT |
| 633 | #define DEFINE_EVENT(template, call, proto, args) \ | 571 | #define DEFINE_EVENT(template, call, proto, args) \ |
| @@ -636,15 +574,10 @@ static struct ftrace_event_call __used \ | |||
| 636 | __attribute__((__aligned__(4))) \ | 574 | __attribute__((__aligned__(4))) \ |
| 637 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 575 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
| 638 | .name = #call, \ | 576 | .name = #call, \ |
| 639 | .system = __stringify(TRACE_SYSTEM), \ | 577 | .class = &event_class_##template, \ |
| 640 | .event = &ftrace_event_type_##call, \ | 578 | .event.funcs = &ftrace_event_type_funcs_##template, \ |
| 641 | .raw_init = trace_event_raw_init, \ | ||
| 642 | .regfunc = ftrace_raw_reg_event_##call, \ | ||
| 643 | .unregfunc = ftrace_raw_unreg_event_##call, \ | ||
| 644 | .print_fmt = print_fmt_##template, \ | 579 | .print_fmt = print_fmt_##template, \ |
| 645 | .define_fields = ftrace_define_fields_##template, \ | 580 | }; |
| 646 | _TRACE_PERF_INIT(call) \ | ||
| 647 | } | ||
| 648 | 581 | ||
| 649 | #undef DEFINE_EVENT_PRINT | 582 | #undef DEFINE_EVENT_PRINT |
| 650 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ | 583 | #define DEFINE_EVENT_PRINT(template, call, proto, args, print) \ |
| @@ -655,14 +588,9 @@ static struct ftrace_event_call __used \ | |||
| 655 | __attribute__((__aligned__(4))) \ | 588 | __attribute__((__aligned__(4))) \ |
| 656 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 589 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
| 657 | .name = #call, \ | 590 | .name = #call, \ |
| 658 | .system = __stringify(TRACE_SYSTEM), \ | 591 | .class = &event_class_##template, \ |
| 659 | .event = &ftrace_event_type_##call, \ | 592 | .event.funcs = &ftrace_event_type_funcs_##call, \ |
| 660 | .raw_init = trace_event_raw_init, \ | ||
| 661 | .regfunc = ftrace_raw_reg_event_##call, \ | ||
| 662 | .unregfunc = ftrace_raw_unreg_event_##call, \ | ||
| 663 | .print_fmt = print_fmt_##call, \ | 593 | .print_fmt = print_fmt_##call, \ |
| 664 | .define_fields = ftrace_define_fields_##template, \ | ||
| 665 | _TRACE_PERF_INIT(call) \ | ||
| 666 | } | 594 | } |
| 667 | 595 | ||
| 668 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) | 596 | #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) |
| @@ -762,17 +690,20 @@ __attribute__((section("_ftrace_events"))) event_##call = { \ | |||
| 762 | #undef DECLARE_EVENT_CLASS | 690 | #undef DECLARE_EVENT_CLASS |
| 763 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ | 691 | #define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \ |
| 764 | static notrace void \ | 692 | static notrace void \ |
| 765 | perf_trace_templ_##call(struct ftrace_event_call *event_call, \ | 693 | perf_trace_##call(void *__data, proto) \ |
| 766 | struct pt_regs *__regs, proto) \ | ||
| 767 | { \ | 694 | { \ |
| 695 | struct ftrace_event_call *event_call = __data; \ | ||
| 768 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 696 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
| 769 | struct ftrace_raw_##call *entry; \ | 697 | struct ftrace_raw_##call *entry; \ |
| 698 | struct pt_regs __regs; \ | ||
| 770 | u64 __addr = 0, __count = 1; \ | 699 | u64 __addr = 0, __count = 1; \ |
| 771 | struct hlist_head *head; \ | 700 | struct hlist_head *head; \ |
| 772 | int __entry_size; \ | 701 | int __entry_size; \ |
| 773 | int __data_size; \ | 702 | int __data_size; \ |
| 774 | int rctx; \ | 703 | int rctx; \ |
| 775 | \ | 704 | \ |
| 705 | perf_fetch_caller_regs(&__regs, 1); \ | ||
| 706 | \ | ||
| 776 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 707 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
| 777 | __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ | 708 | __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\ |
| 778 | sizeof(u64)); \ | 709 | sizeof(u64)); \ |
| @@ -783,7 +714,7 @@ perf_trace_templ_##call(struct ftrace_event_call *event_call, \ | |||
| 783 | return; \ | 714 | return; \ |
| 784 | \ | 715 | \ |
| 785 | entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \ | 716 | entry = (struct ftrace_raw_##call *)perf_trace_buf_prepare( \ |
| 786 | __entry_size, event_call->id, __regs, &rctx); \ | 717 | __entry_size, event_call->event.type, &__regs, &rctx); \ |
| 787 | if (!entry) \ | 718 | if (!entry) \ |
| 788 | return; \ | 719 | return; \ |
| 789 | \ | 720 | \ |
| @@ -793,20 +724,22 @@ perf_trace_templ_##call(struct ftrace_event_call *event_call, \ | |||
| 793 | \ | 724 | \ |
| 794 | head = per_cpu_ptr(event_call->perf_events, smp_processor_id());\ | 725 | head = per_cpu_ptr(event_call->perf_events, smp_processor_id());\ |
| 795 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ | 726 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ |
| 796 | __count, __regs, head); \ | 727 | __count, &__regs, head); \ |
| 797 | } | 728 | } |
| 798 | 729 | ||
| 730 | /* | ||
| 731 | * This part is compiled out, it is only here as a build time check | ||
| 732 | * to make sure that if the tracepoint handling changes, the | ||
| 733 | * perf probe will fail to compile unless it too is updated. | ||
| 734 | */ | ||
| 799 | #undef DEFINE_EVENT | 735 | #undef DEFINE_EVENT |
| 800 | #define DEFINE_EVENT(template, call, proto, args) \ | 736 | #define DEFINE_EVENT(template, call, proto, args) \ |
| 801 | static notrace void perf_trace_##call(proto) \ | 737 | static inline void perf_test_probe_##call(void) \ |
| 802 | { \ | 738 | { \ |
| 803 | struct ftrace_event_call *event_call = &event_##call; \ | 739 | check_trace_callback_type_##call(perf_trace_##template); \ |
| 804 | struct pt_regs __regs; \ | ||
| 805 | \ | ||
| 806 | perf_fetch_caller_regs(&__regs, 1); \ | ||
| 807 | perf_trace_templ_##template(event_call, &__regs, args); \ | ||
| 808 | } | 740 | } |
| 809 | 741 | ||
| 742 | |||
| 810 | #undef DEFINE_EVENT_PRINT | 743 | #undef DEFINE_EVENT_PRINT |
| 811 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ | 744 | #define DEFINE_EVENT_PRINT(template, name, proto, args, print) \ |
| 812 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) | 745 | DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args)) |
diff --git a/include/trace/syscall.h b/include/trace/syscall.h index e5e5f48dbfb3..257e08960d7b 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h | |||
| @@ -25,6 +25,8 @@ struct syscall_metadata { | |||
| 25 | int nb_args; | 25 | int nb_args; |
| 26 | const char **types; | 26 | const char **types; |
| 27 | const char **args; | 27 | const char **args; |
| 28 | struct list_head enter_fields; | ||
| 29 | struct list_head exit_fields; | ||
| 28 | 30 | ||
| 29 | struct ftrace_event_call *enter_event; | 31 | struct ftrace_event_call *enter_event; |
| 30 | struct ftrace_event_call *exit_event; | 32 | struct ftrace_event_call *exit_event; |
| @@ -34,16 +36,16 @@ struct syscall_metadata { | |||
| 34 | extern unsigned long arch_syscall_addr(int nr); | 36 | extern unsigned long arch_syscall_addr(int nr); |
| 35 | extern int init_syscall_trace(struct ftrace_event_call *call); | 37 | extern int init_syscall_trace(struct ftrace_event_call *call); |
| 36 | 38 | ||
| 37 | extern int syscall_enter_define_fields(struct ftrace_event_call *call); | ||
| 38 | extern int syscall_exit_define_fields(struct ftrace_event_call *call); | ||
| 39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); | 39 | extern int reg_event_syscall_enter(struct ftrace_event_call *call); |
| 40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); | 40 | extern void unreg_event_syscall_enter(struct ftrace_event_call *call); |
| 41 | extern int reg_event_syscall_exit(struct ftrace_event_call *call); | 41 | extern int reg_event_syscall_exit(struct ftrace_event_call *call); |
| 42 | extern void unreg_event_syscall_exit(struct ftrace_event_call *call); | 42 | extern void unreg_event_syscall_exit(struct ftrace_event_call *call); |
| 43 | extern int | 43 | extern int |
| 44 | ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s); | 44 | ftrace_format_syscall(struct ftrace_event_call *call, struct trace_seq *s); |
| 45 | enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags); | 45 | enum print_line_t print_syscall_enter(struct trace_iterator *iter, int flags, |
| 46 | enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags); | 46 | struct trace_event *event); |
| 47 | enum print_line_t print_syscall_exit(struct trace_iterator *iter, int flags, | ||
| 48 | struct trace_event *event); | ||
| 47 | #endif | 49 | #endif |
| 48 | 50 | ||
| 49 | #ifdef CONFIG_PERF_EVENTS | 51 | #ifdef CONFIG_PERF_EVENTS |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index b3bc91a3f510..36ea2b65dcdc 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -675,28 +675,33 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq, | |||
| 675 | } | 675 | } |
| 676 | } | 676 | } |
| 677 | 677 | ||
| 678 | static void blk_add_trace_rq_abort(struct request_queue *q, struct request *rq) | 678 | static void blk_add_trace_rq_abort(void *ignore, |
| 679 | struct request_queue *q, struct request *rq) | ||
| 679 | { | 680 | { |
| 680 | blk_add_trace_rq(q, rq, BLK_TA_ABORT); | 681 | blk_add_trace_rq(q, rq, BLK_TA_ABORT); |
| 681 | } | 682 | } |
| 682 | 683 | ||
| 683 | static void blk_add_trace_rq_insert(struct request_queue *q, struct request *rq) | 684 | static void blk_add_trace_rq_insert(void *ignore, |
| 685 | struct request_queue *q, struct request *rq) | ||
| 684 | { | 686 | { |
| 685 | blk_add_trace_rq(q, rq, BLK_TA_INSERT); | 687 | blk_add_trace_rq(q, rq, BLK_TA_INSERT); |
| 686 | } | 688 | } |
| 687 | 689 | ||
| 688 | static void blk_add_trace_rq_issue(struct request_queue *q, struct request *rq) | 690 | static void blk_add_trace_rq_issue(void *ignore, |
| 691 | struct request_queue *q, struct request *rq) | ||
| 689 | { | 692 | { |
| 690 | blk_add_trace_rq(q, rq, BLK_TA_ISSUE); | 693 | blk_add_trace_rq(q, rq, BLK_TA_ISSUE); |
| 691 | } | 694 | } |
| 692 | 695 | ||
| 693 | static void blk_add_trace_rq_requeue(struct request_queue *q, | 696 | static void blk_add_trace_rq_requeue(void *ignore, |
| 697 | struct request_queue *q, | ||
| 694 | struct request *rq) | 698 | struct request *rq) |
| 695 | { | 699 | { |
| 696 | blk_add_trace_rq(q, rq, BLK_TA_REQUEUE); | 700 | blk_add_trace_rq(q, rq, BLK_TA_REQUEUE); |
| 697 | } | 701 | } |
| 698 | 702 | ||
| 699 | static void blk_add_trace_rq_complete(struct request_queue *q, | 703 | static void blk_add_trace_rq_complete(void *ignore, |
| 704 | struct request_queue *q, | ||
| 700 | struct request *rq) | 705 | struct request *rq) |
| 701 | { | 706 | { |
| 702 | blk_add_trace_rq(q, rq, BLK_TA_COMPLETE); | 707 | blk_add_trace_rq(q, rq, BLK_TA_COMPLETE); |
| @@ -724,34 +729,40 @@ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio, | |||
| 724 | !bio_flagged(bio, BIO_UPTODATE), 0, NULL); | 729 | !bio_flagged(bio, BIO_UPTODATE), 0, NULL); |
| 725 | } | 730 | } |
| 726 | 731 | ||
| 727 | static void blk_add_trace_bio_bounce(struct request_queue *q, struct bio *bio) | 732 | static void blk_add_trace_bio_bounce(void *ignore, |
| 733 | struct request_queue *q, struct bio *bio) | ||
| 728 | { | 734 | { |
| 729 | blk_add_trace_bio(q, bio, BLK_TA_BOUNCE); | 735 | blk_add_trace_bio(q, bio, BLK_TA_BOUNCE); |
| 730 | } | 736 | } |
| 731 | 737 | ||
| 732 | static void blk_add_trace_bio_complete(struct request_queue *q, struct bio *bio) | 738 | static void blk_add_trace_bio_complete(void *ignore, |
| 739 | struct request_queue *q, struct bio *bio) | ||
| 733 | { | 740 | { |
| 734 | blk_add_trace_bio(q, bio, BLK_TA_COMPLETE); | 741 | blk_add_trace_bio(q, bio, BLK_TA_COMPLETE); |
| 735 | } | 742 | } |
| 736 | 743 | ||
| 737 | static void blk_add_trace_bio_backmerge(struct request_queue *q, | 744 | static void blk_add_trace_bio_backmerge(void *ignore, |
| 745 | struct request_queue *q, | ||
| 738 | struct bio *bio) | 746 | struct bio *bio) |
| 739 | { | 747 | { |
| 740 | blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE); | 748 | blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE); |
| 741 | } | 749 | } |
| 742 | 750 | ||
| 743 | static void blk_add_trace_bio_frontmerge(struct request_queue *q, | 751 | static void blk_add_trace_bio_frontmerge(void *ignore, |
| 752 | struct request_queue *q, | ||
| 744 | struct bio *bio) | 753 | struct bio *bio) |
| 745 | { | 754 | { |
| 746 | blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE); | 755 | blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE); |
| 747 | } | 756 | } |
| 748 | 757 | ||
| 749 | static void blk_add_trace_bio_queue(struct request_queue *q, struct bio *bio) | 758 | static void blk_add_trace_bio_queue(void *ignore, |
| 759 | struct request_queue *q, struct bio *bio) | ||
| 750 | { | 760 | { |
| 751 | blk_add_trace_bio(q, bio, BLK_TA_QUEUE); | 761 | blk_add_trace_bio(q, bio, BLK_TA_QUEUE); |
| 752 | } | 762 | } |
| 753 | 763 | ||
| 754 | static void blk_add_trace_getrq(struct request_queue *q, | 764 | static void blk_add_trace_getrq(void *ignore, |
| 765 | struct request_queue *q, | ||
| 755 | struct bio *bio, int rw) | 766 | struct bio *bio, int rw) |
| 756 | { | 767 | { |
| 757 | if (bio) | 768 | if (bio) |
| @@ -765,7 +776,8 @@ static void blk_add_trace_getrq(struct request_queue *q, | |||
| 765 | } | 776 | } |
| 766 | 777 | ||
| 767 | 778 | ||
| 768 | static void blk_add_trace_sleeprq(struct request_queue *q, | 779 | static void blk_add_trace_sleeprq(void *ignore, |
| 780 | struct request_queue *q, | ||
| 769 | struct bio *bio, int rw) | 781 | struct bio *bio, int rw) |
| 770 | { | 782 | { |
| 771 | if (bio) | 783 | if (bio) |
| @@ -779,7 +791,7 @@ static void blk_add_trace_sleeprq(struct request_queue *q, | |||
| 779 | } | 791 | } |
| 780 | } | 792 | } |
| 781 | 793 | ||
| 782 | static void blk_add_trace_plug(struct request_queue *q) | 794 | static void blk_add_trace_plug(void *ignore, struct request_queue *q) |
| 783 | { | 795 | { |
| 784 | struct blk_trace *bt = q->blk_trace; | 796 | struct blk_trace *bt = q->blk_trace; |
| 785 | 797 | ||
| @@ -787,7 +799,7 @@ static void blk_add_trace_plug(struct request_queue *q) | |||
| 787 | __blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL); | 799 | __blk_add_trace(bt, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL); |
| 788 | } | 800 | } |
| 789 | 801 | ||
| 790 | static void blk_add_trace_unplug_io(struct request_queue *q) | 802 | static void blk_add_trace_unplug_io(void *ignore, struct request_queue *q) |
| 791 | { | 803 | { |
| 792 | struct blk_trace *bt = q->blk_trace; | 804 | struct blk_trace *bt = q->blk_trace; |
| 793 | 805 | ||
| @@ -800,7 +812,7 @@ static void blk_add_trace_unplug_io(struct request_queue *q) | |||
| 800 | } | 812 | } |
| 801 | } | 813 | } |
| 802 | 814 | ||
| 803 | static void blk_add_trace_unplug_timer(struct request_queue *q) | 815 | static void blk_add_trace_unplug_timer(void *ignore, struct request_queue *q) |
| 804 | { | 816 | { |
| 805 | struct blk_trace *bt = q->blk_trace; | 817 | struct blk_trace *bt = q->blk_trace; |
| 806 | 818 | ||
| @@ -813,7 +825,8 @@ static void blk_add_trace_unplug_timer(struct request_queue *q) | |||
| 813 | } | 825 | } |
| 814 | } | 826 | } |
| 815 | 827 | ||
| 816 | static void blk_add_trace_split(struct request_queue *q, struct bio *bio, | 828 | static void blk_add_trace_split(void *ignore, |
| 829 | struct request_queue *q, struct bio *bio, | ||
| 817 | unsigned int pdu) | 830 | unsigned int pdu) |
| 818 | { | 831 | { |
| 819 | struct blk_trace *bt = q->blk_trace; | 832 | struct blk_trace *bt = q->blk_trace; |
| @@ -839,8 +852,9 @@ static void blk_add_trace_split(struct request_queue *q, struct bio *bio, | |||
| 839 | * it spans a stripe (or similar). Add a trace for that action. | 852 | * it spans a stripe (or similar). Add a trace for that action. |
| 840 | * | 853 | * |
| 841 | **/ | 854 | **/ |
| 842 | static void blk_add_trace_remap(struct request_queue *q, struct bio *bio, | 855 | static void blk_add_trace_remap(void *ignore, |
| 843 | dev_t dev, sector_t from) | 856 | struct request_queue *q, struct bio *bio, |
| 857 | dev_t dev, sector_t from) | ||
| 844 | { | 858 | { |
| 845 | struct blk_trace *bt = q->blk_trace; | 859 | struct blk_trace *bt = q->blk_trace; |
| 846 | struct blk_io_trace_remap r; | 860 | struct blk_io_trace_remap r; |
| @@ -869,7 +883,8 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio, | |||
| 869 | * Add a trace for that action. | 883 | * Add a trace for that action. |
| 870 | * | 884 | * |
| 871 | **/ | 885 | **/ |
| 872 | static void blk_add_trace_rq_remap(struct request_queue *q, | 886 | static void blk_add_trace_rq_remap(void *ignore, |
| 887 | struct request_queue *q, | ||
| 873 | struct request *rq, dev_t dev, | 888 | struct request *rq, dev_t dev, |
| 874 | sector_t from) | 889 | sector_t from) |
| 875 | { | 890 | { |
| @@ -921,64 +936,64 @@ static void blk_register_tracepoints(void) | |||
| 921 | { | 936 | { |
| 922 | int ret; | 937 | int ret; |
| 923 | 938 | ||
| 924 | ret = register_trace_block_rq_abort(blk_add_trace_rq_abort); | 939 | ret = register_trace_block_rq_abort(blk_add_trace_rq_abort, NULL); |
| 925 | WARN_ON(ret); | 940 | WARN_ON(ret); |
| 926 | ret = register_trace_block_rq_insert(blk_add_trace_rq_insert); | 941 | ret = register_trace_block_rq_insert(blk_add_trace_rq_insert, NULL); |
| 927 | WARN_ON(ret); | 942 | WARN_ON(ret); |
| 928 | ret = register_trace_block_rq_issue(blk_add_trace_rq_issue); | 943 | ret = register_trace_block_rq_issue(blk_add_trace_rq_issue, NULL); |
| 929 | WARN_ON(ret); | 944 | WARN_ON(ret); |
| 930 | ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue); | 945 | ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue, NULL); |
| 931 | WARN_ON(ret); | 946 | WARN_ON(ret); |
| 932 | ret = register_trace_block_rq_complete(blk_add_trace_rq_complete); | 947 | ret = register_trace_block_rq_complete(blk_add_trace_rq_complete, NULL); |
| 933 | WARN_ON(ret); | 948 | WARN_ON(ret); |
| 934 | ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce); | 949 | ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce, NULL); |
| 935 | WARN_ON(ret); | 950 | WARN_ON(ret); |
| 936 | ret = register_trace_block_bio_complete(blk_add_trace_bio_complete); | 951 | ret = register_trace_block_bio_complete(blk_add_trace_bio_complete, NULL); |
| 937 | WARN_ON(ret); | 952 | WARN_ON(ret); |
| 938 | ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge); | 953 | ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge, NULL); |
| 939 | WARN_ON(ret); | 954 | WARN_ON(ret); |
| 940 | ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge); | 955 | ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge, NULL); |
| 941 | WARN_ON(ret); | 956 | WARN_ON(ret); |
| 942 | ret = register_trace_block_bio_queue(blk_add_trace_bio_queue); | 957 | ret = register_trace_block_bio_queue(blk_add_trace_bio_queue, NULL); |
| 943 | WARN_ON(ret); | 958 | WARN_ON(ret); |
| 944 | ret = register_trace_block_getrq(blk_add_trace_getrq); | 959 | ret = register_trace_block_getrq(blk_add_trace_getrq, NULL); |
| 945 | WARN_ON(ret); | 960 | WARN_ON(ret); |
| 946 | ret = register_trace_block_sleeprq(blk_add_trace_sleeprq); | 961 | ret = register_trace_block_sleeprq(blk_add_trace_sleeprq, NULL); |
| 947 | WARN_ON(ret); | 962 | WARN_ON(ret); |
| 948 | ret = register_trace_block_plug(blk_add_trace_plug); | 963 | ret = register_trace_block_plug(blk_add_trace_plug, NULL); |
| 949 | WARN_ON(ret); | 964 | WARN_ON(ret); |
| 950 | ret = register_trace_block_unplug_timer(blk_add_trace_unplug_timer); | 965 | ret = register_trace_block_unplug_timer(blk_add_trace_unplug_timer, NULL); |
| 951 | WARN_ON(ret); | 966 | WARN_ON(ret); |
| 952 | ret = register_trace_block_unplug_io(blk_add_trace_unplug_io); | 967 | ret = register_trace_block_unplug_io(blk_add_trace_unplug_io, NULL); |
| 953 | WARN_ON(ret); | 968 | WARN_ON(ret); |
| 954 | ret = register_trace_block_split(blk_add_trace_split); | 969 | ret = register_trace_block_split(blk_add_trace_split, NULL); |
| 955 | WARN_ON(ret); | 970 | WARN_ON(ret); |
| 956 | ret = register_trace_block_remap(blk_add_trace_remap); | 971 | ret = register_trace_block_remap(blk_add_trace_remap, NULL); |
| 957 | WARN_ON(ret); | 972 | WARN_ON(ret); |
| 958 | ret = register_trace_block_rq_remap(blk_add_trace_rq_remap); | 973 | ret = register_trace_block_rq_remap(blk_add_trace_rq_remap, NULL); |
| 959 | WARN_ON(ret); | 974 | WARN_ON(ret); |
| 960 | } | 975 | } |
| 961 | 976 | ||
| 962 | static void blk_unregister_tracepoints(void) | 977 | static void blk_unregister_tracepoints(void) |
| 963 | { | 978 | { |
| 964 | unregister_trace_block_rq_remap(blk_add_trace_rq_remap); | 979 | unregister_trace_block_rq_remap(blk_add_trace_rq_remap, NULL); |
| 965 | unregister_trace_block_remap(blk_add_trace_remap); | 980 | unregister_trace_block_remap(blk_add_trace_remap, NULL); |
| 966 | unregister_trace_block_split(blk_add_trace_split); | 981 | unregister_trace_block_split(blk_add_trace_split, NULL); |
| 967 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io); | 982 | unregister_trace_block_unplug_io(blk_add_trace_unplug_io, NULL); |
| 968 | unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer); | 983 | unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer, NULL); |
| 969 | unregister_trace_block_plug(blk_add_trace_plug); | 984 | unregister_trace_block_plug(blk_add_trace_plug, NULL); |
| 970 | unregister_trace_block_sleeprq(blk_add_trace_sleeprq); | 985 | unregister_trace_block_sleeprq(blk_add_trace_sleeprq, NULL); |
| 971 | unregister_trace_block_getrq(blk_add_trace_getrq); | 986 | unregister_trace_block_getrq(blk_add_trace_getrq, NULL); |
| 972 | unregister_trace_block_bio_queue(blk_add_trace_bio_queue); | 987 | unregister_trace_block_bio_queue(blk_add_trace_bio_queue, NULL); |
| 973 | unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge); | 988 | unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge, NULL); |
| 974 | unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge); | 989 | unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge, NULL); |
| 975 | unregister_trace_block_bio_complete(blk_add_trace_bio_complete); | 990 | unregister_trace_block_bio_complete(blk_add_trace_bio_complete, NULL); |
| 976 | unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce); | 991 | unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce, NULL); |
| 977 | unregister_trace_block_rq_complete(blk_add_trace_rq_complete); | 992 | unregister_trace_block_rq_complete(blk_add_trace_rq_complete, NULL); |
| 978 | unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue); | 993 | unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue, NULL); |
| 979 | unregister_trace_block_rq_issue(blk_add_trace_rq_issue); | 994 | unregister_trace_block_rq_issue(blk_add_trace_rq_issue, NULL); |
| 980 | unregister_trace_block_rq_insert(blk_add_trace_rq_insert); | 995 | unregister_trace_block_rq_insert(blk_add_trace_rq_insert, NULL); |
| 981 | unregister_trace_block_rq_abort(blk_add_trace_rq_abort); | 996 | unregister_trace_block_rq_abort(blk_add_trace_rq_abort, NULL); |
| 982 | 997 | ||
| 983 | tracepoint_synchronize_unregister(); | 998 | tracepoint_synchronize_unregister(); |
| 984 | } | 999 | } |
| @@ -1321,7 +1336,7 @@ out: | |||
| 1321 | } | 1336 | } |
| 1322 | 1337 | ||
| 1323 | static enum print_line_t blk_trace_event_print(struct trace_iterator *iter, | 1338 | static enum print_line_t blk_trace_event_print(struct trace_iterator *iter, |
| 1324 | int flags) | 1339 | int flags, struct trace_event *event) |
| 1325 | { | 1340 | { |
| 1326 | return print_one_line(iter, false); | 1341 | return print_one_line(iter, false); |
| 1327 | } | 1342 | } |
| @@ -1343,7 +1358,8 @@ static int blk_trace_synthesize_old_trace(struct trace_iterator *iter) | |||
| 1343 | } | 1358 | } |
| 1344 | 1359 | ||
| 1345 | static enum print_line_t | 1360 | static enum print_line_t |
| 1346 | blk_trace_event_print_binary(struct trace_iterator *iter, int flags) | 1361 | blk_trace_event_print_binary(struct trace_iterator *iter, int flags, |
| 1362 | struct trace_event *event) | ||
| 1347 | { | 1363 | { |
| 1348 | return blk_trace_synthesize_old_trace(iter) ? | 1364 | return blk_trace_synthesize_old_trace(iter) ? |
| 1349 | TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; | 1365 | TRACE_TYPE_HANDLED : TRACE_TYPE_PARTIAL_LINE; |
| @@ -1381,12 +1397,16 @@ static struct tracer blk_tracer __read_mostly = { | |||
| 1381 | .set_flag = blk_tracer_set_flag, | 1397 | .set_flag = blk_tracer_set_flag, |
| 1382 | }; | 1398 | }; |
| 1383 | 1399 | ||
| 1384 | static struct trace_event trace_blk_event = { | 1400 | static struct trace_event_functions trace_blk_event_funcs = { |
| 1385 | .type = TRACE_BLK, | ||
| 1386 | .trace = blk_trace_event_print, | 1401 | .trace = blk_trace_event_print, |
| 1387 | .binary = blk_trace_event_print_binary, | 1402 | .binary = blk_trace_event_print_binary, |
| 1388 | }; | 1403 | }; |
| 1389 | 1404 | ||
| 1405 | static struct trace_event trace_blk_event = { | ||
| 1406 | .type = TRACE_BLK, | ||
| 1407 | .funcs = &trace_blk_event_funcs, | ||
| 1408 | }; | ||
| 1409 | |||
| 1390 | static int __init init_blk_tracer(void) | 1410 | static int __init init_blk_tracer(void) |
| 1391 | { | 1411 | { |
| 1392 | if (!register_ftrace_event(&trace_blk_event)) { | 1412 | if (!register_ftrace_event(&trace_blk_event)) { |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 32837e19e3bd..6d2cb14f9449 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
| @@ -3234,7 +3234,8 @@ free: | |||
| 3234 | } | 3234 | } |
| 3235 | 3235 | ||
| 3236 | static void | 3236 | static void |
| 3237 | ftrace_graph_probe_sched_switch(struct task_struct *prev, struct task_struct *next) | 3237 | ftrace_graph_probe_sched_switch(void *ignore, |
| 3238 | struct task_struct *prev, struct task_struct *next) | ||
| 3238 | { | 3239 | { |
| 3239 | unsigned long long timestamp; | 3240 | unsigned long long timestamp; |
| 3240 | int index; | 3241 | int index; |
| @@ -3288,7 +3289,7 @@ static int start_graph_tracing(void) | |||
| 3288 | } while (ret == -EAGAIN); | 3289 | } while (ret == -EAGAIN); |
| 3289 | 3290 | ||
| 3290 | if (!ret) { | 3291 | if (!ret) { |
| 3291 | ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch); | 3292 | ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); |
| 3292 | if (ret) | 3293 | if (ret) |
| 3293 | pr_info("ftrace_graph: Couldn't activate tracepoint" | 3294 | pr_info("ftrace_graph: Couldn't activate tracepoint" |
| 3294 | " probe to kernel_sched_switch\n"); | 3295 | " probe to kernel_sched_switch\n"); |
| @@ -3364,7 +3365,7 @@ void unregister_ftrace_graph(void) | |||
| 3364 | ftrace_graph_entry = ftrace_graph_entry_stub; | 3365 | ftrace_graph_entry = ftrace_graph_entry_stub; |
| 3365 | ftrace_shutdown(FTRACE_STOP_FUNC_RET); | 3366 | ftrace_shutdown(FTRACE_STOP_FUNC_RET); |
| 3366 | unregister_pm_notifier(&ftrace_suspend_notifier); | 3367 | unregister_pm_notifier(&ftrace_suspend_notifier); |
| 3367 | unregister_trace_sched_switch(ftrace_graph_probe_sched_switch); | 3368 | unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); |
| 3368 | 3369 | ||
| 3369 | out: | 3370 | out: |
| 3370 | mutex_unlock(&ftrace_lock); | 3371 | mutex_unlock(&ftrace_lock); |
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c index a91da69f153a..bbfc1bb1660b 100644 --- a/kernel/trace/kmemtrace.c +++ b/kernel/trace/kmemtrace.c | |||
| @@ -95,7 +95,8 @@ static inline void kmemtrace_free(enum kmemtrace_type_id type_id, | |||
| 95 | trace_wake_up(); | 95 | trace_wake_up(); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | static void kmemtrace_kmalloc(unsigned long call_site, | 98 | static void kmemtrace_kmalloc(void *ignore, |
| 99 | unsigned long call_site, | ||
| 99 | const void *ptr, | 100 | const void *ptr, |
| 100 | size_t bytes_req, | 101 | size_t bytes_req, |
| 101 | size_t bytes_alloc, | 102 | size_t bytes_alloc, |
| @@ -105,7 +106,8 @@ static void kmemtrace_kmalloc(unsigned long call_site, | |||
| 105 | bytes_req, bytes_alloc, gfp_flags, -1); | 106 | bytes_req, bytes_alloc, gfp_flags, -1); |
| 106 | } | 107 | } |
| 107 | 108 | ||
| 108 | static void kmemtrace_kmem_cache_alloc(unsigned long call_site, | 109 | static void kmemtrace_kmem_cache_alloc(void *ignore, |
| 110 | unsigned long call_site, | ||
| 109 | const void *ptr, | 111 | const void *ptr, |
| 110 | size_t bytes_req, | 112 | size_t bytes_req, |
| 111 | size_t bytes_alloc, | 113 | size_t bytes_alloc, |
| @@ -115,7 +117,8 @@ static void kmemtrace_kmem_cache_alloc(unsigned long call_site, | |||
| 115 | bytes_req, bytes_alloc, gfp_flags, -1); | 117 | bytes_req, bytes_alloc, gfp_flags, -1); |
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | static void kmemtrace_kmalloc_node(unsigned long call_site, | 120 | static void kmemtrace_kmalloc_node(void *ignore, |
| 121 | unsigned long call_site, | ||
| 119 | const void *ptr, | 122 | const void *ptr, |
| 120 | size_t bytes_req, | 123 | size_t bytes_req, |
| 121 | size_t bytes_alloc, | 124 | size_t bytes_alloc, |
| @@ -126,7 +129,8 @@ static void kmemtrace_kmalloc_node(unsigned long call_site, | |||
| 126 | bytes_req, bytes_alloc, gfp_flags, node); | 129 | bytes_req, bytes_alloc, gfp_flags, node); |
| 127 | } | 130 | } |
| 128 | 131 | ||
| 129 | static void kmemtrace_kmem_cache_alloc_node(unsigned long call_site, | 132 | static void kmemtrace_kmem_cache_alloc_node(void *ignore, |
| 133 | unsigned long call_site, | ||
| 130 | const void *ptr, | 134 | const void *ptr, |
| 131 | size_t bytes_req, | 135 | size_t bytes_req, |
| 132 | size_t bytes_alloc, | 136 | size_t bytes_alloc, |
| @@ -137,12 +141,14 @@ static void kmemtrace_kmem_cache_alloc_node(unsigned long call_site, | |||
| 137 | bytes_req, bytes_alloc, gfp_flags, node); | 141 | bytes_req, bytes_alloc, gfp_flags, node); |
| 138 | } | 142 | } |
| 139 | 143 | ||
| 140 | static void kmemtrace_kfree(unsigned long call_site, const void *ptr) | 144 | static void |
| 145 | kmemtrace_kfree(void *ignore, unsigned long call_site, const void *ptr) | ||
| 141 | { | 146 | { |
| 142 | kmemtrace_free(KMEMTRACE_TYPE_KMALLOC, call_site, ptr); | 147 | kmemtrace_free(KMEMTRACE_TYPE_KMALLOC, call_site, ptr); |
| 143 | } | 148 | } |
| 144 | 149 | ||
| 145 | static void kmemtrace_kmem_cache_free(unsigned long call_site, const void *ptr) | 150 | static void kmemtrace_kmem_cache_free(void *ignore, |
| 151 | unsigned long call_site, const void *ptr) | ||
| 146 | { | 152 | { |
| 147 | kmemtrace_free(KMEMTRACE_TYPE_CACHE, call_site, ptr); | 153 | kmemtrace_free(KMEMTRACE_TYPE_CACHE, call_site, ptr); |
| 148 | } | 154 | } |
| @@ -151,34 +157,34 @@ static int kmemtrace_start_probes(void) | |||
| 151 | { | 157 | { |
| 152 | int err; | 158 | int err; |
| 153 | 159 | ||
| 154 | err = register_trace_kmalloc(kmemtrace_kmalloc); | 160 | err = register_trace_kmalloc(kmemtrace_kmalloc, NULL); |
| 155 | if (err) | 161 | if (err) |
| 156 | return err; | 162 | return err; |
| 157 | err = register_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc); | 163 | err = register_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc, NULL); |
| 158 | if (err) | 164 | if (err) |
| 159 | return err; | 165 | return err; |
| 160 | err = register_trace_kmalloc_node(kmemtrace_kmalloc_node); | 166 | err = register_trace_kmalloc_node(kmemtrace_kmalloc_node, NULL); |
| 161 | if (err) | 167 | if (err) |
| 162 | return err; | 168 | return err; |
| 163 | err = register_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node); | 169 | err = register_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node, NULL); |
| 164 | if (err) | 170 | if (err) |
| 165 | return err; | 171 | return err; |
| 166 | err = register_trace_kfree(kmemtrace_kfree); | 172 | err = register_trace_kfree(kmemtrace_kfree, NULL); |
| 167 | if (err) | 173 | if (err) |
| 168 | return err; | 174 | return err; |
| 169 | err = register_trace_kmem_cache_free(kmemtrace_kmem_cache_free); | 175 | err = register_trace_kmem_cache_free(kmemtrace_kmem_cache_free, NULL); |
| 170 | 176 | ||
| 171 | return err; | 177 | return err; |
| 172 | } | 178 | } |
| 173 | 179 | ||
| 174 | static void kmemtrace_stop_probes(void) | 180 | static void kmemtrace_stop_probes(void) |
| 175 | { | 181 | { |
| 176 | unregister_trace_kmalloc(kmemtrace_kmalloc); | 182 | unregister_trace_kmalloc(kmemtrace_kmalloc, NULL); |
| 177 | unregister_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc); | 183 | unregister_trace_kmem_cache_alloc(kmemtrace_kmem_cache_alloc, NULL); |
| 178 | unregister_trace_kmalloc_node(kmemtrace_kmalloc_node); | 184 | unregister_trace_kmalloc_node(kmemtrace_kmalloc_node, NULL); |
| 179 | unregister_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node); | 185 | unregister_trace_kmem_cache_alloc_node(kmemtrace_kmem_cache_alloc_node, NULL); |
| 180 | unregister_trace_kfree(kmemtrace_kfree); | 186 | unregister_trace_kfree(kmemtrace_kfree, NULL); |
| 181 | unregister_trace_kmem_cache_free(kmemtrace_kmem_cache_free); | 187 | unregister_trace_kmem_cache_free(kmemtrace_kmem_cache_free, NULL); |
| 182 | } | 188 | } |
| 183 | 189 | ||
| 184 | static int kmem_trace_init(struct trace_array *tr) | 190 | static int kmem_trace_init(struct trace_array *tr) |
| @@ -237,7 +243,8 @@ struct kmemtrace_user_event_alloc { | |||
| 237 | }; | 243 | }; |
| 238 | 244 | ||
| 239 | static enum print_line_t | 245 | static enum print_line_t |
| 240 | kmemtrace_print_alloc(struct trace_iterator *iter, int flags) | 246 | kmemtrace_print_alloc(struct trace_iterator *iter, int flags, |
| 247 | struct trace_event *event) | ||
| 241 | { | 248 | { |
| 242 | struct trace_seq *s = &iter->seq; | 249 | struct trace_seq *s = &iter->seq; |
| 243 | struct kmemtrace_alloc_entry *entry; | 250 | struct kmemtrace_alloc_entry *entry; |
| @@ -257,7 +264,8 @@ kmemtrace_print_alloc(struct trace_iterator *iter, int flags) | |||
| 257 | } | 264 | } |
| 258 | 265 | ||
| 259 | static enum print_line_t | 266 | static enum print_line_t |
| 260 | kmemtrace_print_free(struct trace_iterator *iter, int flags) | 267 | kmemtrace_print_free(struct trace_iterator *iter, int flags, |
| 268 | struct trace_event *event) | ||
| 261 | { | 269 | { |
| 262 | struct trace_seq *s = &iter->seq; | 270 | struct trace_seq *s = &iter->seq; |
| 263 | struct kmemtrace_free_entry *entry; | 271 | struct kmemtrace_free_entry *entry; |
| @@ -275,7 +283,8 @@ kmemtrace_print_free(struct trace_iterator *iter, int flags) | |||
| 275 | } | 283 | } |
| 276 | 284 | ||
| 277 | static enum print_line_t | 285 | static enum print_line_t |
| 278 | kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags) | 286 | kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags, |
| 287 | struct trace_event *event) | ||
| 279 | { | 288 | { |
| 280 | struct trace_seq *s = &iter->seq; | 289 | struct trace_seq *s = &iter->seq; |
| 281 | struct kmemtrace_alloc_entry *entry; | 290 | struct kmemtrace_alloc_entry *entry; |
| @@ -309,7 +318,8 @@ kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags) | |||
| 309 | } | 318 | } |
| 310 | 319 | ||
| 311 | static enum print_line_t | 320 | static enum print_line_t |
| 312 | kmemtrace_print_free_user(struct trace_iterator *iter, int flags) | 321 | kmemtrace_print_free_user(struct trace_iterator *iter, int flags, |
| 322 | struct trace_event *event) | ||
| 313 | { | 323 | { |
| 314 | struct trace_seq *s = &iter->seq; | 324 | struct trace_seq *s = &iter->seq; |
| 315 | struct kmemtrace_free_entry *entry; | 325 | struct kmemtrace_free_entry *entry; |
| @@ -463,18 +473,26 @@ static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter) | |||
| 463 | } | 473 | } |
| 464 | } | 474 | } |
| 465 | 475 | ||
| 466 | static struct trace_event kmem_trace_alloc = { | 476 | static struct trace_event_functions kmem_trace_alloc_funcs = { |
| 467 | .type = TRACE_KMEM_ALLOC, | ||
| 468 | .trace = kmemtrace_print_alloc, | 477 | .trace = kmemtrace_print_alloc, |
| 469 | .binary = kmemtrace_print_alloc_user, | 478 | .binary = kmemtrace_print_alloc_user, |
| 470 | }; | 479 | }; |
| 471 | 480 | ||
| 472 | static struct trace_event kmem_trace_free = { | 481 | static struct trace_event kmem_trace_alloc = { |
| 473 | .type = TRACE_KMEM_FREE, | 482 | .type = TRACE_KMEM_ALLOC, |
| 483 | .funcs = &kmem_trace_alloc_funcs, | ||
| 484 | }; | ||
| 485 | |||
| 486 | static struct trace_event_functions kmem_trace_free_funcs = { | ||
| 474 | .trace = kmemtrace_print_free, | 487 | .trace = kmemtrace_print_free, |
| 475 | .binary = kmemtrace_print_free_user, | 488 | .binary = kmemtrace_print_free_user, |
| 476 | }; | 489 | }; |
| 477 | 490 | ||
| 491 | static struct trace_event kmem_trace_free = { | ||
| 492 | .type = TRACE_KMEM_FREE, | ||
| 493 | .funcs = &kmem_trace_free_funcs, | ||
| 494 | }; | ||
| 495 | |||
| 478 | static struct tracer kmem_tracer __read_mostly = { | 496 | static struct tracer kmem_tracer __read_mostly = { |
| 479 | .name = "kmemtrace", | 497 | .name = "kmemtrace", |
| 480 | .init = kmem_trace_init, | 498 | .init = kmem_trace_init, |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 756d7283318b..ba0ec81158b2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -1936,7 +1936,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) | |||
| 1936 | } | 1936 | } |
| 1937 | 1937 | ||
| 1938 | if (event) | 1938 | if (event) |
| 1939 | return event->trace(iter, sym_flags); | 1939 | return event->funcs->trace(iter, sym_flags, event); |
| 1940 | 1940 | ||
| 1941 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) | 1941 | if (!trace_seq_printf(s, "Unknown type %d\n", entry->type)) |
| 1942 | goto partial; | 1942 | goto partial; |
| @@ -1962,7 +1962,7 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter) | |||
| 1962 | 1962 | ||
| 1963 | event = ftrace_find_event(entry->type); | 1963 | event = ftrace_find_event(entry->type); |
| 1964 | if (event) | 1964 | if (event) |
| 1965 | return event->raw(iter, 0); | 1965 | return event->funcs->raw(iter, 0, event); |
| 1966 | 1966 | ||
| 1967 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) | 1967 | if (!trace_seq_printf(s, "%d ?\n", entry->type)) |
| 1968 | goto partial; | 1968 | goto partial; |
| @@ -1989,7 +1989,7 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter) | |||
| 1989 | 1989 | ||
| 1990 | event = ftrace_find_event(entry->type); | 1990 | event = ftrace_find_event(entry->type); |
| 1991 | if (event) { | 1991 | if (event) { |
| 1992 | enum print_line_t ret = event->hex(iter, 0); | 1992 | enum print_line_t ret = event->funcs->hex(iter, 0, event); |
| 1993 | if (ret != TRACE_TYPE_HANDLED) | 1993 | if (ret != TRACE_TYPE_HANDLED) |
| 1994 | return ret; | 1994 | return ret; |
| 1995 | } | 1995 | } |
| @@ -2014,7 +2014,8 @@ static enum print_line_t print_bin_fmt(struct trace_iterator *iter) | |||
| 2014 | } | 2014 | } |
| 2015 | 2015 | ||
| 2016 | event = ftrace_find_event(entry->type); | 2016 | event = ftrace_find_event(entry->type); |
| 2017 | return event ? event->binary(iter, 0) : TRACE_TYPE_HANDLED; | 2017 | return event ? event->funcs->binary(iter, 0, event) : |
| 2018 | TRACE_TYPE_HANDLED; | ||
| 2018 | } | 2019 | } |
| 2019 | 2020 | ||
| 2020 | int trace_empty(struct trace_iterator *iter) | 2021 | int trace_empty(struct trace_iterator *iter) |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index d1ce0bec1b3f..2cd96399463f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -405,12 +405,12 @@ void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, | |||
| 405 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, | 405 | void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, |
| 406 | int pc); | 406 | int pc); |
| 407 | #else | 407 | #else |
| 408 | static inline void ftrace_trace_stack(struct trace_array *tr, | 408 | static inline void ftrace_trace_stack(struct ring_buffer *buffer, |
| 409 | unsigned long flags, int skip, int pc) | 409 | unsigned long flags, int skip, int pc) |
| 410 | { | 410 | { |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | static inline void ftrace_trace_userstack(struct trace_array *tr, | 413 | static inline void ftrace_trace_userstack(struct ring_buffer *buffer, |
| 414 | unsigned long flags, int pc) | 414 | unsigned long flags, int pc) |
| 415 | { | 415 | { |
| 416 | } | 416 | } |
| @@ -778,12 +778,15 @@ extern void print_subsystem_event_filter(struct event_subsystem *system, | |||
| 778 | struct trace_seq *s); | 778 | struct trace_seq *s); |
| 779 | extern int filter_assign_type(const char *type); | 779 | extern int filter_assign_type(const char *type); |
| 780 | 780 | ||
| 781 | struct list_head * | ||
| 782 | trace_get_fields(struct ftrace_event_call *event_call); | ||
| 783 | |||
| 781 | static inline int | 784 | static inline int |
| 782 | filter_check_discard(struct ftrace_event_call *call, void *rec, | 785 | filter_check_discard(struct ftrace_event_call *call, void *rec, |
| 783 | struct ring_buffer *buffer, | 786 | struct ring_buffer *buffer, |
| 784 | struct ring_buffer_event *event) | 787 | struct ring_buffer_event *event) |
| 785 | { | 788 | { |
| 786 | if (unlikely(call->filter_active) && | 789 | if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) && |
| 787 | !filter_match_preds(call->filter, rec)) { | 790 | !filter_match_preds(call->filter, rec)) { |
| 788 | ring_buffer_discard_commit(buffer, event); | 791 | ring_buffer_discard_commit(buffer, event); |
| 789 | return 1; | 792 | return 1; |
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c index b9bc4d470177..8d3538b4ea5f 100644 --- a/kernel/trace/trace_branch.c +++ b/kernel/trace/trace_branch.c | |||
| @@ -143,7 +143,7 @@ static void branch_trace_reset(struct trace_array *tr) | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | static enum print_line_t trace_branch_print(struct trace_iterator *iter, | 145 | static enum print_line_t trace_branch_print(struct trace_iterator *iter, |
| 146 | int flags) | 146 | int flags, struct trace_event *event) |
| 147 | { | 147 | { |
| 148 | struct trace_branch *field; | 148 | struct trace_branch *field; |
| 149 | 149 | ||
| @@ -167,9 +167,13 @@ static void branch_print_header(struct seq_file *s) | |||
| 167 | " |\n"); | 167 | " |\n"); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static struct trace_event_functions trace_branch_funcs = { | ||
| 171 | .trace = trace_branch_print, | ||
| 172 | }; | ||
| 173 | |||
| 170 | static struct trace_event trace_branch_event = { | 174 | static struct trace_event trace_branch_event = { |
| 171 | .type = TRACE_BRANCH, | 175 | .type = TRACE_BRANCH, |
| 172 | .trace = trace_branch_print, | 176 | .funcs = &trace_branch_funcs, |
| 173 | }; | 177 | }; |
| 174 | 178 | ||
| 175 | static struct tracer branch_trace __read_mostly = | 179 | static struct tracer branch_trace __read_mostly = |
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 39d5ea7b0653..26b8607a0abc 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
| @@ -56,7 +56,13 @@ static int perf_trace_event_init(struct ftrace_event_call *tp_event, | |||
| 56 | } | 56 | } |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | ret = tp_event->perf_event_enable(tp_event); | 59 | if (tp_event->class->reg) |
| 60 | ret = tp_event->class->reg(tp_event, TRACE_REG_PERF_REGISTER); | ||
| 61 | else | ||
| 62 | ret = tracepoint_probe_register(tp_event->name, | ||
| 63 | tp_event->class->perf_probe, | ||
| 64 | tp_event); | ||
| 65 | |||
| 60 | if (ret) | 66 | if (ret) |
| 61 | goto fail; | 67 | goto fail; |
| 62 | 68 | ||
| @@ -89,7 +95,8 @@ int perf_trace_init(struct perf_event *p_event) | |||
| 89 | 95 | ||
| 90 | mutex_lock(&event_mutex); | 96 | mutex_lock(&event_mutex); |
| 91 | list_for_each_entry(tp_event, &ftrace_events, list) { | 97 | list_for_each_entry(tp_event, &ftrace_events, list) { |
| 92 | if (tp_event->id == event_id && tp_event->perf_event_enable && | 98 | if (tp_event->event.type == event_id && |
| 99 | tp_event->class && tp_event->class->perf_probe && | ||
| 93 | try_module_get(tp_event->mod)) { | 100 | try_module_get(tp_event->mod)) { |
| 94 | ret = perf_trace_event_init(tp_event, p_event); | 101 | ret = perf_trace_event_init(tp_event, p_event); |
| 95 | break; | 102 | break; |
| @@ -128,7 +135,12 @@ void perf_trace_destroy(struct perf_event *p_event) | |||
| 128 | if (--tp_event->perf_refcount > 0) | 135 | if (--tp_event->perf_refcount > 0) |
| 129 | return; | 136 | return; |
| 130 | 137 | ||
| 131 | tp_event->perf_event_disable(tp_event); | 138 | if (tp_event->class->reg) |
| 139 | tp_event->class->reg(tp_event, TRACE_REG_PERF_UNREGISTER); | ||
| 140 | else | ||
| 141 | tracepoint_probe_unregister(tp_event->name, | ||
| 142 | tp_event->class->perf_probe, | ||
| 143 | tp_event); | ||
| 132 | 144 | ||
| 133 | free_percpu(tp_event->perf_events); | 145 | free_percpu(tp_event->perf_events); |
| 134 | tp_event->perf_events = NULL; | 146 | tp_event->perf_events = NULL; |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index c697c7043349..53cffc0b0801 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
| @@ -29,11 +29,23 @@ DEFINE_MUTEX(event_mutex); | |||
| 29 | 29 | ||
| 30 | LIST_HEAD(ftrace_events); | 30 | LIST_HEAD(ftrace_events); |
| 31 | 31 | ||
| 32 | struct list_head * | ||
| 33 | trace_get_fields(struct ftrace_event_call *event_call) | ||
| 34 | { | ||
| 35 | if (!event_call->class->get_fields) | ||
| 36 | return &event_call->class->fields; | ||
| 37 | return event_call->class->get_fields(event_call); | ||
| 38 | } | ||
| 39 | |||
| 32 | int trace_define_field(struct ftrace_event_call *call, const char *type, | 40 | int trace_define_field(struct ftrace_event_call *call, const char *type, |
| 33 | const char *name, int offset, int size, int is_signed, | 41 | const char *name, int offset, int size, int is_signed, |
| 34 | int filter_type) | 42 | int filter_type) |
| 35 | { | 43 | { |
| 36 | struct ftrace_event_field *field; | 44 | struct ftrace_event_field *field; |
| 45 | struct list_head *head; | ||
| 46 | |||
| 47 | if (WARN_ON(!call->class)) | ||
| 48 | return 0; | ||
| 37 | 49 | ||
| 38 | field = kzalloc(sizeof(*field), GFP_KERNEL); | 50 | field = kzalloc(sizeof(*field), GFP_KERNEL); |
| 39 | if (!field) | 51 | if (!field) |
| @@ -56,7 +68,8 @@ int trace_define_field(struct ftrace_event_call *call, const char *type, | |||
| 56 | field->size = size; | 68 | field->size = size; |
| 57 | field->is_signed = is_signed; | 69 | field->is_signed = is_signed; |
| 58 | 70 | ||
| 59 | list_add(&field->link, &call->fields); | 71 | head = trace_get_fields(call); |
| 72 | list_add(&field->link, head); | ||
| 60 | 73 | ||
| 61 | return 0; | 74 | return 0; |
| 62 | 75 | ||
| @@ -94,8 +107,10 @@ static int trace_define_common_fields(struct ftrace_event_call *call) | |||
| 94 | void trace_destroy_fields(struct ftrace_event_call *call) | 107 | void trace_destroy_fields(struct ftrace_event_call *call) |
| 95 | { | 108 | { |
| 96 | struct ftrace_event_field *field, *next; | 109 | struct ftrace_event_field *field, *next; |
| 110 | struct list_head *head; | ||
| 97 | 111 | ||
| 98 | list_for_each_entry_safe(field, next, &call->fields, link) { | 112 | head = trace_get_fields(call); |
| 113 | list_for_each_entry_safe(field, next, head, link) { | ||
| 99 | list_del(&field->link); | 114 | list_del(&field->link); |
| 100 | kfree(field->type); | 115 | kfree(field->type); |
| 101 | kfree(field->name); | 116 | kfree(field->name); |
| @@ -107,11 +122,9 @@ int trace_event_raw_init(struct ftrace_event_call *call) | |||
| 107 | { | 122 | { |
| 108 | int id; | 123 | int id; |
| 109 | 124 | ||
| 110 | id = register_ftrace_event(call->event); | 125 | id = register_ftrace_event(&call->event); |
| 111 | if (!id) | 126 | if (!id) |
| 112 | return -ENODEV; | 127 | return -ENODEV; |
| 113 | call->id = id; | ||
| 114 | INIT_LIST_HEAD(&call->fields); | ||
| 115 | 128 | ||
| 116 | return 0; | 129 | return 0; |
| 117 | } | 130 | } |
| @@ -124,23 +137,33 @@ static int ftrace_event_enable_disable(struct ftrace_event_call *call, | |||
| 124 | 137 | ||
| 125 | switch (enable) { | 138 | switch (enable) { |
| 126 | case 0: | 139 | case 0: |
| 127 | if (call->enabled) { | 140 | if (call->flags & TRACE_EVENT_FL_ENABLED) { |
| 128 | call->enabled = 0; | 141 | call->flags &= ~TRACE_EVENT_FL_ENABLED; |
| 129 | tracing_stop_cmdline_record(); | 142 | tracing_stop_cmdline_record(); |
| 130 | call->unregfunc(call); | 143 | if (call->class->reg) |
| 144 | call->class->reg(call, TRACE_REG_UNREGISTER); | ||
| 145 | else | ||
| 146 | tracepoint_probe_unregister(call->name, | ||
| 147 | call->class->probe, | ||
| 148 | call); | ||
| 131 | } | 149 | } |
| 132 | break; | 150 | break; |
| 133 | case 1: | 151 | case 1: |
| 134 | if (!call->enabled) { | 152 | if (!(call->flags & TRACE_EVENT_FL_ENABLED)) { |
| 135 | tracing_start_cmdline_record(); | 153 | tracing_start_cmdline_record(); |
| 136 | ret = call->regfunc(call); | 154 | if (call->class->reg) |
| 155 | ret = call->class->reg(call, TRACE_REG_REGISTER); | ||
| 156 | else | ||
| 157 | ret = tracepoint_probe_register(call->name, | ||
| 158 | call->class->probe, | ||
| 159 | call); | ||
| 137 | if (ret) { | 160 | if (ret) { |
| 138 | tracing_stop_cmdline_record(); | 161 | tracing_stop_cmdline_record(); |
| 139 | pr_info("event trace: Could not enable event " | 162 | pr_info("event trace: Could not enable event " |
| 140 | "%s\n", call->name); | 163 | "%s\n", call->name); |
| 141 | break; | 164 | break; |
| 142 | } | 165 | } |
| 143 | call->enabled = 1; | 166 | call->flags |= TRACE_EVENT_FL_ENABLED; |
| 144 | } | 167 | } |
| 145 | break; | 168 | break; |
| 146 | } | 169 | } |
| @@ -171,15 +194,16 @@ static int __ftrace_set_clr_event(const char *match, const char *sub, | |||
| 171 | mutex_lock(&event_mutex); | 194 | mutex_lock(&event_mutex); |
| 172 | list_for_each_entry(call, &ftrace_events, list) { | 195 | list_for_each_entry(call, &ftrace_events, list) { |
| 173 | 196 | ||
| 174 | if (!call->name || !call->regfunc) | 197 | if (!call->name || !call->class || |
| 198 | (!call->class->probe && !call->class->reg)) | ||
| 175 | continue; | 199 | continue; |
| 176 | 200 | ||
| 177 | if (match && | 201 | if (match && |
| 178 | strcmp(match, call->name) != 0 && | 202 | strcmp(match, call->name) != 0 && |
| 179 | strcmp(match, call->system) != 0) | 203 | strcmp(match, call->class->system) != 0) |
| 180 | continue; | 204 | continue; |
| 181 | 205 | ||
| 182 | if (sub && strcmp(sub, call->system) != 0) | 206 | if (sub && strcmp(sub, call->class->system) != 0) |
| 183 | continue; | 207 | continue; |
| 184 | 208 | ||
| 185 | if (event && strcmp(event, call->name) != 0) | 209 | if (event && strcmp(event, call->name) != 0) |
| @@ -297,7 +321,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 297 | * The ftrace subsystem is for showing formats only. | 321 | * The ftrace subsystem is for showing formats only. |
| 298 | * They can not be enabled or disabled via the event files. | 322 | * They can not be enabled or disabled via the event files. |
| 299 | */ | 323 | */ |
| 300 | if (call->regfunc) | 324 | if (call->class && (call->class->probe || call->class->reg)) |
| 301 | return call; | 325 | return call; |
| 302 | } | 326 | } |
| 303 | 327 | ||
| @@ -328,7 +352,7 @@ s_next(struct seq_file *m, void *v, loff_t *pos) | |||
| 328 | (*pos)++; | 352 | (*pos)++; |
| 329 | 353 | ||
| 330 | list_for_each_entry_continue(call, &ftrace_events, list) { | 354 | list_for_each_entry_continue(call, &ftrace_events, list) { |
| 331 | if (call->enabled) | 355 | if (call->flags & TRACE_EVENT_FL_ENABLED) |
| 332 | return call; | 356 | return call; |
| 333 | } | 357 | } |
| 334 | 358 | ||
| @@ -355,8 +379,8 @@ static int t_show(struct seq_file *m, void *v) | |||
| 355 | { | 379 | { |
| 356 | struct ftrace_event_call *call = v; | 380 | struct ftrace_event_call *call = v; |
| 357 | 381 | ||
| 358 | if (strcmp(call->system, TRACE_SYSTEM) != 0) | 382 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) |
| 359 | seq_printf(m, "%s:", call->system); | 383 | seq_printf(m, "%s:", call->class->system); |
| 360 | seq_printf(m, "%s\n", call->name); | 384 | seq_printf(m, "%s\n", call->name); |
| 361 | 385 | ||
| 362 | return 0; | 386 | return 0; |
| @@ -387,7 +411,7 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 387 | struct ftrace_event_call *call = filp->private_data; | 411 | struct ftrace_event_call *call = filp->private_data; |
| 388 | char *buf; | 412 | char *buf; |
| 389 | 413 | ||
| 390 | if (call->enabled) | 414 | if (call->flags & TRACE_EVENT_FL_ENABLED) |
| 391 | buf = "1\n"; | 415 | buf = "1\n"; |
| 392 | else | 416 | else |
| 393 | buf = "0\n"; | 417 | buf = "0\n"; |
| @@ -450,10 +474,11 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 450 | 474 | ||
| 451 | mutex_lock(&event_mutex); | 475 | mutex_lock(&event_mutex); |
| 452 | list_for_each_entry(call, &ftrace_events, list) { | 476 | list_for_each_entry(call, &ftrace_events, list) { |
| 453 | if (!call->name || !call->regfunc) | 477 | if (!call->name || !call->class || |
| 478 | (!call->class->probe && !call->class->reg)) | ||
| 454 | continue; | 479 | continue; |
| 455 | 480 | ||
| 456 | if (system && strcmp(call->system, system) != 0) | 481 | if (system && strcmp(call->class->system, system) != 0) |
| 457 | continue; | 482 | continue; |
| 458 | 483 | ||
| 459 | /* | 484 | /* |
| @@ -461,7 +486,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 461 | * or if all events or cleared, or if we have | 486 | * or if all events or cleared, or if we have |
| 462 | * a mixture. | 487 | * a mixture. |
| 463 | */ | 488 | */ |
| 464 | set |= (1 << !!call->enabled); | 489 | set |= (1 << !!(call->flags & TRACE_EVENT_FL_ENABLED)); |
| 465 | 490 | ||
| 466 | /* | 491 | /* |
| 467 | * If we have a mixture, no need to look further. | 492 | * If we have a mixture, no need to look further. |
| @@ -525,6 +550,7 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 525 | { | 550 | { |
| 526 | struct ftrace_event_call *call = filp->private_data; | 551 | struct ftrace_event_call *call = filp->private_data; |
| 527 | struct ftrace_event_field *field; | 552 | struct ftrace_event_field *field; |
| 553 | struct list_head *head; | ||
| 528 | struct trace_seq *s; | 554 | struct trace_seq *s; |
| 529 | int common_field_count = 5; | 555 | int common_field_count = 5; |
| 530 | char *buf; | 556 | char *buf; |
| @@ -540,10 +566,11 @@ event_format_read(struct file *filp, char __user *ubuf, size_t cnt, | |||
| 540 | trace_seq_init(s); | 566 | trace_seq_init(s); |
| 541 | 567 | ||
| 542 | trace_seq_printf(s, "name: %s\n", call->name); | 568 | trace_seq_printf(s, "name: %s\n", call->name); |
| 543 | trace_seq_printf(s, "ID: %d\n", call->id); | 569 | trace_seq_printf(s, "ID: %d\n", call->event.type); |
| 544 | trace_seq_printf(s, "format:\n"); | 570 | trace_seq_printf(s, "format:\n"); |
| 545 | 571 | ||
| 546 | list_for_each_entry_reverse(field, &call->fields, link) { | 572 | head = trace_get_fields(call); |
| 573 | list_for_each_entry_reverse(field, head, link) { | ||
| 547 | /* | 574 | /* |
| 548 | * Smartly shows the array type(except dynamic array). | 575 | * Smartly shows the array type(except dynamic array). |
| 549 | * Normal: | 576 | * Normal: |
| @@ -613,7 +640,7 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) | |||
| 613 | return -ENOMEM; | 640 | return -ENOMEM; |
| 614 | 641 | ||
| 615 | trace_seq_init(s); | 642 | trace_seq_init(s); |
| 616 | trace_seq_printf(s, "%d\n", call->id); | 643 | trace_seq_printf(s, "%d\n", call->event.type); |
| 617 | 644 | ||
| 618 | r = simple_read_from_buffer(ubuf, cnt, ppos, | 645 | r = simple_read_from_buffer(ubuf, cnt, ppos, |
| 619 | s->buffer, s->len); | 646 | s->buffer, s->len); |
| @@ -919,14 +946,15 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
| 919 | const struct file_operations *filter, | 946 | const struct file_operations *filter, |
| 920 | const struct file_operations *format) | 947 | const struct file_operations *format) |
| 921 | { | 948 | { |
| 949 | struct list_head *head; | ||
| 922 | int ret; | 950 | int ret; |
| 923 | 951 | ||
| 924 | /* | 952 | /* |
| 925 | * If the trace point header did not define TRACE_SYSTEM | 953 | * If the trace point header did not define TRACE_SYSTEM |
| 926 | * then the system would be called "TRACE_SYSTEM". | 954 | * then the system would be called "TRACE_SYSTEM". |
| 927 | */ | 955 | */ |
| 928 | if (strcmp(call->system, TRACE_SYSTEM) != 0) | 956 | if (strcmp(call->class->system, TRACE_SYSTEM) != 0) |
| 929 | d_events = event_subsystem_dir(call->system, d_events); | 957 | d_events = event_subsystem_dir(call->class->system, d_events); |
| 930 | 958 | ||
| 931 | call->dir = debugfs_create_dir(call->name, d_events); | 959 | call->dir = debugfs_create_dir(call->name, d_events); |
| 932 | if (!call->dir) { | 960 | if (!call->dir) { |
| @@ -935,22 +963,31 @@ event_create_dir(struct ftrace_event_call *call, struct dentry *d_events, | |||
| 935 | return -1; | 963 | return -1; |
| 936 | } | 964 | } |
| 937 | 965 | ||
| 938 | if (call->regfunc) | 966 | if (call->class->probe || call->class->reg) |
| 939 | trace_create_file("enable", 0644, call->dir, call, | 967 | trace_create_file("enable", 0644, call->dir, call, |
| 940 | enable); | 968 | enable); |
| 941 | 969 | ||
| 942 | if (call->id && call->perf_event_enable) | 970 | #ifdef CONFIG_PERF_EVENTS |
| 971 | if (call->event.type && (call->class->perf_probe || call->class->reg)) | ||
| 943 | trace_create_file("id", 0444, call->dir, call, | 972 | trace_create_file("id", 0444, call->dir, call, |
| 944 | id); | 973 | id); |
| 974 | #endif | ||
| 945 | 975 | ||
| 946 | if (call->define_fields) { | 976 | if (call->class->define_fields) { |
| 947 | ret = trace_define_common_fields(call); | 977 | /* |
| 948 | if (!ret) | 978 | * Other events may have the same class. Only update |
| 949 | ret = call->define_fields(call); | 979 | * the fields if they are not already defined. |
| 950 | if (ret < 0) { | 980 | */ |
| 951 | pr_warning("Could not initialize trace point" | 981 | head = trace_get_fields(call); |
| 952 | " events/%s\n", call->name); | 982 | if (list_empty(head)) { |
| 953 | return ret; | 983 | ret = trace_define_common_fields(call); |
| 984 | if (!ret) | ||
| 985 | ret = call->class->define_fields(call); | ||
| 986 | if (ret < 0) { | ||
| 987 | pr_warning("Could not initialize trace point" | ||
| 988 | " events/%s\n", call->name); | ||
| 989 | return ret; | ||
| 990 | } | ||
| 954 | } | 991 | } |
| 955 | trace_create_file("filter", 0644, call->dir, call, | 992 | trace_create_file("filter", 0644, call->dir, call, |
| 956 | filter); | 993 | filter); |
| @@ -970,8 +1007,8 @@ static int __trace_add_event_call(struct ftrace_event_call *call) | |||
| 970 | if (!call->name) | 1007 | if (!call->name) |
| 971 | return -EINVAL; | 1008 | return -EINVAL; |
| 972 | 1009 | ||
| 973 | if (call->raw_init) { | 1010 | if (call->class->raw_init) { |
| 974 | ret = call->raw_init(call); | 1011 | ret = call->class->raw_init(call); |
| 975 | if (ret < 0) { | 1012 | if (ret < 0) { |
| 976 | if (ret != -ENOSYS) | 1013 | if (ret != -ENOSYS) |
| 977 | pr_warning("Could not initialize trace " | 1014 | pr_warning("Could not initialize trace " |
| @@ -1035,13 +1072,13 @@ static void remove_subsystem_dir(const char *name) | |||
| 1035 | static void __trace_remove_event_call(struct ftrace_event_call *call) | 1072 | static void __trace_remove_event_call(struct ftrace_event_call *call) |
| 1036 | { | 1073 | { |
| 1037 | ftrace_event_enable_disable(call, 0); | 1074 | ftrace_event_enable_disable(call, 0); |
| 1038 | if (call->event) | 1075 | if (call->event.funcs) |
| 1039 | __unregister_ftrace_event(call->event); | 1076 | __unregister_ftrace_event(&call->event); |
| 1040 | debugfs_remove_recursive(call->dir); | 1077 | debugfs_remove_recursive(call->dir); |
| 1041 | list_del(&call->list); | 1078 | list_del(&call->list); |
| 1042 | trace_destroy_fields(call); | 1079 | trace_destroy_fields(call); |
| 1043 | destroy_preds(call); | 1080 | destroy_preds(call); |
| 1044 | remove_subsystem_dir(call->system); | 1081 | remove_subsystem_dir(call->class->system); |
| 1045 | } | 1082 | } |
| 1046 | 1083 | ||
| 1047 | /* Remove an event_call */ | 1084 | /* Remove an event_call */ |
| @@ -1132,8 +1169,8 @@ static void trace_module_add_events(struct module *mod) | |||
| 1132 | /* The linker may leave blanks */ | 1169 | /* The linker may leave blanks */ |
| 1133 | if (!call->name) | 1170 | if (!call->name) |
| 1134 | continue; | 1171 | continue; |
| 1135 | if (call->raw_init) { | 1172 | if (call->class->raw_init) { |
| 1136 | ret = call->raw_init(call); | 1173 | ret = call->class->raw_init(call); |
| 1137 | if (ret < 0) { | 1174 | if (ret < 0) { |
| 1138 | if (ret != -ENOSYS) | 1175 | if (ret != -ENOSYS) |
| 1139 | pr_warning("Could not initialize trace " | 1176 | pr_warning("Could not initialize trace " |
| @@ -1286,8 +1323,8 @@ static __init int event_trace_init(void) | |||
| 1286 | /* The linker may leave blanks */ | 1323 | /* The linker may leave blanks */ |
| 1287 | if (!call->name) | 1324 | if (!call->name) |
| 1288 | continue; | 1325 | continue; |
| 1289 | if (call->raw_init) { | 1326 | if (call->class->raw_init) { |
| 1290 | ret = call->raw_init(call); | 1327 | ret = call->class->raw_init(call); |
| 1291 | if (ret < 0) { | 1328 | if (ret < 0) { |
| 1292 | if (ret != -ENOSYS) | 1329 | if (ret != -ENOSYS) |
| 1293 | pr_warning("Could not initialize trace " | 1330 | pr_warning("Could not initialize trace " |
| @@ -1388,8 +1425,8 @@ static __init void event_trace_self_tests(void) | |||
| 1388 | 1425 | ||
| 1389 | list_for_each_entry(call, &ftrace_events, list) { | 1426 | list_for_each_entry(call, &ftrace_events, list) { |
| 1390 | 1427 | ||
| 1391 | /* Only test those that have a regfunc */ | 1428 | /* Only test those that have a probe */ |
| 1392 | if (!call->regfunc) | 1429 | if (!call->class || !call->class->probe) |
| 1393 | continue; | 1430 | continue; |
| 1394 | 1431 | ||
| 1395 | /* | 1432 | /* |
| @@ -1399,8 +1436,8 @@ static __init void event_trace_self_tests(void) | |||
| 1399 | * syscalls as we test. | 1436 | * syscalls as we test. |
| 1400 | */ | 1437 | */ |
| 1401 | #ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS | 1438 | #ifndef CONFIG_EVENT_TRACE_TEST_SYSCALLS |
| 1402 | if (call->system && | 1439 | if (call->class->system && |
| 1403 | strcmp(call->system, "syscalls") == 0) | 1440 | strcmp(call->class->system, "syscalls") == 0) |
| 1404 | continue; | 1441 | continue; |
| 1405 | #endif | 1442 | #endif |
| 1406 | 1443 | ||
| @@ -1410,7 +1447,7 @@ static __init void event_trace_self_tests(void) | |||
| 1410 | * If an event is already enabled, someone is using | 1447 | * If an event is already enabled, someone is using |
| 1411 | * it and the self test should not be on. | 1448 | * it and the self test should not be on. |
| 1412 | */ | 1449 | */ |
| 1413 | if (call->enabled) { | 1450 | if (call->flags & TRACE_EVENT_FL_ENABLED) { |
| 1414 | pr_warning("Enabled event during self test!\n"); | 1451 | pr_warning("Enabled event during self test!\n"); |
| 1415 | WARN_ON_ONCE(1); | 1452 | WARN_ON_ONCE(1); |
| 1416 | continue; | 1453 | continue; |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 58092d844a1f..57bb1bb32999 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
| @@ -500,8 +500,10 @@ static struct ftrace_event_field * | |||
| 500 | find_event_field(struct ftrace_event_call *call, char *name) | 500 | find_event_field(struct ftrace_event_call *call, char *name) |
| 501 | { | 501 | { |
| 502 | struct ftrace_event_field *field; | 502 | struct ftrace_event_field *field; |
| 503 | struct list_head *head; | ||
| 503 | 504 | ||
| 504 | list_for_each_entry(field, &call->fields, link) { | 505 | head = trace_get_fields(call); |
| 506 | list_for_each_entry(field, head, link) { | ||
| 505 | if (!strcmp(field->name, name)) | 507 | if (!strcmp(field->name, name)) |
| 506 | return field; | 508 | return field; |
| 507 | } | 509 | } |
| @@ -545,7 +547,7 @@ static void filter_disable_preds(struct ftrace_event_call *call) | |||
| 545 | struct event_filter *filter = call->filter; | 547 | struct event_filter *filter = call->filter; |
| 546 | int i; | 548 | int i; |
| 547 | 549 | ||
| 548 | call->filter_active = 0; | 550 | call->flags &= ~TRACE_EVENT_FL_FILTERED; |
| 549 | filter->n_preds = 0; | 551 | filter->n_preds = 0; |
| 550 | 552 | ||
| 551 | for (i = 0; i < MAX_FILTER_PRED; i++) | 553 | for (i = 0; i < MAX_FILTER_PRED; i++) |
| @@ -572,7 +574,7 @@ void destroy_preds(struct ftrace_event_call *call) | |||
| 572 | { | 574 | { |
| 573 | __free_preds(call->filter); | 575 | __free_preds(call->filter); |
| 574 | call->filter = NULL; | 576 | call->filter = NULL; |
| 575 | call->filter_active = 0; | 577 | call->flags &= ~TRACE_EVENT_FL_FILTERED; |
| 576 | } | 578 | } |
| 577 | 579 | ||
| 578 | static struct event_filter *__alloc_preds(void) | 580 | static struct event_filter *__alloc_preds(void) |
| @@ -611,7 +613,7 @@ static int init_preds(struct ftrace_event_call *call) | |||
| 611 | if (call->filter) | 613 | if (call->filter) |
| 612 | return 0; | 614 | return 0; |
| 613 | 615 | ||
| 614 | call->filter_active = 0; | 616 | call->flags &= ~TRACE_EVENT_FL_FILTERED; |
| 615 | call->filter = __alloc_preds(); | 617 | call->filter = __alloc_preds(); |
| 616 | if (IS_ERR(call->filter)) | 618 | if (IS_ERR(call->filter)) |
| 617 | return PTR_ERR(call->filter); | 619 | return PTR_ERR(call->filter); |
| @@ -625,10 +627,10 @@ static int init_subsystem_preds(struct event_subsystem *system) | |||
| 625 | int err; | 627 | int err; |
| 626 | 628 | ||
| 627 | list_for_each_entry(call, &ftrace_events, list) { | 629 | list_for_each_entry(call, &ftrace_events, list) { |
| 628 | if (!call->define_fields) | 630 | if (!call->class || !call->class->define_fields) |
| 629 | continue; | 631 | continue; |
| 630 | 632 | ||
| 631 | if (strcmp(call->system, system->name) != 0) | 633 | if (strcmp(call->class->system, system->name) != 0) |
| 632 | continue; | 634 | continue; |
| 633 | 635 | ||
| 634 | err = init_preds(call); | 636 | err = init_preds(call); |
| @@ -644,10 +646,10 @@ static void filter_free_subsystem_preds(struct event_subsystem *system) | |||
| 644 | struct ftrace_event_call *call; | 646 | struct ftrace_event_call *call; |
| 645 | 647 | ||
| 646 | list_for_each_entry(call, &ftrace_events, list) { | 648 | list_for_each_entry(call, &ftrace_events, list) { |
| 647 | if (!call->define_fields) | 649 | if (!call->class || !call->class->define_fields) |
| 648 | continue; | 650 | continue; |
| 649 | 651 | ||
| 650 | if (strcmp(call->system, system->name) != 0) | 652 | if (strcmp(call->class->system, system->name) != 0) |
| 651 | continue; | 653 | continue; |
| 652 | 654 | ||
| 653 | filter_disable_preds(call); | 655 | filter_disable_preds(call); |
| @@ -1249,10 +1251,10 @@ static int replace_system_preds(struct event_subsystem *system, | |||
| 1249 | list_for_each_entry(call, &ftrace_events, list) { | 1251 | list_for_each_entry(call, &ftrace_events, list) { |
| 1250 | struct event_filter *filter = call->filter; | 1252 | struct event_filter *filter = call->filter; |
| 1251 | 1253 | ||
| 1252 | if (!call->define_fields) | 1254 | if (!call->class || !call->class->define_fields) |
| 1253 | continue; | 1255 | continue; |
| 1254 | 1256 | ||
| 1255 | if (strcmp(call->system, system->name) != 0) | 1257 | if (strcmp(call->class->system, system->name) != 0) |
| 1256 | continue; | 1258 | continue; |
| 1257 | 1259 | ||
| 1258 | /* try to see if the filter can be applied */ | 1260 | /* try to see if the filter can be applied */ |
| @@ -1266,7 +1268,7 @@ static int replace_system_preds(struct event_subsystem *system, | |||
| 1266 | if (err) | 1268 | if (err) |
| 1267 | filter_disable_preds(call); | 1269 | filter_disable_preds(call); |
| 1268 | else { | 1270 | else { |
| 1269 | call->filter_active = 1; | 1271 | call->flags |= TRACE_EVENT_FL_FILTERED; |
| 1270 | replace_filter_string(filter, filter_string); | 1272 | replace_filter_string(filter, filter_string); |
| 1271 | } | 1273 | } |
| 1272 | fail = false; | 1274 | fail = false; |
| @@ -1315,7 +1317,7 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | |||
| 1315 | if (err) | 1317 | if (err) |
| 1316 | append_filter_err(ps, call->filter); | 1318 | append_filter_err(ps, call->filter); |
| 1317 | else | 1319 | else |
| 1318 | call->filter_active = 1; | 1320 | call->flags |= TRACE_EVENT_FL_FILTERED; |
| 1319 | out: | 1321 | out: |
| 1320 | filter_opstack_clear(ps); | 1322 | filter_opstack_clear(ps); |
| 1321 | postfix_clear(ps); | 1323 | postfix_clear(ps); |
| @@ -1393,7 +1395,7 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id, | |||
| 1393 | mutex_lock(&event_mutex); | 1395 | mutex_lock(&event_mutex); |
| 1394 | 1396 | ||
| 1395 | list_for_each_entry(call, &ftrace_events, list) { | 1397 | list_for_each_entry(call, &ftrace_events, list) { |
| 1396 | if (call->id == event_id) | 1398 | if (call->event.type == event_id) |
| 1397 | break; | 1399 | break; |
| 1398 | } | 1400 | } |
| 1399 | 1401 | ||
diff --git a/kernel/trace/trace_export.c b/kernel/trace/trace_export.c index e091f64ba6ce..8536e2a65969 100644 --- a/kernel/trace/trace_export.c +++ b/kernel/trace/trace_export.c | |||
| @@ -127,7 +127,7 @@ ftrace_define_fields_##name(struct ftrace_event_call *event_call) \ | |||
| 127 | 127 | ||
| 128 | static int ftrace_raw_init_event(struct ftrace_event_call *call) | 128 | static int ftrace_raw_init_event(struct ftrace_event_call *call) |
| 129 | { | 129 | { |
| 130 | INIT_LIST_HEAD(&call->fields); | 130 | INIT_LIST_HEAD(&call->class->fields); |
| 131 | return 0; | 131 | return 0; |
| 132 | } | 132 | } |
| 133 | 133 | ||
| @@ -153,17 +153,21 @@ static int ftrace_raw_init_event(struct ftrace_event_call *call) | |||
| 153 | #define F_printk(fmt, args...) #fmt ", " __stringify(args) | 153 | #define F_printk(fmt, args...) #fmt ", " __stringify(args) |
| 154 | 154 | ||
| 155 | #undef FTRACE_ENTRY | 155 | #undef FTRACE_ENTRY |
| 156 | #define FTRACE_ENTRY(call, struct_name, type, tstruct, print) \ | 156 | #define FTRACE_ENTRY(call, struct_name, etype, tstruct, print) \ |
| 157 | \ | ||
| 158 | struct ftrace_event_class event_class_ftrace_##call = { \ | ||
| 159 | .system = __stringify(TRACE_SYSTEM), \ | ||
| 160 | .define_fields = ftrace_define_fields_##call, \ | ||
| 161 | .raw_init = ftrace_raw_init_event, \ | ||
| 162 | }; \ | ||
| 157 | \ | 163 | \ |
| 158 | struct ftrace_event_call __used \ | 164 | struct ftrace_event_call __used \ |
| 159 | __attribute__((__aligned__(4))) \ | 165 | __attribute__((__aligned__(4))) \ |
| 160 | __attribute__((section("_ftrace_events"))) event_##call = { \ | 166 | __attribute__((section("_ftrace_events"))) event_##call = { \ |
| 161 | .name = #call, \ | 167 | .name = #call, \ |
| 162 | .id = type, \ | 168 | .event.type = etype, \ |
| 163 | .system = __stringify(TRACE_SYSTEM), \ | 169 | .class = &event_class_ftrace_##call, \ |
| 164 | .raw_init = ftrace_raw_init_event, \ | ||
| 165 | .print_fmt = print, \ | 170 | .print_fmt = print, \ |
| 166 | .define_fields = ftrace_define_fields_##call, \ | ||
| 167 | }; \ | 171 | }; \ |
| 168 | 172 | ||
| 169 | #include "trace_entries.h" | 173 | #include "trace_entries.h" |
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index dd11c830eb84..79f4bac99a94 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c | |||
| @@ -1025,7 +1025,7 @@ print_graph_comment(struct trace_seq *s, struct trace_entry *ent, | |||
| 1025 | if (!event) | 1025 | if (!event) |
| 1026 | return TRACE_TYPE_UNHANDLED; | 1026 | return TRACE_TYPE_UNHANDLED; |
| 1027 | 1027 | ||
| 1028 | ret = event->trace(iter, sym_flags); | 1028 | ret = event->funcs->trace(iter, sym_flags, event); |
| 1029 | if (ret != TRACE_TYPE_HANDLED) | 1029 | if (ret != TRACE_TYPE_HANDLED) |
| 1030 | return ret; | 1030 | return ret; |
| 1031 | } | 1031 | } |
| @@ -1112,7 +1112,8 @@ print_graph_function(struct trace_iterator *iter) | |||
| 1112 | } | 1112 | } |
| 1113 | 1113 | ||
| 1114 | static enum print_line_t | 1114 | static enum print_line_t |
| 1115 | print_graph_function_event(struct trace_iterator *iter, int flags) | 1115 | print_graph_function_event(struct trace_iterator *iter, int flags, |
| 1116 | struct trace_event *event) | ||
| 1116 | { | 1117 | { |
| 1117 | return print_graph_function(iter); | 1118 | return print_graph_function(iter); |
| 1118 | } | 1119 | } |
| @@ -1225,14 +1226,18 @@ void graph_trace_close(struct trace_iterator *iter) | |||
| 1225 | } | 1226 | } |
| 1226 | } | 1227 | } |
| 1227 | 1228 | ||
| 1229 | static struct trace_event_functions graph_functions = { | ||
| 1230 | .trace = print_graph_function_event, | ||
| 1231 | }; | ||
| 1232 | |||
| 1228 | static struct trace_event graph_trace_entry_event = { | 1233 | static struct trace_event graph_trace_entry_event = { |
| 1229 | .type = TRACE_GRAPH_ENT, | 1234 | .type = TRACE_GRAPH_ENT, |
| 1230 | .trace = print_graph_function_event, | 1235 | .funcs = &graph_functions, |
| 1231 | }; | 1236 | }; |
| 1232 | 1237 | ||
| 1233 | static struct trace_event graph_trace_ret_event = { | 1238 | static struct trace_event graph_trace_ret_event = { |
| 1234 | .type = TRACE_GRAPH_RET, | 1239 | .type = TRACE_GRAPH_RET, |
| 1235 | .trace = print_graph_function_event, | 1240 | .funcs = &graph_functions |
| 1236 | }; | 1241 | }; |
| 1237 | 1242 | ||
| 1238 | static struct tracer graph_trace __read_mostly = { | 1243 | static struct tracer graph_trace __read_mostly = { |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 4681f60dac00..faf7cefd15da 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -324,8 +324,8 @@ struct trace_probe { | |||
| 324 | unsigned long nhit; | 324 | unsigned long nhit; |
| 325 | unsigned int flags; /* For TP_FLAG_* */ | 325 | unsigned int flags; /* For TP_FLAG_* */ |
| 326 | const char *symbol; /* symbol name */ | 326 | const char *symbol; /* symbol name */ |
| 327 | struct ftrace_event_class class; | ||
| 327 | struct ftrace_event_call call; | 328 | struct ftrace_event_call call; |
| 328 | struct trace_event event; | ||
| 329 | ssize_t size; /* trace entry size */ | 329 | ssize_t size; /* trace entry size */ |
| 330 | unsigned int nr_args; | 330 | unsigned int nr_args; |
| 331 | struct probe_arg args[]; | 331 | struct probe_arg args[]; |
| @@ -404,6 +404,7 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
| 404 | goto error; | 404 | goto error; |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | tp->call.class = &tp->class; | ||
| 407 | tp->call.name = kstrdup(event, GFP_KERNEL); | 408 | tp->call.name = kstrdup(event, GFP_KERNEL); |
| 408 | if (!tp->call.name) | 409 | if (!tp->call.name) |
| 409 | goto error; | 410 | goto error; |
| @@ -413,8 +414,8 @@ static struct trace_probe *alloc_trace_probe(const char *group, | |||
| 413 | goto error; | 414 | goto error; |
| 414 | } | 415 | } |
| 415 | 416 | ||
| 416 | tp->call.system = kstrdup(group, GFP_KERNEL); | 417 | tp->class.system = kstrdup(group, GFP_KERNEL); |
| 417 | if (!tp->call.system) | 418 | if (!tp->class.system) |
| 418 | goto error; | 419 | goto error; |
| 419 | 420 | ||
| 420 | INIT_LIST_HEAD(&tp->list); | 421 | INIT_LIST_HEAD(&tp->list); |
| @@ -443,7 +444,7 @@ static void free_trace_probe(struct trace_probe *tp) | |||
| 443 | for (i = 0; i < tp->nr_args; i++) | 444 | for (i = 0; i < tp->nr_args; i++) |
| 444 | free_probe_arg(&tp->args[i]); | 445 | free_probe_arg(&tp->args[i]); |
| 445 | 446 | ||
| 446 | kfree(tp->call.system); | 447 | kfree(tp->call.class->system); |
| 447 | kfree(tp->call.name); | 448 | kfree(tp->call.name); |
| 448 | kfree(tp->symbol); | 449 | kfree(tp->symbol); |
| 449 | kfree(tp); | 450 | kfree(tp); |
| @@ -456,7 +457,7 @@ static struct trace_probe *find_probe_event(const char *event, | |||
| 456 | 457 | ||
| 457 | list_for_each_entry(tp, &probe_list, list) | 458 | list_for_each_entry(tp, &probe_list, list) |
| 458 | if (strcmp(tp->call.name, event) == 0 && | 459 | if (strcmp(tp->call.name, event) == 0 && |
| 459 | strcmp(tp->call.system, group) == 0) | 460 | strcmp(tp->call.class->system, group) == 0) |
| 460 | return tp; | 461 | return tp; |
| 461 | return NULL; | 462 | return NULL; |
| 462 | } | 463 | } |
| @@ -481,7 +482,7 @@ static int register_trace_probe(struct trace_probe *tp) | |||
| 481 | mutex_lock(&probe_lock); | 482 | mutex_lock(&probe_lock); |
| 482 | 483 | ||
| 483 | /* register as an event */ | 484 | /* register as an event */ |
| 484 | old_tp = find_probe_event(tp->call.name, tp->call.system); | 485 | old_tp = find_probe_event(tp->call.name, tp->call.class->system); |
| 485 | if (old_tp) { | 486 | if (old_tp) { |
| 486 | /* delete old event */ | 487 | /* delete old event */ |
| 487 | unregister_trace_probe(old_tp); | 488 | unregister_trace_probe(old_tp); |
| @@ -904,7 +905,7 @@ static int probes_seq_show(struct seq_file *m, void *v) | |||
| 904 | int i; | 905 | int i; |
| 905 | 906 | ||
| 906 | seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p'); | 907 | seq_printf(m, "%c", probe_is_return(tp) ? 'r' : 'p'); |
| 907 | seq_printf(m, ":%s/%s", tp->call.system, tp->call.name); | 908 | seq_printf(m, ":%s/%s", tp->call.class->system, tp->call.name); |
| 908 | 909 | ||
| 909 | if (!tp->symbol) | 910 | if (!tp->symbol) |
| 910 | seq_printf(m, " 0x%p", tp->rp.kp.addr); | 911 | seq_printf(m, " 0x%p", tp->rp.kp.addr); |
| @@ -1061,8 +1062,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 1061 | 1062 | ||
| 1062 | size = sizeof(*entry) + tp->size; | 1063 | size = sizeof(*entry) + tp->size; |
| 1063 | 1064 | ||
| 1064 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 1065 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, |
| 1065 | irq_flags, pc); | 1066 | size, irq_flags, pc); |
| 1066 | if (!event) | 1067 | if (!event) |
| 1067 | return; | 1068 | return; |
| 1068 | 1069 | ||
| @@ -1094,8 +1095,8 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1094 | 1095 | ||
| 1095 | size = sizeof(*entry) + tp->size; | 1096 | size = sizeof(*entry) + tp->size; |
| 1096 | 1097 | ||
| 1097 | event = trace_current_buffer_lock_reserve(&buffer, call->id, size, | 1098 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, |
| 1098 | irq_flags, pc); | 1099 | size, irq_flags, pc); |
| 1099 | if (!event) | 1100 | if (!event) |
| 1100 | return; | 1101 | return; |
| 1101 | 1102 | ||
| @@ -1112,18 +1113,17 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1112 | 1113 | ||
| 1113 | /* Event entry printers */ | 1114 | /* Event entry printers */ |
| 1114 | enum print_line_t | 1115 | enum print_line_t |
| 1115 | print_kprobe_event(struct trace_iterator *iter, int flags) | 1116 | print_kprobe_event(struct trace_iterator *iter, int flags, |
| 1117 | struct trace_event *event) | ||
| 1116 | { | 1118 | { |
| 1117 | struct kprobe_trace_entry_head *field; | 1119 | struct kprobe_trace_entry_head *field; |
| 1118 | struct trace_seq *s = &iter->seq; | 1120 | struct trace_seq *s = &iter->seq; |
| 1119 | struct trace_event *event; | ||
| 1120 | struct trace_probe *tp; | 1121 | struct trace_probe *tp; |
| 1121 | u8 *data; | 1122 | u8 *data; |
| 1122 | int i; | 1123 | int i; |
| 1123 | 1124 | ||
| 1124 | field = (struct kprobe_trace_entry_head *)iter->ent; | 1125 | field = (struct kprobe_trace_entry_head *)iter->ent; |
| 1125 | event = ftrace_find_event(field->ent.type); | 1126 | tp = container_of(event, struct trace_probe, call.event); |
| 1126 | tp = container_of(event, struct trace_probe, event); | ||
| 1127 | 1127 | ||
| 1128 | if (!trace_seq_printf(s, "%s: (", tp->call.name)) | 1128 | if (!trace_seq_printf(s, "%s: (", tp->call.name)) |
| 1129 | goto partial; | 1129 | goto partial; |
| @@ -1149,18 +1149,17 @@ partial: | |||
| 1149 | } | 1149 | } |
| 1150 | 1150 | ||
| 1151 | enum print_line_t | 1151 | enum print_line_t |
| 1152 | print_kretprobe_event(struct trace_iterator *iter, int flags) | 1152 | print_kretprobe_event(struct trace_iterator *iter, int flags, |
| 1153 | struct trace_event *event) | ||
| 1153 | { | 1154 | { |
| 1154 | struct kretprobe_trace_entry_head *field; | 1155 | struct kretprobe_trace_entry_head *field; |
| 1155 | struct trace_seq *s = &iter->seq; | 1156 | struct trace_seq *s = &iter->seq; |
| 1156 | struct trace_event *event; | ||
| 1157 | struct trace_probe *tp; | 1157 | struct trace_probe *tp; |
| 1158 | u8 *data; | 1158 | u8 *data; |
| 1159 | int i; | 1159 | int i; |
| 1160 | 1160 | ||
| 1161 | field = (struct kretprobe_trace_entry_head *)iter->ent; | 1161 | field = (struct kretprobe_trace_entry_head *)iter->ent; |
| 1162 | event = ftrace_find_event(field->ent.type); | 1162 | tp = container_of(event, struct trace_probe, call.event); |
| 1163 | tp = container_of(event, struct trace_probe, event); | ||
| 1164 | 1163 | ||
| 1165 | if (!trace_seq_printf(s, "%s: (", tp->call.name)) | 1164 | if (!trace_seq_printf(s, "%s: (", tp->call.name)) |
| 1166 | goto partial; | 1165 | goto partial; |
| @@ -1217,8 +1216,6 @@ static void probe_event_disable(struct ftrace_event_call *call) | |||
| 1217 | 1216 | ||
| 1218 | static int probe_event_raw_init(struct ftrace_event_call *event_call) | 1217 | static int probe_event_raw_init(struct ftrace_event_call *event_call) |
| 1219 | { | 1218 | { |
| 1220 | INIT_LIST_HEAD(&event_call->fields); | ||
| 1221 | |||
| 1222 | return 0; | 1219 | return 0; |
| 1223 | } | 1220 | } |
| 1224 | 1221 | ||
| @@ -1353,7 +1350,7 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp, | |||
| 1353 | "profile buffer not large enough")) | 1350 | "profile buffer not large enough")) |
| 1354 | return; | 1351 | return; |
| 1355 | 1352 | ||
| 1356 | entry = perf_trace_buf_prepare(size, call->id, regs, &rctx); | 1353 | entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx); |
| 1357 | if (!entry) | 1354 | if (!entry) |
| 1358 | return; | 1355 | return; |
| 1359 | 1356 | ||
| @@ -1385,7 +1382,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, | |||
| 1385 | "profile buffer not large enough")) | 1382 | "profile buffer not large enough")) |
| 1386 | return; | 1383 | return; |
| 1387 | 1384 | ||
| 1388 | entry = perf_trace_buf_prepare(size, call->id, regs, &rctx); | 1385 | entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx); |
| 1389 | if (!entry) | 1386 | if (!entry) |
| 1390 | return; | 1387 | return; |
| 1391 | 1388 | ||
| @@ -1426,6 +1423,26 @@ static void probe_perf_disable(struct ftrace_event_call *call) | |||
| 1426 | } | 1423 | } |
| 1427 | #endif /* CONFIG_PERF_EVENTS */ | 1424 | #endif /* CONFIG_PERF_EVENTS */ |
| 1428 | 1425 | ||
| 1426 | static __kprobes | ||
| 1427 | int kprobe_register(struct ftrace_event_call *event, enum trace_reg type) | ||
| 1428 | { | ||
| 1429 | switch (type) { | ||
| 1430 | case TRACE_REG_REGISTER: | ||
| 1431 | return probe_event_enable(event); | ||
| 1432 | case TRACE_REG_UNREGISTER: | ||
| 1433 | probe_event_disable(event); | ||
| 1434 | return 0; | ||
| 1435 | |||
| 1436 | #ifdef CONFIG_PERF_EVENTS | ||
| 1437 | case TRACE_REG_PERF_REGISTER: | ||
| 1438 | return probe_perf_enable(event); | ||
| 1439 | case TRACE_REG_PERF_UNREGISTER: | ||
| 1440 | probe_perf_disable(event); | ||
| 1441 | return 0; | ||
| 1442 | #endif | ||
| 1443 | } | ||
| 1444 | return 0; | ||
| 1445 | } | ||
| 1429 | 1446 | ||
| 1430 | static __kprobes | 1447 | static __kprobes |
| 1431 | int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) | 1448 | int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) |
| @@ -1455,6 +1472,14 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
| 1455 | return 0; /* We don't tweek kernel, so just return 0 */ | 1472 | return 0; /* We don't tweek kernel, so just return 0 */ |
| 1456 | } | 1473 | } |
| 1457 | 1474 | ||
| 1475 | static struct trace_event_functions kretprobe_funcs = { | ||
| 1476 | .trace = print_kretprobe_event | ||
| 1477 | }; | ||
| 1478 | |||
| 1479 | static struct trace_event_functions kprobe_funcs = { | ||
| 1480 | .trace = print_kprobe_event | ||
| 1481 | }; | ||
| 1482 | |||
| 1458 | static int register_probe_event(struct trace_probe *tp) | 1483 | static int register_probe_event(struct trace_probe *tp) |
| 1459 | { | 1484 | { |
| 1460 | struct ftrace_event_call *call = &tp->call; | 1485 | struct ftrace_event_call *call = &tp->call; |
| @@ -1462,36 +1487,31 @@ static int register_probe_event(struct trace_probe *tp) | |||
| 1462 | 1487 | ||
| 1463 | /* Initialize ftrace_event_call */ | 1488 | /* Initialize ftrace_event_call */ |
| 1464 | if (probe_is_return(tp)) { | 1489 | if (probe_is_return(tp)) { |
| 1465 | tp->event.trace = print_kretprobe_event; | 1490 | INIT_LIST_HEAD(&call->class->fields); |
| 1466 | call->raw_init = probe_event_raw_init; | 1491 | call->event.funcs = &kretprobe_funcs; |
| 1467 | call->define_fields = kretprobe_event_define_fields; | 1492 | call->class->raw_init = probe_event_raw_init; |
| 1493 | call->class->define_fields = kretprobe_event_define_fields; | ||
| 1468 | } else { | 1494 | } else { |
| 1469 | tp->event.trace = print_kprobe_event; | 1495 | INIT_LIST_HEAD(&call->class->fields); |
| 1470 | call->raw_init = probe_event_raw_init; | 1496 | call->event.funcs = &kprobe_funcs; |
| 1471 | call->define_fields = kprobe_event_define_fields; | 1497 | call->class->raw_init = probe_event_raw_init; |
| 1498 | call->class->define_fields = kprobe_event_define_fields; | ||
| 1472 | } | 1499 | } |
| 1473 | if (set_print_fmt(tp) < 0) | 1500 | if (set_print_fmt(tp) < 0) |
| 1474 | return -ENOMEM; | 1501 | return -ENOMEM; |
| 1475 | call->event = &tp->event; | 1502 | ret = register_ftrace_event(&call->event); |
| 1476 | call->id = register_ftrace_event(&tp->event); | 1503 | if (!ret) { |
| 1477 | if (!call->id) { | ||
| 1478 | kfree(call->print_fmt); | 1504 | kfree(call->print_fmt); |
| 1479 | return -ENODEV; | 1505 | return -ENODEV; |
| 1480 | } | 1506 | } |
| 1481 | call->enabled = 0; | 1507 | call->flags = 0; |
| 1482 | call->regfunc = probe_event_enable; | 1508 | call->class->reg = kprobe_register; |
| 1483 | call->unregfunc = probe_event_disable; | ||
| 1484 | |||
| 1485 | #ifdef CONFIG_PERF_EVENTS | ||
| 1486 | call->perf_event_enable = probe_perf_enable; | ||
| 1487 | call->perf_event_disable = probe_perf_disable; | ||
| 1488 | #endif | ||
| 1489 | call->data = tp; | 1509 | call->data = tp; |
| 1490 | ret = trace_add_event_call(call); | 1510 | ret = trace_add_event_call(call); |
| 1491 | if (ret) { | 1511 | if (ret) { |
| 1492 | pr_info("Failed to register kprobe event: %s\n", call->name); | 1512 | pr_info("Failed to register kprobe event: %s\n", call->name); |
| 1493 | kfree(call->print_fmt); | 1513 | kfree(call->print_fmt); |
| 1494 | unregister_ftrace_event(&tp->event); | 1514 | unregister_ftrace_event(&call->event); |
| 1495 | } | 1515 | } |
| 1496 | return ret; | 1516 | return ret; |
| 1497 | } | 1517 | } |
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 2404c129a8c9..fc9d4dbb089e 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
| @@ -726,6 +726,9 @@ int register_ftrace_event(struct trace_event *event) | |||
| 726 | if (WARN_ON(!event)) | 726 | if (WARN_ON(!event)) |
| 727 | goto out; | 727 | goto out; |
| 728 | 728 | ||
| 729 | if (WARN_ON(!event->funcs)) | ||
| 730 | goto out; | ||
| 731 | |||
| 729 | INIT_LIST_HEAD(&event->list); | 732 | INIT_LIST_HEAD(&event->list); |
| 730 | 733 | ||
| 731 | if (!event->type) { | 734 | if (!event->type) { |
| @@ -758,14 +761,14 @@ int register_ftrace_event(struct trace_event *event) | |||
| 758 | goto out; | 761 | goto out; |
| 759 | } | 762 | } |
| 760 | 763 | ||
| 761 | if (event->trace == NULL) | 764 | if (event->funcs->trace == NULL) |
| 762 | event->trace = trace_nop_print; | 765 | event->funcs->trace = trace_nop_print; |
| 763 | if (event->raw == NULL) | 766 | if (event->funcs->raw == NULL) |
| 764 | event->raw = trace_nop_print; | 767 | event->funcs->raw = trace_nop_print; |
| 765 | if (event->hex == NULL) | 768 | if (event->funcs->hex == NULL) |
| 766 | event->hex = trace_nop_print; | 769 | event->funcs->hex = trace_nop_print; |
| 767 | if (event->binary == NULL) | 770 | if (event->funcs->binary == NULL) |
| 768 | event->binary = trace_nop_print; | 771 | event->funcs->binary = trace_nop_print; |
| 769 | 772 | ||
| 770 | key = event->type & (EVENT_HASHSIZE - 1); | 773 | key = event->type & (EVENT_HASHSIZE - 1); |
| 771 | 774 | ||
| @@ -807,13 +810,15 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_event); | |||
| 807 | * Standard events | 810 | * Standard events |
| 808 | */ | 811 | */ |
| 809 | 812 | ||
| 810 | enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags) | 813 | enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags, |
| 814 | struct trace_event *event) | ||
| 811 | { | 815 | { |
| 812 | return TRACE_TYPE_HANDLED; | 816 | return TRACE_TYPE_HANDLED; |
| 813 | } | 817 | } |
| 814 | 818 | ||
| 815 | /* TRACE_FN */ | 819 | /* TRACE_FN */ |
| 816 | static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags) | 820 | static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags, |
| 821 | struct trace_event *event) | ||
| 817 | { | 822 | { |
| 818 | struct ftrace_entry *field; | 823 | struct ftrace_entry *field; |
| 819 | struct trace_seq *s = &iter->seq; | 824 | struct trace_seq *s = &iter->seq; |
| @@ -840,7 +845,8 @@ static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags) | |||
| 840 | return TRACE_TYPE_PARTIAL_LINE; | 845 | return TRACE_TYPE_PARTIAL_LINE; |
| 841 | } | 846 | } |
| 842 | 847 | ||
| 843 | static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags) | 848 | static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags, |
| 849 | struct trace_event *event) | ||
| 844 | { | 850 | { |
| 845 | struct ftrace_entry *field; | 851 | struct ftrace_entry *field; |
| 846 | 852 | ||
| @@ -854,7 +860,8 @@ static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags) | |||
| 854 | return TRACE_TYPE_HANDLED; | 860 | return TRACE_TYPE_HANDLED; |
| 855 | } | 861 | } |
| 856 | 862 | ||
| 857 | static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags) | 863 | static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags, |
| 864 | struct trace_event *event) | ||
| 858 | { | 865 | { |
| 859 | struct ftrace_entry *field; | 866 | struct ftrace_entry *field; |
| 860 | struct trace_seq *s = &iter->seq; | 867 | struct trace_seq *s = &iter->seq; |
| @@ -867,7 +874,8 @@ static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags) | |||
| 867 | return TRACE_TYPE_HANDLED; | 874 | return TRACE_TYPE_HANDLED; |
| 868 | } | 875 | } |
| 869 | 876 | ||
| 870 | static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags) | 877 | static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags, |
| 878 | struct trace_event *event) | ||
| 871 | { | 879 | { |
| 872 | struct ftrace_entry *field; | 880 | struct ftrace_entry *field; |
| 873 | struct trace_seq *s = &iter->seq; | 881 | struct trace_seq *s = &iter->seq; |
| @@ -880,14 +888,18 @@ static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags) | |||
| 880 | return TRACE_TYPE_HANDLED; | 888 | return TRACE_TYPE_HANDLED; |
| 881 | } | 889 | } |
| 882 | 890 | ||
| 883 | static struct trace_event trace_fn_event = { | 891 | static struct trace_event_functions trace_fn_funcs = { |
| 884 | .type = TRACE_FN, | ||
| 885 | .trace = trace_fn_trace, | 892 | .trace = trace_fn_trace, |
| 886 | .raw = trace_fn_raw, | 893 | .raw = trace_fn_raw, |
| 887 | .hex = trace_fn_hex, | 894 | .hex = trace_fn_hex, |
| 888 | .binary = trace_fn_bin, | 895 | .binary = trace_fn_bin, |
| 889 | }; | 896 | }; |
| 890 | 897 | ||
| 898 | static struct trace_event trace_fn_event = { | ||
| 899 | .type = TRACE_FN, | ||
| 900 | .funcs = &trace_fn_funcs, | ||
| 901 | }; | ||
| 902 | |||
| 891 | /* TRACE_CTX an TRACE_WAKE */ | 903 | /* TRACE_CTX an TRACE_WAKE */ |
| 892 | static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, | 904 | static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, |
| 893 | char *delim) | 905 | char *delim) |
| @@ -916,13 +928,14 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter, | |||
| 916 | return TRACE_TYPE_HANDLED; | 928 | return TRACE_TYPE_HANDLED; |
| 917 | } | 929 | } |
| 918 | 930 | ||
| 919 | static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags) | 931 | static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags, |
| 932 | struct trace_event *event) | ||
| 920 | { | 933 | { |
| 921 | return trace_ctxwake_print(iter, "==>"); | 934 | return trace_ctxwake_print(iter, "==>"); |
| 922 | } | 935 | } |
| 923 | 936 | ||
| 924 | static enum print_line_t trace_wake_print(struct trace_iterator *iter, | 937 | static enum print_line_t trace_wake_print(struct trace_iterator *iter, |
| 925 | int flags) | 938 | int flags, struct trace_event *event) |
| 926 | { | 939 | { |
| 927 | return trace_ctxwake_print(iter, " +"); | 940 | return trace_ctxwake_print(iter, " +"); |
| 928 | } | 941 | } |
| @@ -950,12 +963,14 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S) | |||
| 950 | return TRACE_TYPE_HANDLED; | 963 | return TRACE_TYPE_HANDLED; |
| 951 | } | 964 | } |
| 952 | 965 | ||
| 953 | static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags) | 966 | static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags, |
| 967 | struct trace_event *event) | ||
| 954 | { | 968 | { |
| 955 | return trace_ctxwake_raw(iter, 0); | 969 | return trace_ctxwake_raw(iter, 0); |
| 956 | } | 970 | } |
| 957 | 971 | ||
| 958 | static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags) | 972 | static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags, |
| 973 | struct trace_event *event) | ||
| 959 | { | 974 | { |
| 960 | return trace_ctxwake_raw(iter, '+'); | 975 | return trace_ctxwake_raw(iter, '+'); |
| 961 | } | 976 | } |
| @@ -984,18 +999,20 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S) | |||
| 984 | return TRACE_TYPE_HANDLED; | 999 | return TRACE_TYPE_HANDLED; |
| 985 | } | 1000 | } |
| 986 | 1001 | ||
| 987 | static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags) | 1002 | static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags, |
| 1003 | struct trace_event *event) | ||
| 988 | { | 1004 | { |
| 989 | return trace_ctxwake_hex(iter, 0); | 1005 | return trace_ctxwake_hex(iter, 0); |
| 990 | } | 1006 | } |
| 991 | 1007 | ||
| 992 | static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags) | 1008 | static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags, |
| 1009 | struct trace_event *event) | ||
| 993 | { | 1010 | { |
| 994 | return trace_ctxwake_hex(iter, '+'); | 1011 | return trace_ctxwake_hex(iter, '+'); |
| 995 | } | 1012 | } |
| 996 | 1013 | ||
| 997 | static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, | 1014 | static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, |
| 998 | int flags) | 1015 | int flags, struct trace_event *event) |
| 999 | { | 1016 | { |
| 1000 | struct ctx_switch_entry *field; | 1017 | struct ctx_switch_entry *field; |
| 1001 | struct trace_seq *s = &iter->seq; | 1018 | struct trace_seq *s = &iter->seq; |
| @@ -1012,25 +1029,33 @@ static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter, | |||
| 1012 | return TRACE_TYPE_HANDLED; | 1029 | return TRACE_TYPE_HANDLED; |
| 1013 | } | 1030 | } |
| 1014 | 1031 | ||
| 1015 | static struct trace_event trace_ctx_event = { | 1032 | static struct trace_event_functions trace_ctx_funcs = { |
| 1016 | .type = TRACE_CTX, | ||
| 1017 | .trace = trace_ctx_print, | 1033 | .trace = trace_ctx_print, |
| 1018 | .raw = trace_ctx_raw, | 1034 | .raw = trace_ctx_raw, |
| 1019 | .hex = trace_ctx_hex, | 1035 | .hex = trace_ctx_hex, |
| 1020 | .binary = trace_ctxwake_bin, | 1036 | .binary = trace_ctxwake_bin, |
| 1021 | }; | 1037 | }; |
| 1022 | 1038 | ||
| 1023 | static struct trace_event trace_wake_event = { | 1039 | static struct trace_event trace_ctx_event = { |
| 1024 | .type = TRACE_WAKE, | 1040 | .type = TRACE_CTX, |
| 1041 | .funcs = &trace_ctx_funcs, | ||
| 1042 | }; | ||
| 1043 | |||
| 1044 | static struct trace_event_functions trace_wake_funcs = { | ||
| 1025 | .trace = trace_wake_print, | 1045 | .trace = trace_wake_print, |
| 1026 | .raw = trace_wake_raw, | 1046 | .raw = trace_wake_raw, |
| 1027 | .hex = trace_wake_hex, | 1047 | .hex = trace_wake_hex, |
| 1028 | .binary = trace_ctxwake_bin, | 1048 | .binary = trace_ctxwake_bin, |
| 1029 | }; | 1049 | }; |
| 1030 | 1050 | ||
| 1051 | static struct trace_event trace_wake_event = { | ||
| 1052 | .type = TRACE_WAKE, | ||
| 1053 | .funcs = &trace_wake_funcs, | ||
| 1054 | }; | ||
| 1055 | |||
| 1031 | /* TRACE_SPECIAL */ | 1056 | /* TRACE_SPECIAL */ |
| 1032 | static enum print_line_t trace_special_print(struct trace_iterator *iter, | 1057 | static enum print_line_t trace_special_print(struct trace_iterator *iter, |
| 1033 | int flags) | 1058 | int flags, struct trace_event *event) |
| 1034 | { | 1059 | { |
| 1035 | struct special_entry *field; | 1060 | struct special_entry *field; |
| 1036 | 1061 | ||
| @@ -1046,7 +1071,7 @@ static enum print_line_t trace_special_print(struct trace_iterator *iter, | |||
| 1046 | } | 1071 | } |
| 1047 | 1072 | ||
| 1048 | static enum print_line_t trace_special_hex(struct trace_iterator *iter, | 1073 | static enum print_line_t trace_special_hex(struct trace_iterator *iter, |
| 1049 | int flags) | 1074 | int flags, struct trace_event *event) |
| 1050 | { | 1075 | { |
| 1051 | struct special_entry *field; | 1076 | struct special_entry *field; |
| 1052 | struct trace_seq *s = &iter->seq; | 1077 | struct trace_seq *s = &iter->seq; |
| @@ -1061,7 +1086,7 @@ static enum print_line_t trace_special_hex(struct trace_iterator *iter, | |||
| 1061 | } | 1086 | } |
| 1062 | 1087 | ||
| 1063 | static enum print_line_t trace_special_bin(struct trace_iterator *iter, | 1088 | static enum print_line_t trace_special_bin(struct trace_iterator *iter, |
| 1064 | int flags) | 1089 | int flags, struct trace_event *event) |
| 1065 | { | 1090 | { |
| 1066 | struct special_entry *field; | 1091 | struct special_entry *field; |
| 1067 | struct trace_seq *s = &iter->seq; | 1092 | struct trace_seq *s = &iter->seq; |
| @@ -1075,18 +1100,22 @@ static enum print_line_t trace_special_bin(struct trace_iterator *iter, | |||
| 1075 | return TRACE_TYPE_HANDLED; | 1100 | return TRACE_TYPE_HANDLED; |
| 1076 | } | 1101 | } |
| 1077 | 1102 | ||
| 1078 | static struct trace_event trace_special_event = { | 1103 | static struct trace_event_functions trace_special_funcs = { |
| 1079 | .type = TRACE_SPECIAL, | ||
| 1080 | .trace = trace_special_print, | 1104 | .trace = trace_special_print, |
| 1081 | .raw = trace_special_print, | 1105 | .raw = trace_special_print, |
| 1082 | .hex = trace_special_hex, | 1106 | .hex = trace_special_hex, |
| 1083 | .binary = trace_special_bin, | 1107 | .binary = trace_special_bin, |
| 1084 | }; | 1108 | }; |
| 1085 | 1109 | ||
| 1110 | static struct trace_event trace_special_event = { | ||
| 1111 | .type = TRACE_SPECIAL, | ||
| 1112 | .funcs = &trace_special_funcs, | ||
| 1113 | }; | ||
| 1114 | |||
| 1086 | /* TRACE_STACK */ | 1115 | /* TRACE_STACK */ |
| 1087 | 1116 | ||
| 1088 | static enum print_line_t trace_stack_print(struct trace_iterator *iter, | 1117 | static enum print_line_t trace_stack_print(struct trace_iterator *iter, |
| 1089 | int flags) | 1118 | int flags, struct trace_event *event) |
| 1090 | { | 1119 | { |
| 1091 | struct stack_entry *field; | 1120 | struct stack_entry *field; |
| 1092 | struct trace_seq *s = &iter->seq; | 1121 | struct trace_seq *s = &iter->seq; |
| @@ -1114,17 +1143,21 @@ static enum print_line_t trace_stack_print(struct trace_iterator *iter, | |||
| 1114 | return TRACE_TYPE_PARTIAL_LINE; | 1143 | return TRACE_TYPE_PARTIAL_LINE; |
| 1115 | } | 1144 | } |
| 1116 | 1145 | ||
| 1117 | static struct trace_event trace_stack_event = { | 1146 | static struct trace_event_functions trace_stack_funcs = { |
| 1118 | .type = TRACE_STACK, | ||
| 1119 | .trace = trace_stack_print, | 1147 | .trace = trace_stack_print, |
| 1120 | .raw = trace_special_print, | 1148 | .raw = trace_special_print, |
| 1121 | .hex = trace_special_hex, | 1149 | .hex = trace_special_hex, |
| 1122 | .binary = trace_special_bin, | 1150 | .binary = trace_special_bin, |
| 1123 | }; | 1151 | }; |
| 1124 | 1152 | ||
| 1153 | static struct trace_event trace_stack_event = { | ||
| 1154 | .type = TRACE_STACK, | ||
| 1155 | .funcs = &trace_stack_funcs, | ||
| 1156 | }; | ||
| 1157 | |||
| 1125 | /* TRACE_USER_STACK */ | 1158 | /* TRACE_USER_STACK */ |
| 1126 | static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, | 1159 | static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, |
| 1127 | int flags) | 1160 | int flags, struct trace_event *event) |
| 1128 | { | 1161 | { |
| 1129 | struct userstack_entry *field; | 1162 | struct userstack_entry *field; |
| 1130 | struct trace_seq *s = &iter->seq; | 1163 | struct trace_seq *s = &iter->seq; |
| @@ -1143,17 +1176,22 @@ static enum print_line_t trace_user_stack_print(struct trace_iterator *iter, | |||
| 1143 | return TRACE_TYPE_PARTIAL_LINE; | 1176 | return TRACE_TYPE_PARTIAL_LINE; |
| 1144 | } | 1177 | } |
| 1145 | 1178 | ||
| 1146 | static struct trace_event trace_user_stack_event = { | 1179 | static struct trace_event_functions trace_user_stack_funcs = { |
| 1147 | .type = TRACE_USER_STACK, | ||
| 1148 | .trace = trace_user_stack_print, | 1180 | .trace = trace_user_stack_print, |
| 1149 | .raw = trace_special_print, | 1181 | .raw = trace_special_print, |
| 1150 | .hex = trace_special_hex, | 1182 | .hex = trace_special_hex, |
| 1151 | .binary = trace_special_bin, | 1183 | .binary = trace_special_bin, |
| 1152 | }; | 1184 | }; |
| 1153 | 1185 | ||
| 1186 | static struct trace_event trace_user_stack_event = { | ||
| 1187 | .type = TRACE_USER_STACK, | ||
| 1188 | .funcs = &trace_user_stack_funcs, | ||
| 1189 | }; | ||
| 1190 | |||
| 1154 | /* TRACE_BPRINT */ | 1191 | /* TRACE_BPRINT */ |
| 1155 | static enum print_line_t | 1192 | static enum print_line_t |
| 1156 | trace_bprint_print(struct trace_iterator *iter, int flags) | 1193 | trace_bprint_print(struct trace_iterator *iter, int flags, |
| 1194 | struct trace_event *event) | ||
| 1157 | { | 1195 | { |
| 1158 | struct trace_entry *entry = iter->ent; | 1196 | struct trace_entry *entry = iter->ent; |
| 1159 | struct trace_seq *s = &iter->seq; | 1197 | struct trace_seq *s = &iter->seq; |
| @@ -1178,7 +1216,8 @@ trace_bprint_print(struct trace_iterator *iter, int flags) | |||
| 1178 | 1216 | ||
| 1179 | 1217 | ||
| 1180 | static enum print_line_t | 1218 | static enum print_line_t |
| 1181 | trace_bprint_raw(struct trace_iterator *iter, int flags) | 1219 | trace_bprint_raw(struct trace_iterator *iter, int flags, |
| 1220 | struct trace_event *event) | ||
| 1182 | { | 1221 | { |
| 1183 | struct bprint_entry *field; | 1222 | struct bprint_entry *field; |
| 1184 | struct trace_seq *s = &iter->seq; | 1223 | struct trace_seq *s = &iter->seq; |
| @@ -1197,16 +1236,19 @@ trace_bprint_raw(struct trace_iterator *iter, int flags) | |||
| 1197 | return TRACE_TYPE_PARTIAL_LINE; | 1236 | return TRACE_TYPE_PARTIAL_LINE; |
| 1198 | } | 1237 | } |
| 1199 | 1238 | ||
| 1239 | static struct trace_event_functions trace_bprint_funcs = { | ||
| 1240 | .trace = trace_bprint_print, | ||
| 1241 | .raw = trace_bprint_raw, | ||
| 1242 | }; | ||
| 1200 | 1243 | ||
| 1201 | static struct trace_event trace_bprint_event = { | 1244 | static struct trace_event trace_bprint_event = { |
| 1202 | .type = TRACE_BPRINT, | 1245 | .type = TRACE_BPRINT, |
| 1203 | .trace = trace_bprint_print, | 1246 | .funcs = &trace_bprint_funcs, |
| 1204 | .raw = trace_bprint_raw, | ||
| 1205 | }; | 1247 | }; |
| 1206 | 1248 | ||
| 1207 | /* TRACE_PRINT */ | 1249 | /* TRACE_PRINT */ |
| 1208 | static enum print_line_t trace_print_print(struct trace_iterator *iter, | 1250 | static enum print_line_t trace_print_print(struct trace_iterator *iter, |
| 1209 | int flags) | 1251 | int flags, struct trace_event *event) |
| 1210 | { | 1252 | { |
| 1211 | struct print_entry *field; | 1253 | struct print_entry *field; |
| 1212 | struct trace_seq *s = &iter->seq; | 1254 | struct trace_seq *s = &iter->seq; |
| @@ -1225,7 +1267,8 @@ static enum print_line_t trace_print_print(struct trace_iterator *iter, | |||
| 1225 | return TRACE_TYPE_PARTIAL_LINE; | 1267 | return TRACE_TYPE_PARTIAL_LINE; |
| 1226 | } | 1268 | } |
| 1227 | 1269 | ||
| 1228 | static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags) | 1270 | static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags, |
| 1271 | struct trace_event *event) | ||
| 1229 | { | 1272 | { |
| 1230 | struct print_entry *field; | 1273 | struct print_entry *field; |
| 1231 | 1274 | ||
| @@ -1240,12 +1283,16 @@ static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags) | |||
| 1240 | return TRACE_TYPE_PARTIAL_LINE; | 1283 | return TRACE_TYPE_PARTIAL_LINE; |
| 1241 | } | 1284 | } |
| 1242 | 1285 | ||
| 1243 | static struct trace_event trace_print_event = { | 1286 | static struct trace_event_functions trace_print_funcs = { |
| 1244 | .type = TRACE_PRINT, | ||
| 1245 | .trace = trace_print_print, | 1287 | .trace = trace_print_print, |
| 1246 | .raw = trace_print_raw, | 1288 | .raw = trace_print_raw, |
| 1247 | }; | 1289 | }; |
| 1248 | 1290 | ||
| 1291 | static struct trace_event trace_print_event = { | ||
| 1292 | .type = TRACE_PRINT, | ||
| 1293 | .funcs = &trace_print_funcs, | ||
| 1294 | }; | ||
| 1295 | |||
| 1249 | 1296 | ||
| 1250 | static struct trace_event *events[] __initdata = { | 1297 | static struct trace_event *events[] __initdata = { |
| 1251 | &trace_fn_event, | 1298 | &trace_fn_event, |
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h index 9d91c72ba38b..c038eba0492b 100644 --- a/kernel/trace/trace_output.h +++ b/kernel/trace/trace_output.h | |||
| @@ -25,7 +25,7 @@ extern void trace_event_read_unlock(void); | |||
| 25 | extern struct trace_event *ftrace_find_event(int type); | 25 | extern struct trace_event *ftrace_find_event(int type); |
| 26 | 26 | ||
| 27 | extern enum print_line_t trace_nop_print(struct trace_iterator *iter, | 27 | extern enum print_line_t trace_nop_print(struct trace_iterator *iter, |
| 28 | int flags); | 28 | int flags, struct trace_event *event); |
| 29 | extern int | 29 | extern int |
| 30 | trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry); | 30 | trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry); |
| 31 | 31 | ||
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index a55fccfede5d..8f758d070c43 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c | |||
| @@ -50,7 +50,7 @@ tracing_sched_switch_trace(struct trace_array *tr, | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | static void | 52 | static void |
| 53 | probe_sched_switch(struct task_struct *prev, struct task_struct *next) | 53 | probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) |
| 54 | { | 54 | { |
| 55 | struct trace_array_cpu *data; | 55 | struct trace_array_cpu *data; |
| 56 | unsigned long flags; | 56 | unsigned long flags; |
| @@ -108,7 +108,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr, | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void | 110 | static void |
| 111 | probe_sched_wakeup(struct task_struct *wakee, int success) | 111 | probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success) |
| 112 | { | 112 | { |
| 113 | struct trace_array_cpu *data; | 113 | struct trace_array_cpu *data; |
| 114 | unsigned long flags; | 114 | unsigned long flags; |
| @@ -138,21 +138,21 @@ static int tracing_sched_register(void) | |||
| 138 | { | 138 | { |
| 139 | int ret; | 139 | int ret; |
| 140 | 140 | ||
| 141 | ret = register_trace_sched_wakeup(probe_sched_wakeup); | 141 | ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL); |
| 142 | if (ret) { | 142 | if (ret) { |
| 143 | pr_info("wakeup trace: Couldn't activate tracepoint" | 143 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 144 | " probe to kernel_sched_wakeup\n"); | 144 | " probe to kernel_sched_wakeup\n"); |
| 145 | return ret; | 145 | return ret; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | ret = register_trace_sched_wakeup_new(probe_sched_wakeup); | 148 | ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL); |
| 149 | if (ret) { | 149 | if (ret) { |
| 150 | pr_info("wakeup trace: Couldn't activate tracepoint" | 150 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 151 | " probe to kernel_sched_wakeup_new\n"); | 151 | " probe to kernel_sched_wakeup_new\n"); |
| 152 | goto fail_deprobe; | 152 | goto fail_deprobe; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | ret = register_trace_sched_switch(probe_sched_switch); | 155 | ret = register_trace_sched_switch(probe_sched_switch, NULL); |
| 156 | if (ret) { | 156 | if (ret) { |
| 157 | pr_info("sched trace: Couldn't activate tracepoint" | 157 | pr_info("sched trace: Couldn't activate tracepoint" |
| 158 | " probe to kernel_sched_switch\n"); | 158 | " probe to kernel_sched_switch\n"); |
| @@ -161,17 +161,17 @@ static int tracing_sched_register(void) | |||
| 161 | 161 | ||
| 162 | return ret; | 162 | return ret; |
| 163 | fail_deprobe_wake_new: | 163 | fail_deprobe_wake_new: |
| 164 | unregister_trace_sched_wakeup_new(probe_sched_wakeup); | 164 | unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); |
| 165 | fail_deprobe: | 165 | fail_deprobe: |
| 166 | unregister_trace_sched_wakeup(probe_sched_wakeup); | 166 | unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); |
| 167 | return ret; | 167 | return ret; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static void tracing_sched_unregister(void) | 170 | static void tracing_sched_unregister(void) |
| 171 | { | 171 | { |
| 172 | unregister_trace_sched_switch(probe_sched_switch); | 172 | unregister_trace_sched_switch(probe_sched_switch, NULL); |
| 173 | unregister_trace_sched_wakeup_new(probe_sched_wakeup); | 173 | unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL); |
| 174 | unregister_trace_sched_wakeup(probe_sched_wakeup); | 174 | unregister_trace_sched_wakeup(probe_sched_wakeup, NULL); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | static void tracing_start_sched_switch(void) | 177 | static void tracing_start_sched_switch(void) |
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 8052446ceeaa..0e73bc2ef8c5 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c | |||
| @@ -98,7 +98,8 @@ static int report_latency(cycle_t delta) | |||
| 98 | return 1; | 98 | return 1; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static void probe_wakeup_migrate_task(struct task_struct *task, int cpu) | 101 | static void |
| 102 | probe_wakeup_migrate_task(void *ignore, struct task_struct *task, int cpu) | ||
| 102 | { | 103 | { |
| 103 | if (task != wakeup_task) | 104 | if (task != wakeup_task) |
| 104 | return; | 105 | return; |
| @@ -107,7 +108,8 @@ static void probe_wakeup_migrate_task(struct task_struct *task, int cpu) | |||
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static void notrace | 110 | static void notrace |
| 110 | probe_wakeup_sched_switch(struct task_struct *prev, struct task_struct *next) | 111 | probe_wakeup_sched_switch(void *ignore, |
| 112 | struct task_struct *prev, struct task_struct *next) | ||
| 111 | { | 113 | { |
| 112 | struct trace_array_cpu *data; | 114 | struct trace_array_cpu *data; |
| 113 | cycle_t T0, T1, delta; | 115 | cycle_t T0, T1, delta; |
| @@ -199,7 +201,7 @@ static void wakeup_reset(struct trace_array *tr) | |||
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | static void | 203 | static void |
| 202 | probe_wakeup(struct task_struct *p, int success) | 204 | probe_wakeup(void *ignore, struct task_struct *p, int success) |
| 203 | { | 205 | { |
| 204 | struct trace_array_cpu *data; | 206 | struct trace_array_cpu *data; |
| 205 | int cpu = smp_processor_id(); | 207 | int cpu = smp_processor_id(); |
| @@ -263,28 +265,28 @@ static void start_wakeup_tracer(struct trace_array *tr) | |||
| 263 | { | 265 | { |
| 264 | int ret; | 266 | int ret; |
| 265 | 267 | ||
| 266 | ret = register_trace_sched_wakeup(probe_wakeup); | 268 | ret = register_trace_sched_wakeup(probe_wakeup, NULL); |
| 267 | if (ret) { | 269 | if (ret) { |
| 268 | pr_info("wakeup trace: Couldn't activate tracepoint" | 270 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 269 | " probe to kernel_sched_wakeup\n"); | 271 | " probe to kernel_sched_wakeup\n"); |
| 270 | return; | 272 | return; |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | ret = register_trace_sched_wakeup_new(probe_wakeup); | 275 | ret = register_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 274 | if (ret) { | 276 | if (ret) { |
| 275 | pr_info("wakeup trace: Couldn't activate tracepoint" | 277 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 276 | " probe to kernel_sched_wakeup_new\n"); | 278 | " probe to kernel_sched_wakeup_new\n"); |
| 277 | goto fail_deprobe; | 279 | goto fail_deprobe; |
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | ret = register_trace_sched_switch(probe_wakeup_sched_switch); | 282 | ret = register_trace_sched_switch(probe_wakeup_sched_switch, NULL); |
| 281 | if (ret) { | 283 | if (ret) { |
| 282 | pr_info("sched trace: Couldn't activate tracepoint" | 284 | pr_info("sched trace: Couldn't activate tracepoint" |
| 283 | " probe to kernel_sched_switch\n"); | 285 | " probe to kernel_sched_switch\n"); |
| 284 | goto fail_deprobe_wake_new; | 286 | goto fail_deprobe_wake_new; |
| 285 | } | 287 | } |
| 286 | 288 | ||
| 287 | ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task); | 289 | ret = register_trace_sched_migrate_task(probe_wakeup_migrate_task, NULL); |
| 288 | if (ret) { | 290 | if (ret) { |
| 289 | pr_info("wakeup trace: Couldn't activate tracepoint" | 291 | pr_info("wakeup trace: Couldn't activate tracepoint" |
| 290 | " probe to kernel_sched_migrate_task\n"); | 292 | " probe to kernel_sched_migrate_task\n"); |
| @@ -311,19 +313,19 @@ static void start_wakeup_tracer(struct trace_array *tr) | |||
| 311 | 313 | ||
| 312 | return; | 314 | return; |
| 313 | fail_deprobe_wake_new: | 315 | fail_deprobe_wake_new: |
| 314 | unregister_trace_sched_wakeup_new(probe_wakeup); | 316 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 315 | fail_deprobe: | 317 | fail_deprobe: |
| 316 | unregister_trace_sched_wakeup(probe_wakeup); | 318 | unregister_trace_sched_wakeup(probe_wakeup, NULL); |
| 317 | } | 319 | } |
| 318 | 320 | ||
| 319 | static void stop_wakeup_tracer(struct trace_array *tr) | 321 | static void stop_wakeup_tracer(struct trace_array *tr) |
| 320 | { | 322 | { |
| 321 | tracer_enabled = 0; | 323 | tracer_enabled = 0; |
| 322 | unregister_ftrace_function(&trace_ops); | 324 | unregister_ftrace_function(&trace_ops); |
| 323 | unregister_trace_sched_switch(probe_wakeup_sched_switch); | 325 | unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); |
| 324 | unregister_trace_sched_wakeup_new(probe_wakeup); | 326 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 325 | unregister_trace_sched_wakeup(probe_wakeup); | 327 | unregister_trace_sched_wakeup(probe_wakeup, NULL); |
| 326 | unregister_trace_sched_migrate_task(probe_wakeup_migrate_task); | 328 | unregister_trace_sched_migrate_task(probe_wakeup_migrate_task, NULL); |
| 327 | } | 329 | } |
| 328 | 330 | ||
| 329 | static int __wakeup_tracer_init(struct trace_array *tr) | 331 | static int __wakeup_tracer_init(struct trace_array *tr) |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index eb769f270291..d2c859cec9ea 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
| @@ -15,6 +15,54 @@ static int sys_refcount_exit; | |||
| 15 | static DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls); | 15 | static DECLARE_BITMAP(enabled_enter_syscalls, NR_syscalls); |
| 16 | static DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls); | 16 | static DECLARE_BITMAP(enabled_exit_syscalls, NR_syscalls); |
| 17 | 17 | ||
| 18 | static int syscall_enter_register(struct ftrace_event_call *event, | ||
| 19 | enum trace_reg type); | ||
| 20 | static int syscall_exit_register(struct ftrace_event_call *event, | ||
| 21 | enum trace_reg type); | ||
| 22 | |||
| 23 | static int syscall_enter_define_fields(struct ftrace_event_call *call); | ||
| 24 | static int syscall_exit_define_fields(struct ftrace_event_call *call); | ||
| 25 | |||
| 26 | static struct list_head * | ||
| 27 | syscall_get_enter_fields(struct ftrace_event_call *call) | ||
| 28 | { | ||
| 29 | struct syscall_metadata *entry = call->data; | ||
| 30 | |||
| 31 | return &entry->enter_fields; | ||
| 32 | } | ||
| 33 | |||
| 34 | static struct list_head * | ||
| 35 | syscall_get_exit_fields(struct ftrace_event_call *call) | ||
| 36 | { | ||
| 37 | struct syscall_metadata *entry = call->data; | ||
| 38 | |||
| 39 | return &entry->exit_fields; | ||
| 40 | } | ||
| 41 | |||
| 42 | struct trace_event_functions enter_syscall_print_funcs = { | ||
| 43 | .trace = print_syscall_enter, | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct trace_event_functions exit_syscall_print_funcs = { | ||
| 47 | .trace = print_syscall_exit, | ||
| 48 | }; | ||
| 49 | |||
| 50 | struct ftrace_event_class event_class_syscall_enter = { | ||
| 51 | .system = "syscalls", | ||
| 52 | .reg = syscall_enter_register, | ||
| 53 | .define_fields = syscall_enter_define_fields, | ||
| 54 | .get_fields = syscall_get_enter_fields, | ||
| 55 | .raw_init = init_syscall_trace, | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct ftrace_event_class event_class_syscall_exit = { | ||
| 59 | .system = "syscalls", | ||
| 60 | .reg = syscall_exit_register, | ||
| 61 | .define_fields = syscall_exit_define_fields, | ||
| 62 | .get_fields = syscall_get_exit_fields, | ||
| 63 | .raw_init = init_syscall_trace, | ||
| 64 | }; | ||
| 65 | |||
| 18 | extern unsigned long __start_syscalls_metadata[]; | 66 | extern unsigned long __start_syscalls_metadata[]; |
| 19 | extern unsigned long __stop_syscalls_metadata[]; | 67 | extern unsigned long __stop_syscalls_metadata[]; |
| 20 | 68 | ||
| @@ -53,7 +101,8 @@ static struct syscall_metadata *syscall_nr_to_meta(int nr) | |||
| 53 | } | 101 | } |
| 54 | 102 | ||
| 55 | enum print_line_t | 103 | enum print_line_t |
| 56 | print_syscall_enter(struct trace_iterator *iter, int flags) | 104 | print_syscall_enter(struct trace_iterator *iter, int flags, |
| 105 | struct trace_event *event) | ||
| 57 | { | 106 | { |
| 58 | struct trace_seq *s = &iter->seq; | 107 | struct trace_seq *s = &iter->seq; |
| 59 | struct trace_entry *ent = iter->ent; | 108 | struct trace_entry *ent = iter->ent; |
| @@ -68,7 +117,7 @@ print_syscall_enter(struct trace_iterator *iter, int flags) | |||
| 68 | if (!entry) | 117 | if (!entry) |
| 69 | goto end; | 118 | goto end; |
| 70 | 119 | ||
| 71 | if (entry->enter_event->id != ent->type) { | 120 | if (entry->enter_event->event.type != ent->type) { |
| 72 | WARN_ON_ONCE(1); | 121 | WARN_ON_ONCE(1); |
| 73 | goto end; | 122 | goto end; |
| 74 | } | 123 | } |
| @@ -105,7 +154,8 @@ end: | |||
| 105 | } | 154 | } |
| 106 | 155 | ||
| 107 | enum print_line_t | 156 | enum print_line_t |
| 108 | print_syscall_exit(struct trace_iterator *iter, int flags) | 157 | print_syscall_exit(struct trace_iterator *iter, int flags, |
| 158 | struct trace_event *event) | ||
| 109 | { | 159 | { |
| 110 | struct trace_seq *s = &iter->seq; | 160 | struct trace_seq *s = &iter->seq; |
| 111 | struct trace_entry *ent = iter->ent; | 161 | struct trace_entry *ent = iter->ent; |
| @@ -123,7 +173,7 @@ print_syscall_exit(struct trace_iterator *iter, int flags) | |||
| 123 | return TRACE_TYPE_HANDLED; | 173 | return TRACE_TYPE_HANDLED; |
| 124 | } | 174 | } |
| 125 | 175 | ||
| 126 | if (entry->exit_event->id != ent->type) { | 176 | if (entry->exit_event->event.type != ent->type) { |
| 127 | WARN_ON_ONCE(1); | 177 | WARN_ON_ONCE(1); |
| 128 | return TRACE_TYPE_UNHANDLED; | 178 | return TRACE_TYPE_UNHANDLED; |
| 129 | } | 179 | } |
| @@ -205,7 +255,7 @@ static void free_syscall_print_fmt(struct ftrace_event_call *call) | |||
| 205 | kfree(call->print_fmt); | 255 | kfree(call->print_fmt); |
| 206 | } | 256 | } |
| 207 | 257 | ||
| 208 | int syscall_enter_define_fields(struct ftrace_event_call *call) | 258 | static int syscall_enter_define_fields(struct ftrace_event_call *call) |
| 209 | { | 259 | { |
| 210 | struct syscall_trace_enter trace; | 260 | struct syscall_trace_enter trace; |
| 211 | struct syscall_metadata *meta = call->data; | 261 | struct syscall_metadata *meta = call->data; |
| @@ -228,7 +278,7 @@ int syscall_enter_define_fields(struct ftrace_event_call *call) | |||
| 228 | return ret; | 278 | return ret; |
| 229 | } | 279 | } |
| 230 | 280 | ||
| 231 | int syscall_exit_define_fields(struct ftrace_event_call *call) | 281 | static int syscall_exit_define_fields(struct ftrace_event_call *call) |
| 232 | { | 282 | { |
| 233 | struct syscall_trace_exit trace; | 283 | struct syscall_trace_exit trace; |
| 234 | int ret; | 284 | int ret; |
| @@ -243,7 +293,7 @@ int syscall_exit_define_fields(struct ftrace_event_call *call) | |||
| 243 | return ret; | 293 | return ret; |
| 244 | } | 294 | } |
| 245 | 295 | ||
| 246 | void ftrace_syscall_enter(struct pt_regs *regs, long id) | 296 | void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id) |
| 247 | { | 297 | { |
| 248 | struct syscall_trace_enter *entry; | 298 | struct syscall_trace_enter *entry; |
| 249 | struct syscall_metadata *sys_data; | 299 | struct syscall_metadata *sys_data; |
| @@ -265,7 +315,7 @@ void ftrace_syscall_enter(struct pt_regs *regs, long id) | |||
| 265 | size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; | 315 | size = sizeof(*entry) + sizeof(unsigned long) * sys_data->nb_args; |
| 266 | 316 | ||
| 267 | event = trace_current_buffer_lock_reserve(&buffer, | 317 | event = trace_current_buffer_lock_reserve(&buffer, |
| 268 | sys_data->enter_event->id, size, 0, 0); | 318 | sys_data->enter_event->event.type, size, 0, 0); |
| 269 | if (!event) | 319 | if (!event) |
| 270 | return; | 320 | return; |
| 271 | 321 | ||
| @@ -278,7 +328,7 @@ void ftrace_syscall_enter(struct pt_regs *regs, long id) | |||
| 278 | trace_current_buffer_unlock_commit(buffer, event, 0, 0); | 328 | trace_current_buffer_unlock_commit(buffer, event, 0, 0); |
| 279 | } | 329 | } |
| 280 | 330 | ||
| 281 | void ftrace_syscall_exit(struct pt_regs *regs, long ret) | 331 | void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret) |
| 282 | { | 332 | { |
| 283 | struct syscall_trace_exit *entry; | 333 | struct syscall_trace_exit *entry; |
| 284 | struct syscall_metadata *sys_data; | 334 | struct syscall_metadata *sys_data; |
| @@ -297,7 +347,7 @@ void ftrace_syscall_exit(struct pt_regs *regs, long ret) | |||
| 297 | return; | 347 | return; |
| 298 | 348 | ||
| 299 | event = trace_current_buffer_lock_reserve(&buffer, | 349 | event = trace_current_buffer_lock_reserve(&buffer, |
| 300 | sys_data->exit_event->id, sizeof(*entry), 0, 0); | 350 | sys_data->exit_event->event.type, sizeof(*entry), 0, 0); |
| 301 | if (!event) | 351 | if (!event) |
| 302 | return; | 352 | return; |
| 303 | 353 | ||
| @@ -320,7 +370,7 @@ int reg_event_syscall_enter(struct ftrace_event_call *call) | |||
| 320 | return -ENOSYS; | 370 | return -ENOSYS; |
| 321 | mutex_lock(&syscall_trace_lock); | 371 | mutex_lock(&syscall_trace_lock); |
| 322 | if (!sys_refcount_enter) | 372 | if (!sys_refcount_enter) |
| 323 | ret = register_trace_sys_enter(ftrace_syscall_enter); | 373 | ret = register_trace_sys_enter(ftrace_syscall_enter, NULL); |
| 324 | if (!ret) { | 374 | if (!ret) { |
| 325 | set_bit(num, enabled_enter_syscalls); | 375 | set_bit(num, enabled_enter_syscalls); |
| 326 | sys_refcount_enter++; | 376 | sys_refcount_enter++; |
| @@ -340,7 +390,7 @@ void unreg_event_syscall_enter(struct ftrace_event_call *call) | |||
| 340 | sys_refcount_enter--; | 390 | sys_refcount_enter--; |
| 341 | clear_bit(num, enabled_enter_syscalls); | 391 | clear_bit(num, enabled_enter_syscalls); |
| 342 | if (!sys_refcount_enter) | 392 | if (!sys_refcount_enter) |
| 343 | unregister_trace_sys_enter(ftrace_syscall_enter); | 393 | unregister_trace_sys_enter(ftrace_syscall_enter, NULL); |
| 344 | mutex_unlock(&syscall_trace_lock); | 394 | mutex_unlock(&syscall_trace_lock); |
| 345 | } | 395 | } |
| 346 | 396 | ||
| @@ -354,7 +404,7 @@ int reg_event_syscall_exit(struct ftrace_event_call *call) | |||
| 354 | return -ENOSYS; | 404 | return -ENOSYS; |
| 355 | mutex_lock(&syscall_trace_lock); | 405 | mutex_lock(&syscall_trace_lock); |
| 356 | if (!sys_refcount_exit) | 406 | if (!sys_refcount_exit) |
| 357 | ret = register_trace_sys_exit(ftrace_syscall_exit); | 407 | ret = register_trace_sys_exit(ftrace_syscall_exit, NULL); |
| 358 | if (!ret) { | 408 | if (!ret) { |
| 359 | set_bit(num, enabled_exit_syscalls); | 409 | set_bit(num, enabled_exit_syscalls); |
| 360 | sys_refcount_exit++; | 410 | sys_refcount_exit++; |
| @@ -374,7 +424,7 @@ void unreg_event_syscall_exit(struct ftrace_event_call *call) | |||
| 374 | sys_refcount_exit--; | 424 | sys_refcount_exit--; |
| 375 | clear_bit(num, enabled_exit_syscalls); | 425 | clear_bit(num, enabled_exit_syscalls); |
| 376 | if (!sys_refcount_exit) | 426 | if (!sys_refcount_exit) |
| 377 | unregister_trace_sys_exit(ftrace_syscall_exit); | 427 | unregister_trace_sys_exit(ftrace_syscall_exit, NULL); |
| 378 | mutex_unlock(&syscall_trace_lock); | 428 | mutex_unlock(&syscall_trace_lock); |
| 379 | } | 429 | } |
| 380 | 430 | ||
| @@ -434,7 +484,7 @@ static DECLARE_BITMAP(enabled_perf_exit_syscalls, NR_syscalls); | |||
| 434 | static int sys_perf_refcount_enter; | 484 | static int sys_perf_refcount_enter; |
| 435 | static int sys_perf_refcount_exit; | 485 | static int sys_perf_refcount_exit; |
| 436 | 486 | ||
| 437 | static void perf_syscall_enter(struct pt_regs *regs, long id) | 487 | static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) |
| 438 | { | 488 | { |
| 439 | struct syscall_metadata *sys_data; | 489 | struct syscall_metadata *sys_data; |
| 440 | struct syscall_trace_enter *rec; | 490 | struct syscall_trace_enter *rec; |
| @@ -461,7 +511,7 @@ static void perf_syscall_enter(struct pt_regs *regs, long id) | |||
| 461 | return; | 511 | return; |
| 462 | 512 | ||
| 463 | rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size, | 513 | rec = (struct syscall_trace_enter *)perf_trace_buf_prepare(size, |
| 464 | sys_data->enter_event->id, regs, &rctx); | 514 | sys_data->enter_event->event.type, regs, &rctx); |
| 465 | if (!rec) | 515 | if (!rec) |
| 466 | return; | 516 | return; |
| 467 | 517 | ||
| @@ -482,7 +532,7 @@ int perf_sysenter_enable(struct ftrace_event_call *call) | |||
| 482 | 532 | ||
| 483 | mutex_lock(&syscall_trace_lock); | 533 | mutex_lock(&syscall_trace_lock); |
| 484 | if (!sys_perf_refcount_enter) | 534 | if (!sys_perf_refcount_enter) |
| 485 | ret = register_trace_sys_enter(perf_syscall_enter); | 535 | ret = register_trace_sys_enter(perf_syscall_enter, NULL); |
| 486 | if (ret) { | 536 | if (ret) { |
| 487 | pr_info("event trace: Could not activate" | 537 | pr_info("event trace: Could not activate" |
| 488 | "syscall entry trace point"); | 538 | "syscall entry trace point"); |
| @@ -504,11 +554,11 @@ void perf_sysenter_disable(struct ftrace_event_call *call) | |||
| 504 | sys_perf_refcount_enter--; | 554 | sys_perf_refcount_enter--; |
| 505 | clear_bit(num, enabled_perf_enter_syscalls); | 555 | clear_bit(num, enabled_perf_enter_syscalls); |
| 506 | if (!sys_perf_refcount_enter) | 556 | if (!sys_perf_refcount_enter) |
| 507 | unregister_trace_sys_enter(perf_syscall_enter); | 557 | unregister_trace_sys_enter(perf_syscall_enter, NULL); |
| 508 | mutex_unlock(&syscall_trace_lock); | 558 | mutex_unlock(&syscall_trace_lock); |
| 509 | } | 559 | } |
| 510 | 560 | ||
| 511 | static void perf_syscall_exit(struct pt_regs *regs, long ret) | 561 | static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) |
| 512 | { | 562 | { |
| 513 | struct syscall_metadata *sys_data; | 563 | struct syscall_metadata *sys_data; |
| 514 | struct syscall_trace_exit *rec; | 564 | struct syscall_trace_exit *rec; |
| @@ -538,7 +588,7 @@ static void perf_syscall_exit(struct pt_regs *regs, long ret) | |||
| 538 | return; | 588 | return; |
| 539 | 589 | ||
| 540 | rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size, | 590 | rec = (struct syscall_trace_exit *)perf_trace_buf_prepare(size, |
| 541 | sys_data->exit_event->id, regs, &rctx); | 591 | sys_data->exit_event->event.type, regs, &rctx); |
| 542 | if (!rec) | 592 | if (!rec) |
| 543 | return; | 593 | return; |
| 544 | 594 | ||
| @@ -558,7 +608,7 @@ int perf_sysexit_enable(struct ftrace_event_call *call) | |||
| 558 | 608 | ||
| 559 | mutex_lock(&syscall_trace_lock); | 609 | mutex_lock(&syscall_trace_lock); |
| 560 | if (!sys_perf_refcount_exit) | 610 | if (!sys_perf_refcount_exit) |
| 561 | ret = register_trace_sys_exit(perf_syscall_exit); | 611 | ret = register_trace_sys_exit(perf_syscall_exit, NULL); |
| 562 | if (ret) { | 612 | if (ret) { |
| 563 | pr_info("event trace: Could not activate" | 613 | pr_info("event trace: Could not activate" |
| 564 | "syscall exit trace point"); | 614 | "syscall exit trace point"); |
| @@ -580,9 +630,50 @@ void perf_sysexit_disable(struct ftrace_event_call *call) | |||
| 580 | sys_perf_refcount_exit--; | 630 | sys_perf_refcount_exit--; |
| 581 | clear_bit(num, enabled_perf_exit_syscalls); | 631 | clear_bit(num, enabled_perf_exit_syscalls); |
| 582 | if (!sys_perf_refcount_exit) | 632 | if (!sys_perf_refcount_exit) |
| 583 | unregister_trace_sys_exit(perf_syscall_exit); | 633 | unregister_trace_sys_exit(perf_syscall_exit, NULL); |
| 584 | mutex_unlock(&syscall_trace_lock); | 634 | mutex_unlock(&syscall_trace_lock); |
| 585 | } | 635 | } |
| 586 | 636 | ||
| 587 | #endif /* CONFIG_PERF_EVENTS */ | 637 | #endif /* CONFIG_PERF_EVENTS */ |
| 588 | 638 | ||
| 639 | static int syscall_enter_register(struct ftrace_event_call *event, | ||
| 640 | enum trace_reg type) | ||
| 641 | { | ||
| 642 | switch (type) { | ||
| 643 | case TRACE_REG_REGISTER: | ||
| 644 | return reg_event_syscall_enter(event); | ||
| 645 | case TRACE_REG_UNREGISTER: | ||
| 646 | unreg_event_syscall_enter(event); | ||
| 647 | return 0; | ||
| 648 | |||
| 649 | #ifdef CONFIG_PERF_EVENTS | ||
| 650 | case TRACE_REG_PERF_REGISTER: | ||
| 651 | return perf_sysenter_enable(event); | ||
| 652 | case TRACE_REG_PERF_UNREGISTER: | ||
| 653 | perf_sysenter_disable(event); | ||
| 654 | return 0; | ||
| 655 | #endif | ||
| 656 | } | ||
| 657 | return 0; | ||
| 658 | } | ||
| 659 | |||
| 660 | static int syscall_exit_register(struct ftrace_event_call *event, | ||
| 661 | enum trace_reg type) | ||
| 662 | { | ||
| 663 | switch (type) { | ||
| 664 | case TRACE_REG_REGISTER: | ||
| 665 | return reg_event_syscall_exit(event); | ||
| 666 | case TRACE_REG_UNREGISTER: | ||
| 667 | unreg_event_syscall_exit(event); | ||
| 668 | return 0; | ||
| 669 | |||
| 670 | #ifdef CONFIG_PERF_EVENTS | ||
| 671 | case TRACE_REG_PERF_REGISTER: | ||
| 672 | return perf_sysexit_enable(event); | ||
| 673 | case TRACE_REG_PERF_UNREGISTER: | ||
| 674 | perf_sysexit_disable(event); | ||
| 675 | return 0; | ||
| 676 | #endif | ||
| 677 | } | ||
| 678 | return 0; | ||
| 679 | } | ||
diff --git a/kernel/trace/trace_workqueue.c b/kernel/trace/trace_workqueue.c index cc2d2faa7d9e..a7cc3793baf6 100644 --- a/kernel/trace/trace_workqueue.c +++ b/kernel/trace/trace_workqueue.c | |||
| @@ -49,7 +49,8 @@ static void cpu_workqueue_stat_free(struct kref *kref) | |||
| 49 | 49 | ||
| 50 | /* Insertion of a work */ | 50 | /* Insertion of a work */ |
| 51 | static void | 51 | static void |
| 52 | probe_workqueue_insertion(struct task_struct *wq_thread, | 52 | probe_workqueue_insertion(void *ignore, |
| 53 | struct task_struct *wq_thread, | ||
| 53 | struct work_struct *work) | 54 | struct work_struct *work) |
| 54 | { | 55 | { |
| 55 | int cpu = cpumask_first(&wq_thread->cpus_allowed); | 56 | int cpu = cpumask_first(&wq_thread->cpus_allowed); |
| @@ -70,7 +71,8 @@ found: | |||
| 70 | 71 | ||
| 71 | /* Execution of a work */ | 72 | /* Execution of a work */ |
| 72 | static void | 73 | static void |
| 73 | probe_workqueue_execution(struct task_struct *wq_thread, | 74 | probe_workqueue_execution(void *ignore, |
| 75 | struct task_struct *wq_thread, | ||
| 74 | struct work_struct *work) | 76 | struct work_struct *work) |
| 75 | { | 77 | { |
| 76 | int cpu = cpumask_first(&wq_thread->cpus_allowed); | 78 | int cpu = cpumask_first(&wq_thread->cpus_allowed); |
| @@ -90,7 +92,8 @@ found: | |||
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | /* Creation of a cpu workqueue thread */ | 94 | /* Creation of a cpu workqueue thread */ |
| 93 | static void probe_workqueue_creation(struct task_struct *wq_thread, int cpu) | 95 | static void probe_workqueue_creation(void *ignore, |
| 96 | struct task_struct *wq_thread, int cpu) | ||
| 94 | { | 97 | { |
| 95 | struct cpu_workqueue_stats *cws; | 98 | struct cpu_workqueue_stats *cws; |
| 96 | unsigned long flags; | 99 | unsigned long flags; |
| @@ -114,7 +117,8 @@ static void probe_workqueue_creation(struct task_struct *wq_thread, int cpu) | |||
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | /* Destruction of a cpu workqueue thread */ | 119 | /* Destruction of a cpu workqueue thread */ |
| 117 | static void probe_workqueue_destruction(struct task_struct *wq_thread) | 120 | static void |
| 121 | probe_workqueue_destruction(void *ignore, struct task_struct *wq_thread) | ||
| 118 | { | 122 | { |
| 119 | /* Workqueue only execute on one cpu */ | 123 | /* Workqueue only execute on one cpu */ |
| 120 | int cpu = cpumask_first(&wq_thread->cpus_allowed); | 124 | int cpu = cpumask_first(&wq_thread->cpus_allowed); |
| @@ -259,19 +263,19 @@ int __init trace_workqueue_early_init(void) | |||
| 259 | { | 263 | { |
| 260 | int ret, cpu; | 264 | int ret, cpu; |
| 261 | 265 | ||
| 262 | ret = register_trace_workqueue_insertion(probe_workqueue_insertion); | 266 | ret = register_trace_workqueue_insertion(probe_workqueue_insertion, NULL); |
| 263 | if (ret) | 267 | if (ret) |
| 264 | goto out; | 268 | goto out; |
| 265 | 269 | ||
| 266 | ret = register_trace_workqueue_execution(probe_workqueue_execution); | 270 | ret = register_trace_workqueue_execution(probe_workqueue_execution, NULL); |
| 267 | if (ret) | 271 | if (ret) |
| 268 | goto no_insertion; | 272 | goto no_insertion; |
| 269 | 273 | ||
| 270 | ret = register_trace_workqueue_creation(probe_workqueue_creation); | 274 | ret = register_trace_workqueue_creation(probe_workqueue_creation, NULL); |
| 271 | if (ret) | 275 | if (ret) |
| 272 | goto no_execution; | 276 | goto no_execution; |
| 273 | 277 | ||
| 274 | ret = register_trace_workqueue_destruction(probe_workqueue_destruction); | 278 | ret = register_trace_workqueue_destruction(probe_workqueue_destruction, NULL); |
| 275 | if (ret) | 279 | if (ret) |
| 276 | goto no_creation; | 280 | goto no_creation; |
| 277 | 281 | ||
| @@ -283,11 +287,11 @@ int __init trace_workqueue_early_init(void) | |||
| 283 | return 0; | 287 | return 0; |
| 284 | 288 | ||
| 285 | no_creation: | 289 | no_creation: |
| 286 | unregister_trace_workqueue_creation(probe_workqueue_creation); | 290 | unregister_trace_workqueue_creation(probe_workqueue_creation, NULL); |
| 287 | no_execution: | 291 | no_execution: |
| 288 | unregister_trace_workqueue_execution(probe_workqueue_execution); | 292 | unregister_trace_workqueue_execution(probe_workqueue_execution, NULL); |
| 289 | no_insertion: | 293 | no_insertion: |
| 290 | unregister_trace_workqueue_insertion(probe_workqueue_insertion); | 294 | unregister_trace_workqueue_insertion(probe_workqueue_insertion, NULL); |
| 291 | out: | 295 | out: |
| 292 | pr_warning("trace_workqueue: unable to trace workqueues\n"); | 296 | pr_warning("trace_workqueue: unable to trace workqueues\n"); |
| 293 | 297 | ||
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index cc89be5bc0f8..c77f3eceea25 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -54,7 +54,7 @@ static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; | |||
| 54 | */ | 54 | */ |
| 55 | struct tracepoint_entry { | 55 | struct tracepoint_entry { |
| 56 | struct hlist_node hlist; | 56 | struct hlist_node hlist; |
| 57 | void **funcs; | 57 | struct tracepoint_func *funcs; |
| 58 | int refcount; /* Number of times armed. 0 if disarmed. */ | 58 | int refcount; /* Number of times armed. 0 if disarmed. */ |
| 59 | char name[0]; | 59 | char name[0]; |
| 60 | }; | 60 | }; |
| @@ -64,12 +64,12 @@ struct tp_probes { | |||
| 64 | struct rcu_head rcu; | 64 | struct rcu_head rcu; |
| 65 | struct list_head list; | 65 | struct list_head list; |
| 66 | } u; | 66 | } u; |
| 67 | void *probes[0]; | 67 | struct tracepoint_func probes[0]; |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | static inline void *allocate_probes(int count) | 70 | static inline void *allocate_probes(int count) |
| 71 | { | 71 | { |
| 72 | struct tp_probes *p = kmalloc(count * sizeof(void *) | 72 | struct tp_probes *p = kmalloc(count * sizeof(struct tracepoint_func) |
| 73 | + sizeof(struct tp_probes), GFP_KERNEL); | 73 | + sizeof(struct tp_probes), GFP_KERNEL); |
| 74 | return p == NULL ? NULL : p->probes; | 74 | return p == NULL ? NULL : p->probes; |
| 75 | } | 75 | } |
| @@ -79,7 +79,7 @@ static void rcu_free_old_probes(struct rcu_head *head) | |||
| 79 | kfree(container_of(head, struct tp_probes, u.rcu)); | 79 | kfree(container_of(head, struct tp_probes, u.rcu)); |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static inline void release_probes(void *old) | 82 | static inline void release_probes(struct tracepoint_func *old) |
| 83 | { | 83 | { |
| 84 | if (old) { | 84 | if (old) { |
| 85 | struct tp_probes *tp_probes = container_of(old, | 85 | struct tp_probes *tp_probes = container_of(old, |
| @@ -95,15 +95,16 @@ static void debug_print_probes(struct tracepoint_entry *entry) | |||
| 95 | if (!tracepoint_debug || !entry->funcs) | 95 | if (!tracepoint_debug || !entry->funcs) |
| 96 | return; | 96 | return; |
| 97 | 97 | ||
| 98 | for (i = 0; entry->funcs[i]; i++) | 98 | for (i = 0; entry->funcs[i].func; i++) |
| 99 | printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]); | 99 | printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i].func); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | static void * | 102 | static struct tracepoint_func * |
| 103 | tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe) | 103 | tracepoint_entry_add_probe(struct tracepoint_entry *entry, |
| 104 | void *probe, void *data) | ||
| 104 | { | 105 | { |
| 105 | int nr_probes = 0; | 106 | int nr_probes = 0; |
| 106 | void **old, **new; | 107 | struct tracepoint_func *old, *new; |
| 107 | 108 | ||
| 108 | WARN_ON(!probe); | 109 | WARN_ON(!probe); |
| 109 | 110 | ||
| @@ -111,8 +112,9 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe) | |||
| 111 | old = entry->funcs; | 112 | old = entry->funcs; |
| 112 | if (old) { | 113 | if (old) { |
| 113 | /* (N -> N+1), (N != 0, 1) probes */ | 114 | /* (N -> N+1), (N != 0, 1) probes */ |
| 114 | for (nr_probes = 0; old[nr_probes]; nr_probes++) | 115 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) |
| 115 | if (old[nr_probes] == probe) | 116 | if (old[nr_probes].func == probe && |
| 117 | old[nr_probes].data == data) | ||
| 116 | return ERR_PTR(-EEXIST); | 118 | return ERR_PTR(-EEXIST); |
| 117 | } | 119 | } |
| 118 | /* + 2 : one for new probe, one for NULL func */ | 120 | /* + 2 : one for new probe, one for NULL func */ |
| @@ -120,9 +122,10 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe) | |||
| 120 | if (new == NULL) | 122 | if (new == NULL) |
| 121 | return ERR_PTR(-ENOMEM); | 123 | return ERR_PTR(-ENOMEM); |
| 122 | if (old) | 124 | if (old) |
| 123 | memcpy(new, old, nr_probes * sizeof(void *)); | 125 | memcpy(new, old, nr_probes * sizeof(struct tracepoint_func)); |
| 124 | new[nr_probes] = probe; | 126 | new[nr_probes].func = probe; |
| 125 | new[nr_probes + 1] = NULL; | 127 | new[nr_probes].data = data; |
| 128 | new[nr_probes + 1].func = NULL; | ||
| 126 | entry->refcount = nr_probes + 1; | 129 | entry->refcount = nr_probes + 1; |
| 127 | entry->funcs = new; | 130 | entry->funcs = new; |
| 128 | debug_print_probes(entry); | 131 | debug_print_probes(entry); |
| @@ -130,10 +133,11 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe) | |||
| 130 | } | 133 | } |
| 131 | 134 | ||
| 132 | static void * | 135 | static void * |
| 133 | tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe) | 136 | tracepoint_entry_remove_probe(struct tracepoint_entry *entry, |
| 137 | void *probe, void *data) | ||
| 134 | { | 138 | { |
| 135 | int nr_probes = 0, nr_del = 0, i; | 139 | int nr_probes = 0, nr_del = 0, i; |
| 136 | void **old, **new; | 140 | struct tracepoint_func *old, *new; |
| 137 | 141 | ||
| 138 | old = entry->funcs; | 142 | old = entry->funcs; |
| 139 | 143 | ||
| @@ -142,8 +146,10 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe) | |||
| 142 | 146 | ||
| 143 | debug_print_probes(entry); | 147 | debug_print_probes(entry); |
| 144 | /* (N -> M), (N > 1, M >= 0) probes */ | 148 | /* (N -> M), (N > 1, M >= 0) probes */ |
| 145 | for (nr_probes = 0; old[nr_probes]; nr_probes++) { | 149 | for (nr_probes = 0; old[nr_probes].func; nr_probes++) { |
| 146 | if ((!probe || old[nr_probes] == probe)) | 150 | if (!probe || |
| 151 | (old[nr_probes].func == probe && | ||
| 152 | old[nr_probes].data == data)) | ||
| 147 | nr_del++; | 153 | nr_del++; |
| 148 | } | 154 | } |
| 149 | 155 | ||
| @@ -160,10 +166,11 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe) | |||
| 160 | new = allocate_probes(nr_probes - nr_del + 1); | 166 | new = allocate_probes(nr_probes - nr_del + 1); |
| 161 | if (new == NULL) | 167 | if (new == NULL) |
| 162 | return ERR_PTR(-ENOMEM); | 168 | return ERR_PTR(-ENOMEM); |
| 163 | for (i = 0; old[i]; i++) | 169 | for (i = 0; old[i].func; i++) |
| 164 | if ((probe && old[i] != probe)) | 170 | if (probe && |
| 171 | (old[i].func != probe || old[i].data != data)) | ||
| 165 | new[j++] = old[i]; | 172 | new[j++] = old[i]; |
| 166 | new[nr_probes - nr_del] = NULL; | 173 | new[nr_probes - nr_del].func = NULL; |
| 167 | entry->refcount = nr_probes - nr_del; | 174 | entry->refcount = nr_probes - nr_del; |
| 168 | entry->funcs = new; | 175 | entry->funcs = new; |
| 169 | } | 176 | } |
| @@ -315,18 +322,19 @@ static void tracepoint_update_probes(void) | |||
| 315 | module_update_tracepoints(); | 322 | module_update_tracepoints(); |
| 316 | } | 323 | } |
| 317 | 324 | ||
| 318 | static void *tracepoint_add_probe(const char *name, void *probe) | 325 | static struct tracepoint_func * |
| 326 | tracepoint_add_probe(const char *name, void *probe, void *data) | ||
| 319 | { | 327 | { |
| 320 | struct tracepoint_entry *entry; | 328 | struct tracepoint_entry *entry; |
| 321 | void *old; | 329 | struct tracepoint_func *old; |
| 322 | 330 | ||
| 323 | entry = get_tracepoint(name); | 331 | entry = get_tracepoint(name); |
| 324 | if (!entry) { | 332 | if (!entry) { |
| 325 | entry = add_tracepoint(name); | 333 | entry = add_tracepoint(name); |
| 326 | if (IS_ERR(entry)) | 334 | if (IS_ERR(entry)) |
| 327 | return entry; | 335 | return (struct tracepoint_func *)entry; |
| 328 | } | 336 | } |
| 329 | old = tracepoint_entry_add_probe(entry, probe); | 337 | old = tracepoint_entry_add_probe(entry, probe, data); |
| 330 | if (IS_ERR(old) && !entry->refcount) | 338 | if (IS_ERR(old) && !entry->refcount) |
| 331 | remove_tracepoint(entry); | 339 | remove_tracepoint(entry); |
| 332 | return old; | 340 | return old; |
| @@ -340,12 +348,12 @@ static void *tracepoint_add_probe(const char *name, void *probe) | |||
| 340 | * Returns 0 if ok, error value on error. | 348 | * Returns 0 if ok, error value on error. |
| 341 | * The probe address must at least be aligned on the architecture pointer size. | 349 | * The probe address must at least be aligned on the architecture pointer size. |
| 342 | */ | 350 | */ |
| 343 | int tracepoint_probe_register(const char *name, void *probe) | 351 | int tracepoint_probe_register(const char *name, void *probe, void *data) |
| 344 | { | 352 | { |
| 345 | void *old; | 353 | struct tracepoint_func *old; |
| 346 | 354 | ||
| 347 | mutex_lock(&tracepoints_mutex); | 355 | mutex_lock(&tracepoints_mutex); |
| 348 | old = tracepoint_add_probe(name, probe); | 356 | old = tracepoint_add_probe(name, probe, data); |
| 349 | mutex_unlock(&tracepoints_mutex); | 357 | mutex_unlock(&tracepoints_mutex); |
| 350 | if (IS_ERR(old)) | 358 | if (IS_ERR(old)) |
| 351 | return PTR_ERR(old); | 359 | return PTR_ERR(old); |
| @@ -356,15 +364,16 @@ int tracepoint_probe_register(const char *name, void *probe) | |||
| 356 | } | 364 | } |
| 357 | EXPORT_SYMBOL_GPL(tracepoint_probe_register); | 365 | EXPORT_SYMBOL_GPL(tracepoint_probe_register); |
| 358 | 366 | ||
| 359 | static void *tracepoint_remove_probe(const char *name, void *probe) | 367 | static struct tracepoint_func * |
| 368 | tracepoint_remove_probe(const char *name, void *probe, void *data) | ||
| 360 | { | 369 | { |
| 361 | struct tracepoint_entry *entry; | 370 | struct tracepoint_entry *entry; |
| 362 | void *old; | 371 | struct tracepoint_func *old; |
| 363 | 372 | ||
| 364 | entry = get_tracepoint(name); | 373 | entry = get_tracepoint(name); |
| 365 | if (!entry) | 374 | if (!entry) |
| 366 | return ERR_PTR(-ENOENT); | 375 | return ERR_PTR(-ENOENT); |
| 367 | old = tracepoint_entry_remove_probe(entry, probe); | 376 | old = tracepoint_entry_remove_probe(entry, probe, data); |
| 368 | if (IS_ERR(old)) | 377 | if (IS_ERR(old)) |
| 369 | return old; | 378 | return old; |
| 370 | if (!entry->refcount) | 379 | if (!entry->refcount) |
| @@ -382,12 +391,12 @@ static void *tracepoint_remove_probe(const char *name, void *probe) | |||
| 382 | * itself uses stop_machine(), which insures that every preempt disabled section | 391 | * itself uses stop_machine(), which insures that every preempt disabled section |
| 383 | * have finished. | 392 | * have finished. |
| 384 | */ | 393 | */ |
| 385 | int tracepoint_probe_unregister(const char *name, void *probe) | 394 | int tracepoint_probe_unregister(const char *name, void *probe, void *data) |
| 386 | { | 395 | { |
| 387 | void *old; | 396 | struct tracepoint_func *old; |
| 388 | 397 | ||
| 389 | mutex_lock(&tracepoints_mutex); | 398 | mutex_lock(&tracepoints_mutex); |
| 390 | old = tracepoint_remove_probe(name, probe); | 399 | old = tracepoint_remove_probe(name, probe, data); |
| 391 | mutex_unlock(&tracepoints_mutex); | 400 | mutex_unlock(&tracepoints_mutex); |
| 392 | if (IS_ERR(old)) | 401 | if (IS_ERR(old)) |
| 393 | return PTR_ERR(old); | 402 | return PTR_ERR(old); |
| @@ -418,12 +427,13 @@ static void tracepoint_add_old_probes(void *old) | |||
| 418 | * | 427 | * |
| 419 | * caller must call tracepoint_probe_update_all() | 428 | * caller must call tracepoint_probe_update_all() |
| 420 | */ | 429 | */ |
| 421 | int tracepoint_probe_register_noupdate(const char *name, void *probe) | 430 | int tracepoint_probe_register_noupdate(const char *name, void *probe, |
| 431 | void *data) | ||
| 422 | { | 432 | { |
| 423 | void *old; | 433 | struct tracepoint_func *old; |
| 424 | 434 | ||
| 425 | mutex_lock(&tracepoints_mutex); | 435 | mutex_lock(&tracepoints_mutex); |
| 426 | old = tracepoint_add_probe(name, probe); | 436 | old = tracepoint_add_probe(name, probe, data); |
| 427 | if (IS_ERR(old)) { | 437 | if (IS_ERR(old)) { |
| 428 | mutex_unlock(&tracepoints_mutex); | 438 | mutex_unlock(&tracepoints_mutex); |
| 429 | return PTR_ERR(old); | 439 | return PTR_ERR(old); |
| @@ -441,12 +451,13 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate); | |||
| 441 | * | 451 | * |
| 442 | * caller must call tracepoint_probe_update_all() | 452 | * caller must call tracepoint_probe_update_all() |
| 443 | */ | 453 | */ |
| 444 | int tracepoint_probe_unregister_noupdate(const char *name, void *probe) | 454 | int tracepoint_probe_unregister_noupdate(const char *name, void *probe, |
| 455 | void *data) | ||
| 445 | { | 456 | { |
| 446 | void *old; | 457 | struct tracepoint_func *old; |
| 447 | 458 | ||
| 448 | mutex_lock(&tracepoints_mutex); | 459 | mutex_lock(&tracepoints_mutex); |
| 449 | old = tracepoint_remove_probe(name, probe); | 460 | old = tracepoint_remove_probe(name, probe, data); |
| 450 | if (IS_ERR(old)) { | 461 | if (IS_ERR(old)) { |
| 451 | mutex_unlock(&tracepoints_mutex); | 462 | mutex_unlock(&tracepoints_mutex); |
| 452 | return PTR_ERR(old); | 463 | return PTR_ERR(old); |
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index cf208d8042b1..ad41529fb60f 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c | |||
| @@ -172,12 +172,12 @@ out: | |||
| 172 | return; | 172 | return; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | static void trace_kfree_skb_hit(struct sk_buff *skb, void *location) | 175 | static void trace_kfree_skb_hit(void *ignore, struct sk_buff *skb, void *location) |
| 176 | { | 176 | { |
| 177 | trace_drop_common(skb, location); | 177 | trace_drop_common(skb, location); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static void trace_napi_poll_hit(struct napi_struct *napi) | 180 | static void trace_napi_poll_hit(void *ignore, struct napi_struct *napi) |
| 181 | { | 181 | { |
| 182 | struct dm_hw_stat_delta *new_stat; | 182 | struct dm_hw_stat_delta *new_stat; |
| 183 | 183 | ||
| @@ -225,12 +225,12 @@ static int set_all_monitor_traces(int state) | |||
| 225 | 225 | ||
| 226 | switch (state) { | 226 | switch (state) { |
| 227 | case TRACE_ON: | 227 | case TRACE_ON: |
| 228 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit); | 228 | rc |= register_trace_kfree_skb(trace_kfree_skb_hit, NULL); |
| 229 | rc |= register_trace_napi_poll(trace_napi_poll_hit); | 229 | rc |= register_trace_napi_poll(trace_napi_poll_hit, NULL); |
| 230 | break; | 230 | break; |
| 231 | case TRACE_OFF: | 231 | case TRACE_OFF: |
| 232 | rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit); | 232 | rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit, NULL); |
| 233 | rc |= unregister_trace_napi_poll(trace_napi_poll_hit); | 233 | rc |= unregister_trace_napi_poll(trace_napi_poll_hit, NULL); |
| 234 | 234 | ||
| 235 | tracepoint_synchronize_unregister(); | 235 | tracepoint_synchronize_unregister(); |
| 236 | 236 | ||
diff --git a/samples/tracepoints/tp-samples-trace.h b/samples/tracepoints/tp-samples-trace.h index dffdc49878af..4d46be965961 100644 --- a/samples/tracepoints/tp-samples-trace.h +++ b/samples/tracepoints/tp-samples-trace.h | |||
| @@ -7,7 +7,5 @@ | |||
| 7 | DECLARE_TRACE(subsys_event, | 7 | DECLARE_TRACE(subsys_event, |
| 8 | TP_PROTO(struct inode *inode, struct file *file), | 8 | TP_PROTO(struct inode *inode, struct file *file), |
| 9 | TP_ARGS(inode, file)); | 9 | TP_ARGS(inode, file)); |
| 10 | DECLARE_TRACE(subsys_eventb, | 10 | DECLARE_TRACE_NOARGS(subsys_eventb); |
| 11 | TP_PROTO(void), | ||
| 12 | TP_ARGS()); | ||
| 13 | #endif | 11 | #endif |
diff --git a/samples/tracepoints/tracepoint-probe-sample.c b/samples/tracepoints/tracepoint-probe-sample.c index 9e60eb6ca2d8..744c0b9652a7 100644 --- a/samples/tracepoints/tracepoint-probe-sample.c +++ b/samples/tracepoints/tracepoint-probe-sample.c | |||
| @@ -13,7 +13,8 @@ | |||
| 13 | * Here the caller only guarantees locking for struct file and struct inode. | 13 | * Here the caller only guarantees locking for struct file and struct inode. |
| 14 | * Locking must therefore be done in the probe to use the dentry. | 14 | * Locking must therefore be done in the probe to use the dentry. |
| 15 | */ | 15 | */ |
| 16 | static void probe_subsys_event(struct inode *inode, struct file *file) | 16 | static void probe_subsys_event(void *ignore, |
| 17 | struct inode *inode, struct file *file) | ||
| 17 | { | 18 | { |
| 18 | path_get(&file->f_path); | 19 | path_get(&file->f_path); |
| 19 | dget(file->f_path.dentry); | 20 | dget(file->f_path.dentry); |
| @@ -23,7 +24,7 @@ static void probe_subsys_event(struct inode *inode, struct file *file) | |||
| 23 | path_put(&file->f_path); | 24 | path_put(&file->f_path); |
| 24 | } | 25 | } |
| 25 | 26 | ||
| 26 | static void probe_subsys_eventb(void) | 27 | static void probe_subsys_eventb(void *ignore) |
| 27 | { | 28 | { |
| 28 | printk(KERN_INFO "Event B is encountered\n"); | 29 | printk(KERN_INFO "Event B is encountered\n"); |
| 29 | } | 30 | } |
| @@ -32,9 +33,9 @@ static int __init tp_sample_trace_init(void) | |||
| 32 | { | 33 | { |
| 33 | int ret; | 34 | int ret; |
| 34 | 35 | ||
| 35 | ret = register_trace_subsys_event(probe_subsys_event); | 36 | ret = register_trace_subsys_event(probe_subsys_event, NULL); |
| 36 | WARN_ON(ret); | 37 | WARN_ON(ret); |
| 37 | ret = register_trace_subsys_eventb(probe_subsys_eventb); | 38 | ret = register_trace_subsys_eventb(probe_subsys_eventb, NULL); |
| 38 | WARN_ON(ret); | 39 | WARN_ON(ret); |
| 39 | 40 | ||
| 40 | return 0; | 41 | return 0; |
| @@ -44,8 +45,8 @@ module_init(tp_sample_trace_init); | |||
| 44 | 45 | ||
| 45 | static void __exit tp_sample_trace_exit(void) | 46 | static void __exit tp_sample_trace_exit(void) |
| 46 | { | 47 | { |
| 47 | unregister_trace_subsys_eventb(probe_subsys_eventb); | 48 | unregister_trace_subsys_eventb(probe_subsys_eventb, NULL); |
| 48 | unregister_trace_subsys_event(probe_subsys_event); | 49 | unregister_trace_subsys_event(probe_subsys_event, NULL); |
| 49 | tracepoint_synchronize_unregister(); | 50 | tracepoint_synchronize_unregister(); |
| 50 | } | 51 | } |
| 51 | 52 | ||
diff --git a/samples/tracepoints/tracepoint-probe-sample2.c b/samples/tracepoints/tracepoint-probe-sample2.c index be2a960573f1..9fcf990e5d4b 100644 --- a/samples/tracepoints/tracepoint-probe-sample2.c +++ b/samples/tracepoints/tracepoint-probe-sample2.c | |||
| @@ -12,7 +12,8 @@ | |||
| 12 | * Here the caller only guarantees locking for struct file and struct inode. | 12 | * Here the caller only guarantees locking for struct file and struct inode. |
| 13 | * Locking must therefore be done in the probe to use the dentry. | 13 | * Locking must therefore be done in the probe to use the dentry. |
| 14 | */ | 14 | */ |
| 15 | static void probe_subsys_event(struct inode *inode, struct file *file) | 15 | static void probe_subsys_event(void *ignore, |
| 16 | struct inode *inode, struct file *file) | ||
| 16 | { | 17 | { |
| 17 | printk(KERN_INFO "Event is encountered with inode number %lu\n", | 18 | printk(KERN_INFO "Event is encountered with inode number %lu\n", |
| 18 | inode->i_ino); | 19 | inode->i_ino); |
| @@ -22,7 +23,7 @@ static int __init tp_sample_trace_init(void) | |||
| 22 | { | 23 | { |
| 23 | int ret; | 24 | int ret; |
| 24 | 25 | ||
| 25 | ret = register_trace_subsys_event(probe_subsys_event); | 26 | ret = register_trace_subsys_event(probe_subsys_event, NULL); |
| 26 | WARN_ON(ret); | 27 | WARN_ON(ret); |
| 27 | 28 | ||
| 28 | return 0; | 29 | return 0; |
| @@ -32,7 +33,7 @@ module_init(tp_sample_trace_init); | |||
| 32 | 33 | ||
| 33 | static void __exit tp_sample_trace_exit(void) | 34 | static void __exit tp_sample_trace_exit(void) |
| 34 | { | 35 | { |
| 35 | unregister_trace_subsys_event(probe_subsys_event); | 36 | unregister_trace_subsys_event(probe_subsys_event, NULL); |
| 36 | tracepoint_synchronize_unregister(); | 37 | tracepoint_synchronize_unregister(); |
| 37 | } | 38 | } |
| 38 | 39 | ||
