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>
This commit is contained in:
parent
3fd40d1ee6
commit
b196e2b9e2
|
@ -62,6 +62,7 @@ struct tracepoint_entry {
|
|||
struct hlist_node hlist;
|
||||
struct tracepoint_func *funcs;
|
||||
int refcount; /* Number of times armed. 0 if disarmed. */
|
||||
int enabled; /* Tracepoint enabled */
|
||||
char name[0];
|
||||
};
|
||||
|
||||
|
@ -237,6 +238,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
|
|||
memcpy(&e->name[0], name, name_len);
|
||||
e->funcs = NULL;
|
||||
e->refcount = 0;
|
||||
e->enabled = 0;
|
||||
hlist_add_head(&e->hlist, head);
|
||||
return e;
|
||||
}
|
||||
|
@ -316,6 +318,7 @@ static void tracepoint_update_probe_range(struct tracepoint * const *begin,
|
|||
if (mark_entry) {
|
||||
set_tracepoint(&mark_entry, *iter,
|
||||
!!mark_entry->refcount);
|
||||
mark_entry->enabled = !!mark_entry->refcount;
|
||||
} else {
|
||||
disable_tracepoint(*iter);
|
||||
}
|
||||
|
@ -380,6 +383,8 @@ tracepoint_add_probe(const char *name, void *probe, void *data)
|
|||
int tracepoint_probe_register(const char *name, void *probe, void *data)
|
||||
{
|
||||
struct tracepoint_func *old;
|
||||
struct tracepoint_entry *entry;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&tracepoints_mutex);
|
||||
old = tracepoint_add_probe(name, probe, data);
|
||||
|
@ -388,9 +393,13 @@ int tracepoint_probe_register(const char *name, void *probe, void *data)
|
|||
return PTR_ERR(old);
|
||||
}
|
||||
tracepoint_update_probes(); /* may update entry */
|
||||
entry = get_tracepoint(name);
|
||||
/* Make sure the entry was enabled */
|
||||
if (!entry || !entry->enabled)
|
||||
ret = -ENODEV;
|
||||
mutex_unlock(&tracepoints_mutex);
|
||||
release_probes(old);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tracepoint_probe_register);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user