diff options
Diffstat (limited to 'include/linux/tracepoint.h')
-rw-r--r-- | include/linux/tracepoint.h | 63 |
1 files changed, 22 insertions, 41 deletions
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 2f322c38bd4..d530a4460a0 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <linux/rcupdate.h> | 19 | #include <linux/rcupdate.h> |
20 | #include <linux/static_key.h> | 20 | #include <linux/jump_label.h> |
21 | 21 | ||
22 | struct module; | 22 | struct module; |
23 | struct tracepoint; | 23 | struct tracepoint; |
@@ -29,7 +29,7 @@ struct tracepoint_func { | |||
29 | 29 | ||
30 | struct tracepoint { | 30 | struct tracepoint { |
31 | const char *name; /* Tracepoint name */ | 31 | const char *name; /* Tracepoint name */ |
32 | struct static_key key; | 32 | struct jump_label_key key; |
33 | void (*regfunc)(void); | 33 | void (*regfunc)(void); |
34 | void (*unregfunc)(void); | 34 | void (*unregfunc)(void); |
35 | struct tracepoint_func __rcu *funcs; | 35 | struct tracepoint_func __rcu *funcs; |
@@ -54,18 +54,8 @@ extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe, | |||
54 | void *data); | 54 | void *data); |
55 | extern void tracepoint_probe_update_all(void); | 55 | extern void tracepoint_probe_update_all(void); |
56 | 56 | ||
57 | #ifdef CONFIG_MODULES | ||
58 | struct tp_module { | ||
59 | struct list_head list; | ||
60 | unsigned int num_tracepoints; | ||
61 | struct tracepoint * const *tracepoints_ptrs; | ||
62 | }; | ||
63 | #endif /* CONFIG_MODULES */ | ||
64 | |||
65 | struct tracepoint_iter { | 57 | struct tracepoint_iter { |
66 | #ifdef CONFIG_MODULES | 58 | struct module *module; |
67 | struct tp_module *module; | ||
68 | #endif /* CONFIG_MODULES */ | ||
69 | struct tracepoint * const *tracepoint; | 59 | struct tracepoint * const *tracepoint; |
70 | }; | 60 | }; |
71 | 61 | ||
@@ -73,6 +63,8 @@ extern void tracepoint_iter_start(struct tracepoint_iter *iter); | |||
73 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); | 63 | extern void tracepoint_iter_next(struct tracepoint_iter *iter); |
74 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); | 64 | extern void tracepoint_iter_stop(struct tracepoint_iter *iter); |
75 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); | 65 | extern void tracepoint_iter_reset(struct tracepoint_iter *iter); |
66 | extern int tracepoint_get_iter_range(struct tracepoint * const **tracepoint, | ||
67 | struct tracepoint * const *begin, struct tracepoint * const *end); | ||
76 | 68 | ||
77 | /* | 69 | /* |
78 | * tracepoint_synchronize_unregister must be called between the last tracepoint | 70 | * tracepoint_synchronize_unregister must be called between the last tracepoint |
@@ -86,6 +78,17 @@ static inline void tracepoint_synchronize_unregister(void) | |||
86 | 78 | ||
87 | #define PARAMS(args...) args | 79 | #define PARAMS(args...) args |
88 | 80 | ||
81 | #ifdef CONFIG_TRACEPOINTS | ||
82 | extern | ||
83 | void tracepoint_update_probe_range(struct tracepoint * const *begin, | ||
84 | struct tracepoint * const *end); | ||
85 | #else | ||
86 | static inline | ||
87 | void tracepoint_update_probe_range(struct tracepoint * const *begin, | ||
88 | struct tracepoint * const *end) | ||
89 | { } | ||
90 | #endif /* CONFIG_TRACEPOINTS */ | ||
91 | |||
89 | #endif /* _LINUX_TRACEPOINT_H */ | 92 | #endif /* _LINUX_TRACEPOINT_H */ |
90 | 93 | ||
91 | /* | 94 | /* |
@@ -114,7 +117,7 @@ static inline void tracepoint_synchronize_unregister(void) | |||
114 | * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just | 117 | * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just |
115 | * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto". | 118 | * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto". |
116 | */ | 119 | */ |
117 | #define __DO_TRACE(tp, proto, args, cond, prercu, postrcu) \ | 120 | #define __DO_TRACE(tp, proto, args, cond) \ |
118 | do { \ | 121 | do { \ |
119 | struct tracepoint_func *it_func_ptr; \ | 122 | struct tracepoint_func *it_func_ptr; \ |
120 | void *it_func; \ | 123 | void *it_func; \ |
@@ -122,7 +125,6 @@ static inline void tracepoint_synchronize_unregister(void) | |||
122 | \ | 125 | \ |
123 | if (!(cond)) \ | 126 | if (!(cond)) \ |
124 | return; \ | 127 | return; \ |
125 | prercu; \ | ||
126 | rcu_read_lock_sched_notrace(); \ | 128 | rcu_read_lock_sched_notrace(); \ |
127 | it_func_ptr = rcu_dereference_sched((tp)->funcs); \ | 129 | it_func_ptr = rcu_dereference_sched((tp)->funcs); \ |
128 | if (it_func_ptr) { \ | 130 | if (it_func_ptr) { \ |
@@ -133,42 +135,23 @@ static inline void tracepoint_synchronize_unregister(void) | |||
133 | } while ((++it_func_ptr)->func); \ | 135 | } while ((++it_func_ptr)->func); \ |
134 | } \ | 136 | } \ |
135 | rcu_read_unlock_sched_notrace(); \ | 137 | rcu_read_unlock_sched_notrace(); \ |
136 | postrcu; \ | ||
137 | } while (0) | 138 | } while (0) |
138 | 139 | ||
139 | #ifndef MODULE | ||
140 | #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) \ | ||
141 | static inline void trace_##name##_rcuidle(proto) \ | ||
142 | { \ | ||
143 | if (static_key_false(&__tracepoint_##name.key)) \ | ||
144 | __DO_TRACE(&__tracepoint_##name, \ | ||
145 | TP_PROTO(data_proto), \ | ||
146 | TP_ARGS(data_args), \ | ||
147 | TP_CONDITION(cond), \ | ||
148 | rcu_idle_exit(), \ | ||
149 | rcu_idle_enter()); \ | ||
150 | } | ||
151 | #else | ||
152 | #define __DECLARE_TRACE_RCU(name, proto, args, cond, data_proto, data_args) | ||
153 | #endif | ||
154 | |||
155 | /* | 140 | /* |
156 | * Make sure the alignment of the structure in the __tracepoints section will | 141 | * Make sure the alignment of the structure in the __tracepoints section will |
157 | * not add unwanted padding between the beginning of the section and the | 142 | * not add unwanted padding between the beginning of the section and the |
158 | * structure. Force alignment to the same alignment as the section start. | 143 | * structure. Force alignment to the same alignment as the section start. |
159 | */ | 144 | */ |
160 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ | 145 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ |
161 | extern struct tracepoint __tracepoint_##name; \ | 146 | extern struct tracepoint __tracepoint_##name; \ |
162 | static inline void trace_##name(proto) \ | 147 | static inline void trace_##name(proto) \ |
163 | { \ | 148 | { \ |
164 | if (static_key_false(&__tracepoint_##name.key)) \ | 149 | if (static_branch(&__tracepoint_##name.key)) \ |
165 | __DO_TRACE(&__tracepoint_##name, \ | 150 | __DO_TRACE(&__tracepoint_##name, \ |
166 | TP_PROTO(data_proto), \ | 151 | TP_PROTO(data_proto), \ |
167 | TP_ARGS(data_args), \ | 152 | TP_ARGS(data_args), \ |
168 | TP_CONDITION(cond),,); \ | 153 | TP_CONDITION(cond)); \ |
169 | } \ | 154 | } \ |
170 | __DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \ | ||
171 | PARAMS(cond), PARAMS(data_proto), PARAMS(data_args)) \ | ||
172 | static inline int \ | 155 | static inline int \ |
173 | register_trace_##name(void (*probe)(data_proto), void *data) \ | 156 | register_trace_##name(void (*probe)(data_proto), void *data) \ |
174 | { \ | 157 | { \ |
@@ -196,7 +179,7 @@ static inline void tracepoint_synchronize_unregister(void) | |||
196 | __attribute__((section("__tracepoints_strings"))) = #name; \ | 179 | __attribute__((section("__tracepoints_strings"))) = #name; \ |
197 | struct tracepoint __tracepoint_##name \ | 180 | struct tracepoint __tracepoint_##name \ |
198 | __attribute__((section("__tracepoints"))) = \ | 181 | __attribute__((section("__tracepoints"))) = \ |
199 | { __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\ | 182 | { __tpstrtab_##name, JUMP_LABEL_INIT, reg, unreg, NULL };\ |
200 | static struct tracepoint * const __tracepoint_ptr_##name __used \ | 183 | static struct tracepoint * const __tracepoint_ptr_##name __used \ |
201 | __attribute__((section("__tracepoints_ptrs"))) = \ | 184 | __attribute__((section("__tracepoints_ptrs"))) = \ |
202 | &__tracepoint_##name; | 185 | &__tracepoint_##name; |
@@ -210,11 +193,9 @@ static inline void tracepoint_synchronize_unregister(void) | |||
210 | EXPORT_SYMBOL(__tracepoint_##name) | 193 | EXPORT_SYMBOL(__tracepoint_##name) |
211 | 194 | ||
212 | #else /* !CONFIG_TRACEPOINTS */ | 195 | #else /* !CONFIG_TRACEPOINTS */ |
213 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ | 196 | #define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ |
214 | static inline void trace_##name(proto) \ | 197 | static inline void trace_##name(proto) \ |
215 | { } \ | 198 | { } \ |
216 | static inline void trace_##name##_rcuidle(proto) \ | ||
217 | { } \ | ||
218 | static inline int \ | 199 | static inline int \ |
219 | register_trace_##name(void (*probe)(data_proto), \ | 200 | register_trace_##name(void (*probe)(data_proto), \ |
220 | void *data) \ | 201 | void *data) \ |