aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/tracepoint.c
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2014-02-13 15:45:07 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-03-07 10:06:07 -0500
commitb196e2b9e262be01737dc2bbf9e3c7c87340fa4d (patch)
tree0916b9230d0ffe669629e1cbc03a458653cb61b1 /kernel/tracepoint.c
parent3fd40d1ee6a317523172ab95b6f7ea41ba8fcee3 (diff)
tracing: Warn if a tracepoint is not set via debugfs
Tracepoints were made to allow enabling a tracepoint in a module before that module was loaded. When a tracepoint is enabled and it does not exist, the name is stored and will be enabled when the tracepoint is created. The problem with this approach is that when a tracepoint is enabled when it expects to be there, it gives no warning that it does not exist. To add salt to the wound, if a module is added and sets the FORCED flag, which can happen if it isn't signed properly, the tracepoint code will not enabled the tracepoints, but they will be created in the debugfs system! When a user goes to enable the tracepoint, the tracepoint code will not see it existing and will think it is to be enabled later AND WILL NOT GIVE A WARNING. The tracing will look like it succeeded but will actually be doing nothing. This will cause lots of confusion and headaches for developers trying to figure out why they are not seeing their tracepoints. Link: http://lkml.kernel.org/r/20140213154507.4040fb06@gandalf.local.home Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Reported-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/tracepoint.c')
-rw-r--r--kernel/tracepoint.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 0d4ef26574ff..0058f33d05c1 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -62,6 +62,7 @@ struct tracepoint_entry {
62 struct hlist_node hlist; 62 struct hlist_node hlist;
63 struct tracepoint_func *funcs; 63 struct tracepoint_func *funcs;
64 int refcount; /* Number of times armed. 0 if disarmed. */ 64 int refcount; /* Number of times armed. 0 if disarmed. */
65 int enabled; /* Tracepoint enabled */
65 char name[0]; 66 char name[0];
66}; 67};
67 68
@@ -237,6 +238,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
237 memcpy(&e->name[0], name, name_len); 238 memcpy(&e->name[0], name, name_len);
238 e->funcs = NULL; 239 e->funcs = NULL;
239 e->refcount = 0; 240 e->refcount = 0;
241 e->enabled = 0;
240 hlist_add_head(&e->hlist, head); 242 hlist_add_head(&e->hlist, head);
241 return e; 243 return e;
242} 244}
@@ -316,6 +318,7 @@ static void tracepoint_update_probe_range(struct tracepoint * const *begin,
316 if (mark_entry) { 318 if (mark_entry) {
317 set_tracepoint(&mark_entry, *iter, 319 set_tracepoint(&mark_entry, *iter,
318 !!mark_entry->refcount); 320 !!mark_entry->refcount);
321 mark_entry->enabled = !!mark_entry->refcount;
319 } else { 322 } else {
320 disable_tracepoint(*iter); 323 disable_tracepoint(*iter);
321 } 324 }
@@ -380,6 +383,8 @@ tracepoint_add_probe(const char *name, void *probe, void *data)
380int tracepoint_probe_register(const char *name, void *probe, void *data) 383int tracepoint_probe_register(const char *name, void *probe, void *data)
381{ 384{
382 struct tracepoint_func *old; 385 struct tracepoint_func *old;
386 struct tracepoint_entry *entry;
387 int ret = 0;
383 388
384 mutex_lock(&tracepoints_mutex); 389 mutex_lock(&tracepoints_mutex);
385 old = tracepoint_add_probe(name, probe, data); 390 old = tracepoint_add_probe(name, probe, data);
@@ -388,9 +393,13 @@ int tracepoint_probe_register(const char *name, void *probe, void *data)
388 return PTR_ERR(old); 393 return PTR_ERR(old);
389 } 394 }
390 tracepoint_update_probes(); /* may update entry */ 395 tracepoint_update_probes(); /* may update entry */
396 entry = get_tracepoint(name);
397 /* Make sure the entry was enabled */
398 if (!entry || !entry->enabled)
399 ret = -ENODEV;
391 mutex_unlock(&tracepoints_mutex); 400 mutex_unlock(&tracepoints_mutex);
392 release_probes(old); 401 release_probes(old);
393 return 0; 402 return ret;
394} 403}
395EXPORT_SYMBOL_GPL(tracepoint_probe_register); 404EXPORT_SYMBOL_GPL(tracepoint_probe_register);
396 405