aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/tracepoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/tracepoint.c')
-rw-r--r--kernel/tracepoint.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index c77f3eceea25..b219f1449c54 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -25,9 +25,10 @@
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
29extern struct tracepoint __start___tracepoints[]; 30extern struct tracepoint * const __start___tracepoints_ptrs[];
30extern struct tracepoint __stop___tracepoints[]; 31extern struct tracepoint * const __stop___tracepoints_ptrs[];
31 32
32/* Set to 1 to enable tracepoint debug output */ 33/* Set to 1 to enable tracepoint debug output */
33static const int tracepoint_debug; 34static const int tracepoint_debug;
@@ -250,9 +251,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,
250{ 251{
251 WARN_ON(strcmp((*entry)->name, elem->name) != 0); 252 WARN_ON(strcmp((*entry)->name, elem->name) != 0);
252 253
253 if (elem->regfunc && !elem->state && active) 254 if (elem->regfunc && !jump_label_enabled(&elem->key) && active)
254 elem->regfunc(); 255 elem->regfunc();
255 else if (elem->unregfunc && elem->state && !active) 256 else if (elem->unregfunc && jump_label_enabled(&elem->key) && !active)
256 elem->unregfunc(); 257 elem->unregfunc();
257 258
258 /* 259 /*
@@ -263,7 +264,10 @@ 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 (active && !jump_label_enabled(&elem->key))
268 jump_label_inc(&elem->key);
269 else if (!active && jump_label_enabled(&elem->key))
270 jump_label_dec(&elem->key);
267} 271}
268 272
269/* 273/*
@@ -274,10 +278,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,
274 */ 278 */
275static void disable_tracepoint(struct tracepoint *elem) 279static void disable_tracepoint(struct tracepoint *elem)
276{ 280{
277 if (elem->unregfunc && elem->state) 281 if (elem->unregfunc && jump_label_enabled(&elem->key))
278 elem->unregfunc(); 282 elem->unregfunc();
279 283
280 elem->state = 0; 284 if (jump_label_enabled(&elem->key))
285 jump_label_dec(&elem->key);
281 rcu_assign_pointer(elem->funcs, NULL); 286 rcu_assign_pointer(elem->funcs, NULL);
282} 287}
283 288
@@ -288,10 +293,10 @@ static void disable_tracepoint(struct tracepoint *elem)
288 * 293 *
289 * Updates the probe callback corresponding to a range of tracepoints. 294 * Updates the probe callback corresponding to a range of tracepoints.
290 */ 295 */
291void 296void tracepoint_update_probe_range(struct tracepoint * const *begin,
292tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end) 297 struct tracepoint * const *end)
293{ 298{
294 struct tracepoint *iter; 299 struct tracepoint * const *iter;
295 struct tracepoint_entry *mark_entry; 300 struct tracepoint_entry *mark_entry;
296 301
297 if (!begin) 302 if (!begin)
@@ -299,12 +304,12 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end)
299 304
300 mutex_lock(&tracepoints_mutex); 305 mutex_lock(&tracepoints_mutex);
301 for (iter = begin; iter < end; iter++) { 306 for (iter = begin; iter < end; iter++) {
302 mark_entry = get_tracepoint(iter->name); 307 mark_entry = get_tracepoint((*iter)->name);
303 if (mark_entry) { 308 if (mark_entry) {
304 set_tracepoint(&mark_entry, iter, 309 set_tracepoint(&mark_entry, *iter,
305 !!mark_entry->refcount); 310 !!mark_entry->refcount);
306 } else { 311 } else {
307 disable_tracepoint(iter); 312 disable_tracepoint(*iter);
308 } 313 }
309 } 314 }
310 mutex_unlock(&tracepoints_mutex); 315 mutex_unlock(&tracepoints_mutex);
@@ -316,8 +321,8 @@ tracepoint_update_probe_range(struct tracepoint *begin, struct tracepoint *end)
316static void tracepoint_update_probes(void) 321static void tracepoint_update_probes(void)
317{ 322{
318 /* Core kernel tracepoints */ 323 /* Core kernel tracepoints */
319 tracepoint_update_probe_range(__start___tracepoints, 324 tracepoint_update_probe_range(__start___tracepoints_ptrs,
320 __stop___tracepoints); 325 __stop___tracepoints_ptrs);
321 /* tracepoints in modules. */ 326 /* tracepoints in modules. */
322 module_update_tracepoints(); 327 module_update_tracepoints();
323} 328}
@@ -504,8 +509,8 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
504 * Will return the first tracepoint in the range if the input tracepoint is 509 * Will return the first tracepoint in the range if the input tracepoint is
505 * NULL. 510 * NULL.
506 */ 511 */
507int tracepoint_get_iter_range(struct tracepoint **tracepoint, 512int tracepoint_get_iter_range(struct tracepoint * const **tracepoint,
508 struct tracepoint *begin, struct tracepoint *end) 513 struct tracepoint * const *begin, struct tracepoint * const *end)
509{ 514{
510 if (!*tracepoint && begin != end) { 515 if (!*tracepoint && begin != end) {
511 *tracepoint = begin; 516 *tracepoint = begin;
@@ -524,7 +529,8 @@ static void tracepoint_get_iter(struct tracepoint_iter *iter)
524 /* Core kernel tracepoints */ 529 /* Core kernel tracepoints */
525 if (!iter->module) { 530 if (!iter->module) {
526 found = tracepoint_get_iter_range(&iter->tracepoint, 531 found = tracepoint_get_iter_range(&iter->tracepoint,
527 __start___tracepoints, __stop___tracepoints); 532 __start___tracepoints_ptrs,
533 __stop___tracepoints_ptrs);
528 if (found) 534 if (found)
529 goto end; 535 goto end;
530 } 536 }
@@ -575,8 +581,8 @@ int tracepoint_module_notify(struct notifier_block *self,
575 switch (val) { 581 switch (val) {
576 case MODULE_STATE_COMING: 582 case MODULE_STATE_COMING:
577 case MODULE_STATE_GOING: 583 case MODULE_STATE_GOING:
578 tracepoint_update_probe_range(mod->tracepoints, 584 tracepoint_update_probe_range(mod->tracepoints_ptrs,
579 mod->tracepoints + mod->num_tracepoints); 585 mod->tracepoints_ptrs + mod->num_tracepoints);
580 break; 586 break;
581 } 587 }
582 return 0; 588 return 0;