diff options
| author | Jason Baron <jbaron@redhat.com> | 2010-09-17 11:09:13 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-09-22 16:31:01 -0400 |
| commit | 8f7b50c514206211cc282a4247f7b12f18dee674 (patch) | |
| tree | 8d69af92e9ba46f8f775a300ba863040c817e77c | |
| parent | 4c3ef6d79328c0e23ade60cbfc8d496123a6855c (diff) | |
jump label: Tracepoint support for jump labels
Make use of the jump label infrastructure for tracepoints.
Signed-off-by: Jason Baron <jbaron@redhat.com>
LKML-Reference: <a9ba2056e2c9cf332c3c300b577463ce66ff23a8.1284733808.git.jbaron@redhat.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | include/linux/tracepoint.h | 5 | ||||
| -rw-r--r-- | kernel/tracepoint.c | 14 |
2 files changed, 16 insertions, 3 deletions
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 103d1b61aacb..a4a90b6726ce 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h | |||
| @@ -17,6 +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/jump_label.h> | ||
| 20 | 21 | ||
| 21 | struct module; | 22 | struct module; |
| 22 | struct tracepoint; | 23 | struct tracepoint; |
| @@ -145,7 +146,9 @@ static inline void tracepoint_update_probe_range(struct tracepoint *begin, | |||
| 145 | extern struct tracepoint __tracepoint_##name; \ | 146 | extern struct tracepoint __tracepoint_##name; \ |
| 146 | static inline void trace_##name(proto) \ | 147 | static inline void trace_##name(proto) \ |
| 147 | { \ | 148 | { \ |
| 148 | if (unlikely(__tracepoint_##name.state)) \ | 149 | JUMP_LABEL(&__tracepoint_##name.state, do_trace); \ |
| 150 | return; \ | ||
| 151 | do_trace: \ | ||
| 149 | __DO_TRACE(&__tracepoint_##name, \ | 152 | __DO_TRACE(&__tracepoint_##name, \ |
| 150 | TP_PROTO(data_proto), \ | 153 | TP_PROTO(data_proto), \ |
| 151 | TP_ARGS(data_args)); \ | 154 | TP_ARGS(data_args)); \ |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index c77f3eceea25..d6073a50a6ca 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 28 | #include <linux/jump_label.h> | ||
| 28 | 29 | ||
| 29 | extern struct tracepoint __start___tracepoints[]; | 30 | extern struct tracepoint __start___tracepoints[]; |
| 30 | extern struct tracepoint __stop___tracepoints[]; | 31 | extern struct tracepoint __stop___tracepoints[]; |
| @@ -263,7 +264,13 @@ static void set_tracepoint(struct tracepoint_entry **entry, | |||
| 263 | * is used. | 264 | * is used. |
| 264 | */ | 265 | */ |
| 265 | rcu_assign_pointer(elem->funcs, (*entry)->funcs); | 266 | rcu_assign_pointer(elem->funcs, (*entry)->funcs); |
| 266 | elem->state = active; | 267 | if (!elem->state && active) { |
| 268 | enable_jump_label(&elem->state); | ||
| 269 | elem->state = active; | ||
| 270 | } else if (elem->state && !active) { | ||
| 271 | disable_jump_label(&elem->state); | ||
| 272 | elem->state = active; | ||
| 273 | } | ||
| 267 | } | 274 | } |
| 268 | 275 | ||
| 269 | /* | 276 | /* |
| @@ -277,7 +284,10 @@ static void disable_tracepoint(struct tracepoint *elem) | |||
| 277 | if (elem->unregfunc && elem->state) | 284 | if (elem->unregfunc && elem->state) |
| 278 | elem->unregfunc(); | 285 | elem->unregfunc(); |
| 279 | 286 | ||
| 280 | elem->state = 0; | 287 | if (elem->state) { |
| 288 | disable_jump_label(&elem->state); | ||
| 289 | elem->state = 0; | ||
| 290 | } | ||
| 281 | rcu_assign_pointer(elem->funcs, NULL); | 291 | rcu_assign_pointer(elem->funcs, NULL); |
| 282 | } | 292 | } |
| 283 | 293 | ||
