Skip to content

Commit

Permalink
tracing: Modify soft-mode only if there's no other referrer
Browse files Browse the repository at this point in the history
Modify soft-mode flag only if no other soft-mode referrer
(currently only the ftrace triggers) by using a reference
counter in each ftrace_event_file.

Without this fix, adding and removing several different
enable/disable_event triggers on the same event clear
soft-mode bit from the ftrace_event_file. This also
happens with a typo of glob on setting triggers.

e.g.

 # echo vfs_symlink:enable_event:net:netif_rx > set_ftrace_filter
 # cat events/net/netif_rx/enable
 0*
 # echo typo_func:enable_event:net:netif_rx > set_ftrace_filter
 # cat events/net/netif_rx/enable
 0
 # cat set_ftrace_filter
 #### all functions enabled ####
 vfs_symlink:enable_event:net:netif_rx:unlimited

As above, we still have a trigger, but soft-mode is gone.

Link: http://lkml.kernel.org/r/20130509054429.30398.7464.stgit@mhiramat-M0-7522

Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: David Sharp <dhsharp@google.com>
Cc: Hiraku Toyooka <hiraku.toyooka.gu@hitachi.com>
Cc: Tom Zanussi <tom.zanussi@intel.com>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
  • Loading branch information
Masami Hiramatsu authored and Steven Rostedt committed May 10, 2013
1 parent 3005217 commit 1cf4c07
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/linux/ftrace_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ struct ftrace_event_file {
* caching and such. Which is mostly OK ;-)
*/
unsigned long flags;
atomic_t sm_ref; /* soft-mode reference counter */
};

#define __TRACE_EVENT_FLAGS(name, value) \
Expand Down
12 changes: 10 additions & 2 deletions kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,8 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file,
switch (enable) {
case 0:
/*
* When soft_disable is set and enable is cleared, we want
* When soft_disable is set and enable is cleared, the sm_ref
* reference counter is decremented. If it reaches 0, we want
* to clear the SOFT_DISABLED flag but leave the event in the
* state that it was. That is, if the event was enabled and
* SOFT_DISABLED isn't set, then do nothing. But if SOFT_DISABLED
Expand All @@ -263,6 +264,8 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file,
* "soft enable"s (clearing the SOFT_DISABLED bit) wont work.
*/
if (soft_disable) {
if (atomic_dec_return(&file->sm_ref) > 0)
break;
disable = file->flags & FTRACE_EVENT_FL_SOFT_DISABLED;
clear_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags);
} else
Expand Down Expand Up @@ -291,8 +294,11 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file,
*/
if (!soft_disable)
clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags);
else
else {
if (atomic_inc_return(&file->sm_ref) > 1)
break;
set_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags);
}

if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) {

Expand Down Expand Up @@ -1540,6 +1546,7 @@ __trace_add_new_event(struct ftrace_event_call *call,

file->event_call = call;
file->tr = tr;
atomic_set(&file->sm_ref, 0);
list_add(&file->list, &tr->events);

return event_create_dir(tr->event_dir, file, id, enable, filter, format);
Expand All @@ -1562,6 +1569,7 @@ __trace_early_add_new_event(struct ftrace_event_call *call,

file->event_call = call;
file->tr = tr;
atomic_set(&file->sm_ref, 0);
list_add(&file->list, &tr->events);

return 0;
Expand Down

0 comments on commit 1cf4c07

Please sign in to comment.