aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Zanussi <tom.zanussi@linux.intel.com>2013-10-24 09:59:24 -0400
committerSteven Rostedt <rostedt@goodmis.org>2013-12-20 18:40:22 -0500
commit85f2b08268c014e290b600ba49fa85530600eaa1 (patch)
tree911b2e24ac56434fc04e8ecafe6251536b6f06a0
parent319e2e3f63c348a9b66db4667efa73178e18b17d (diff)
tracing: Add basic event trigger framework
Add a 'trigger' file for each trace event, enabling 'trace event triggers' to be set for trace events. 'trace event triggers' are patterned after the existing 'ftrace function triggers' implementation except that triggers are written to per-event 'trigger' files instead of to a single file such as the 'set_ftrace_filter' used for ftrace function triggers. The implementation is meant to be entirely separate from ftrace function triggers, in order to keep the respective implementations relatively simple and to allow them to diverge. The event trigger functionality is built on top of SOFT_DISABLE functionality. It adds a TRIGGER_MODE bit to the ftrace_event_file flags which is checked when any trace event fires. Triggers set for a particular event need to be checked regardless of whether that event is actually enabled or not - getting an event to fire even if it's not enabled is what's already implemented by SOFT_DISABLE mode, so trigger mode directly reuses that. Event trigger essentially inherit the soft disable logic in __ftrace_event_enable_disable() while adding a bit of logic and trigger reference counting via tm_ref on top of that in a new trace_event_trigger_enable_disable() function. Because the base __ftrace_event_enable_disable() code now needs to be invoked from outside trace_events.c, a wrapper is also added for those usages. The triggers for an event are actually invoked via a new function, event_triggers_call(), and code is also added to invoke them for ftrace_raw_event calls as well as syscall events. The main part of the patch creates a new trace_events_trigger.c file to contain the trace event triggers implementation. The standard open, read, and release file operations are implemented here. The open() implementation sets up for the various open modes of the 'trigger' file. It creates and attaches the trigger iterator and sets up the command parser. If opened for reading set up the trigger seq_ops. The read() implementation parses the event trigger written to the 'trigger' file, looks up the trigger command, and passes it along to that event_command's func() implementation for command-specific processing. The release() implementation does whatever cleanup is needed to release the 'trigger' file, like releasing the parser and trigger iterator, etc. A couple of functions for event command registration and unregistration are added, along with a list to add them to and a mutex to protect them, as well as an (initially empty) registration function to add the set of commands that will be added by future commits, and call to it from the trace event initialization code. also added are a couple trigger-specific data structures needed for these implementations such as a trigger iterator and a struct for trigger-specific data. A couple structs consisting mostly of function meant to be implemented in command-specific ways, event_command and event_trigger_ops, are used by the generic event trigger command implementations. They're being put into trace.h alongside the other trace_event data structures and functions, in the expectation that they'll be needed in several trace_event-related files such as trace_events_trigger.c and trace_events.c. The event_command.func() function is meant to be called by the trigger parsing code in order to add a trigger instance to the corresponding event. It essentially coordinates adding a live trigger instance to the event, and arming the triggering the event. Every event_command func() implementation essentially does the same thing for any command: - choose ops - use the value of param to choose either a number or count version of event_trigger_ops specific to the command - do the register or unregister of those ops - associate a filter, if specified, with the triggering event The reg() and unreg() ops allow command-specific implementations for event_trigger_op registration and unregistration, and the get_trigger_ops() op allows command-specific event_trigger_ops selection to be parameterized. When a trigger instance is added, the reg() op essentially adds that trigger to the triggering event and arms it, while unreg() does the opposite. The set_filter() function is used to associate a filter with the trigger - if the command doesn't specify a set_filter() implementation, the command will ignore filters. Each command has an associated trigger_type, which serves double duty, both as a unique identifier for the command as well as a value that can be used for setting a trigger mode bit during trigger invocation. The signature of func() adds a pointer to the event_command struct, used to invoke those functions, along with a command_data param that can be passed to the reg/unreg functions. This allows func() implementations to use command-specific blobs and supports code re-use. The event_trigger_ops.func() command corrsponds to the trigger 'probe' function that gets called when the triggering event is actually invoked. The other functions are used to list the trigger when needed, along with a couple mundane book-keeping functions. This also moves event_file_data() into trace.h so it can be used outside of trace_events.c. Link: http://lkml.kernel.org/r/316d95061accdee070aac8e5750afba0192fa5b9.1382622043.git.tom.zanussi@linux.intel.com Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> Idea-by: Steve Rostedt <rostedt@goodmis.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/ftrace_event.h11
-rw-r--r--include/trace/ftrace.h4
-rw-r--r--kernel/trace/Makefile1
-rw-r--r--kernel/trace/trace.h181
-rw-r--r--kernel/trace/trace_events.c21
-rw-r--r--kernel/trace/trace_events_trigger.c278
-rw-r--r--kernel/trace/trace_syscalls.c4
7 files changed, 495 insertions, 5 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 8c9b7a1c4138..211e7ad2baf5 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -264,6 +264,7 @@ enum {
264 FTRACE_EVENT_FL_NO_SET_FILTER_BIT, 264 FTRACE_EVENT_FL_NO_SET_FILTER_BIT,
265 FTRACE_EVENT_FL_SOFT_MODE_BIT, 265 FTRACE_EVENT_FL_SOFT_MODE_BIT,
266 FTRACE_EVENT_FL_SOFT_DISABLED_BIT, 266 FTRACE_EVENT_FL_SOFT_DISABLED_BIT,
267 FTRACE_EVENT_FL_TRIGGER_MODE_BIT,
267}; 268};
268 269
269/* 270/*
@@ -275,6 +276,7 @@ enum {
275 * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED 276 * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED
276 * SOFT_DISABLED - When set, do not trace the event (even though its 277 * SOFT_DISABLED - When set, do not trace the event (even though its
277 * tracepoint may be enabled) 278 * tracepoint may be enabled)
279 * TRIGGER_MODE - When set, invoke the triggers associated with the event
278 */ 280 */
279enum { 281enum {
280 FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT), 282 FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT),
@@ -283,6 +285,7 @@ enum {
283 FTRACE_EVENT_FL_NO_SET_FILTER = (1 << FTRACE_EVENT_FL_NO_SET_FILTER_BIT), 285 FTRACE_EVENT_FL_NO_SET_FILTER = (1 << FTRACE_EVENT_FL_NO_SET_FILTER_BIT),
284 FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT), 286 FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT),
285 FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT), 287 FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT),
288 FTRACE_EVENT_FL_TRIGGER_MODE = (1 << FTRACE_EVENT_FL_TRIGGER_MODE_BIT),
286}; 289};
287 290
288struct ftrace_event_file { 291struct ftrace_event_file {
@@ -292,6 +295,7 @@ struct ftrace_event_file {
292 struct dentry *dir; 295 struct dentry *dir;
293 struct trace_array *tr; 296 struct trace_array *tr;
294 struct ftrace_subsystem_dir *system; 297 struct ftrace_subsystem_dir *system;
298 struct list_head triggers;
295 299
296 /* 300 /*
297 * 32 bit flags: 301 * 32 bit flags:
@@ -299,6 +303,7 @@ struct ftrace_event_file {
299 * bit 1: enabled cmd record 303 * bit 1: enabled cmd record
300 * bit 2: enable/disable with the soft disable bit 304 * bit 2: enable/disable with the soft disable bit
301 * bit 3: soft disabled 305 * bit 3: soft disabled
306 * bit 4: trigger enabled
302 * 307 *
303 * Note: The bits must be set atomically to prevent races 308 * Note: The bits must be set atomically to prevent races
304 * from other writers. Reads of flags do not need to be in 309 * from other writers. Reads of flags do not need to be in
@@ -310,6 +315,7 @@ struct ftrace_event_file {
310 */ 315 */
311 unsigned long flags; 316 unsigned long flags;
312 atomic_t sm_ref; /* soft-mode reference counter */ 317 atomic_t sm_ref; /* soft-mode reference counter */
318 atomic_t tm_ref; /* trigger-mode reference counter */
313}; 319};
314 320
315#define __TRACE_EVENT_FLAGS(name, value) \ 321#define __TRACE_EVENT_FLAGS(name, value) \
@@ -337,6 +343,10 @@ struct ftrace_event_file {
337 343
338#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ 344#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
339 345
346enum event_trigger_type {
347 ETT_NONE = (0),
348};
349
340extern void destroy_preds(struct ftrace_event_file *file); 350extern void destroy_preds(struct ftrace_event_file *file);
341extern void destroy_call_preds(struct ftrace_event_call *call); 351extern void destroy_call_preds(struct ftrace_event_call *call);
342extern int filter_match_preds(struct event_filter *filter, void *rec); 352extern int filter_match_preds(struct event_filter *filter, void *rec);
@@ -347,6 +357,7 @@ extern int filter_check_discard(struct ftrace_event_file *file, void *rec,
347extern int call_filter_check_discard(struct ftrace_event_call *call, void *rec, 357extern int call_filter_check_discard(struct ftrace_event_call *call, void *rec,
348 struct ring_buffer *buffer, 358 struct ring_buffer *buffer,
349 struct ring_buffer_event *event); 359 struct ring_buffer_event *event);
360extern void event_triggers_call(struct ftrace_event_file *file);
350 361
351enum { 362enum {
352 FILTER_OTHER = 0, 363 FILTER_OTHER = 0,
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 5c38606613d8..0a48bff964bd 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -539,6 +539,10 @@ ftrace_raw_event_##call(void *__data, proto) \
539 int __data_size; \ 539 int __data_size; \
540 int pc; \ 540 int pc; \
541 \ 541 \
542 if (test_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, \
543 &ftrace_file->flags)) \
544 event_triggers_call(ftrace_file); \
545 \
542 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, \ 546 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, \
543 &ftrace_file->flags)) \ 547 &ftrace_file->flags)) \
544 return; \ 548 return; \
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index d7e2068e4b71..1378e84fbe39 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -50,6 +50,7 @@ ifeq ($(CONFIG_PERF_EVENTS),y)
50obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o 50obj-$(CONFIG_EVENT_TRACING) += trace_event_perf.o
51endif 51endif
52obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o 52obj-$(CONFIG_EVENT_TRACING) += trace_events_filter.o
53obj-$(CONFIG_EVENT_TRACING) += trace_events_trigger.o
53obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o 54obj-$(CONFIG_KPROBE_EVENT) += trace_kprobe.o
54obj-$(CONFIG_TRACEPOINTS) += power-traces.o 55obj-$(CONFIG_TRACEPOINTS) += power-traces.o
55ifeq ($(CONFIG_PM_RUNTIME),y) 56ifeq ($(CONFIG_PM_RUNTIME),y)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index ea189e027b80..9775e518fe77 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1028,9 +1028,190 @@ extern void trace_event_enable_cmd_record(bool enable);
1028extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr); 1028extern int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr);
1029extern int event_trace_del_tracer(struct trace_array *tr); 1029extern int event_trace_del_tracer(struct trace_array *tr);
1030 1030
1031static inline void *event_file_data(struct file *filp)
1032{
1033 return ACCESS_ONCE(file_inode(filp)->i_private);
1034}
1035
1031extern struct mutex event_mutex; 1036extern struct mutex event_mutex;
1032extern struct list_head ftrace_events; 1037extern struct list_head ftrace_events;
1033 1038
1039extern const struct file_operations event_trigger_fops;
1040
1041extern int register_trigger_cmds(void);
1042extern void clear_event_triggers(struct trace_array *tr);
1043
1044struct event_trigger_data {
1045 unsigned long count;
1046 int ref;
1047 struct event_trigger_ops *ops;
1048 struct event_command *cmd_ops;
1049 struct event_filter *filter;
1050 char *filter_str;
1051 void *private_data;
1052 struct list_head list;
1053};
1054
1055/**
1056 * struct event_trigger_ops - callbacks for trace event triggers
1057 *
1058 * The methods in this structure provide per-event trigger hooks for
1059 * various trigger operations.
1060 *
1061 * All the methods below, except for @init() and @free(), must be
1062 * implemented.
1063 *
1064 * @func: The trigger 'probe' function called when the triggering
1065 * event occurs. The data passed into this callback is the data
1066 * that was supplied to the event_command @reg() function that
1067 * registered the trigger (see struct event_command).
1068 *
1069 * @init: An optional initialization function called for the trigger
1070 * when the trigger is registered (via the event_command reg()
1071 * function). This can be used to perform per-trigger
1072 * initialization such as incrementing a per-trigger reference
1073 * count, for instance. This is usually implemented by the
1074 * generic utility function @event_trigger_init() (see
1075 * trace_event_triggers.c).
1076 *
1077 * @free: An optional de-initialization function called for the
1078 * trigger when the trigger is unregistered (via the
1079 * event_command @reg() function). This can be used to perform
1080 * per-trigger de-initialization such as decrementing a
1081 * per-trigger reference count and freeing corresponding trigger
1082 * data, for instance. This is usually implemented by the
1083 * generic utility function @event_trigger_free() (see
1084 * trace_event_triggers.c).
1085 *
1086 * @print: The callback function invoked to have the trigger print
1087 * itself. This is usually implemented by a wrapper function
1088 * that calls the generic utility function @event_trigger_print()
1089 * (see trace_event_triggers.c).
1090 */
1091struct event_trigger_ops {
1092 void (*func)(struct event_trigger_data *data);
1093 int (*init)(struct event_trigger_ops *ops,
1094 struct event_trigger_data *data);
1095 void (*free)(struct event_trigger_ops *ops,
1096 struct event_trigger_data *data);
1097 int (*print)(struct seq_file *m,
1098 struct event_trigger_ops *ops,
1099 struct event_trigger_data *data);
1100};
1101
1102/**
1103 * struct event_command - callbacks and data members for event commands
1104 *
1105 * Event commands are invoked by users by writing the command name
1106 * into the 'trigger' file associated with a trace event. The
1107 * parameters associated with a specific invocation of an event
1108 * command are used to create an event trigger instance, which is
1109 * added to the list of trigger instances associated with that trace
1110 * event. When the event is hit, the set of triggers associated with
1111 * that event is invoked.
1112 *
1113 * The data members in this structure provide per-event command data
1114 * for various event commands.
1115 *
1116 * All the data members below, except for @post_trigger, must be set
1117 * for each event command.
1118 *
1119 * @name: The unique name that identifies the event command. This is
1120 * the name used when setting triggers via trigger files.
1121 *
1122 * @trigger_type: A unique id that identifies the event command
1123 * 'type'. This value has two purposes, the first to ensure that
1124 * only one trigger of the same type can be set at a given time
1125 * for a particular event e.g. it doesn't make sense to have both
1126 * a traceon and traceoff trigger attached to a single event at
1127 * the same time, so traceon and traceoff have the same type
1128 * though they have different names. The @trigger_type value is
1129 * also used as a bit value for deferring the actual trigger
1130 * action until after the current event is finished. Some
1131 * commands need to do this if they themselves log to the trace
1132 * buffer (see the @post_trigger() member below). @trigger_type
1133 * values are defined by adding new values to the trigger_type
1134 * enum in include/linux/ftrace_event.h.
1135 *
1136 * @post_trigger: A flag that says whether or not this command needs
1137 * to have its action delayed until after the current event has
1138 * been closed. Some triggers need to avoid being invoked while
1139 * an event is currently in the process of being logged, since
1140 * the trigger may itself log data into the trace buffer. Thus
1141 * we make sure the current event is committed before invoking
1142 * those triggers. To do that, the trigger invocation is split
1143 * in two - the first part checks the filter using the current
1144 * trace record; if a command has the @post_trigger flag set, it
1145 * sets a bit for itself in the return value, otherwise it
1146 * directly invokes the trigger. Once all commands have been
1147 * either invoked or set their return flag, the current record is
1148 * either committed or discarded. At that point, if any commands
1149 * have deferred their triggers, those commands are finally
1150 * invoked following the close of the current event. In other
1151 * words, if the event_trigger_ops @func() probe implementation
1152 * itself logs to the trace buffer, this flag should be set,
1153 * otherwise it can be left unspecified.
1154 *
1155 * All the methods below, except for @set_filter(), must be
1156 * implemented.
1157 *
1158 * @func: The callback function responsible for parsing and
1159 * registering the trigger written to the 'trigger' file by the
1160 * user. It allocates the trigger instance and registers it with
1161 * the appropriate trace event. It makes use of the other
1162 * event_command callback functions to orchestrate this, and is
1163 * usually implemented by the generic utility function
1164 * @event_trigger_callback() (see trace_event_triggers.c).
1165 *
1166 * @reg: Adds the trigger to the list of triggers associated with the
1167 * event, and enables the event trigger itself, after
1168 * initializing it (via the event_trigger_ops @init() function).
1169 * This is also where commands can use the @trigger_type value to
1170 * make the decision as to whether or not multiple instances of
1171 * the trigger should be allowed. This is usually implemented by
1172 * the generic utility function @register_trigger() (see
1173 * trace_event_triggers.c).
1174 *
1175 * @unreg: Removes the trigger from the list of triggers associated
1176 * with the event, and disables the event trigger itself, after
1177 * initializing it (via the event_trigger_ops @free() function).
1178 * This is usually implemented by the generic utility function
1179 * @unregister_trigger() (see trace_event_triggers.c).
1180 *
1181 * @set_filter: An optional function called to parse and set a filter
1182 * for the trigger. If no @set_filter() method is set for the
1183 * event command, filters set by the user for the command will be
1184 * ignored. This is usually implemented by the generic utility
1185 * function @set_trigger_filter() (see trace_event_triggers.c).
1186 *
1187 * @get_trigger_ops: The callback function invoked to retrieve the
1188 * event_trigger_ops implementation associated with the command.
1189 */
1190struct event_command {
1191 struct list_head list;
1192 char *name;
1193 enum event_trigger_type trigger_type;
1194 bool post_trigger;
1195 int (*func)(struct event_command *cmd_ops,
1196 struct ftrace_event_file *file,
1197 char *glob, char *cmd, char *params);
1198 int (*reg)(char *glob,
1199 struct event_trigger_ops *ops,
1200 struct event_trigger_data *data,
1201 struct ftrace_event_file *file);
1202 void (*unreg)(char *glob,
1203 struct event_trigger_ops *ops,
1204 struct event_trigger_data *data,
1205 struct ftrace_event_file *file);
1206 int (*set_filter)(char *filter_str,
1207 struct event_trigger_data *data,
1208 struct ftrace_event_file *file);
1209 struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
1210};
1211
1212extern int trace_event_enable_disable(struct ftrace_event_file *file,
1213 int enable, int soft_disable);
1214
1034extern const char *__start___trace_bprintk_fmt[]; 1215extern const char *__start___trace_bprintk_fmt[];
1035extern const char *__stop___trace_bprintk_fmt[]; 1216extern const char *__stop___trace_bprintk_fmt[];
1036 1217
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index a11800ae96de..442775c9dbf3 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -342,6 +342,12 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file,
342 return ret; 342 return ret;
343} 343}
344 344
345int trace_event_enable_disable(struct ftrace_event_file *file,
346 int enable, int soft_disable)
347{
348 return __ftrace_event_enable_disable(file, enable, soft_disable);
349}
350
345static int ftrace_event_enable_disable(struct ftrace_event_file *file, 351static int ftrace_event_enable_disable(struct ftrace_event_file *file,
346 int enable) 352 int enable)
347{ 353{
@@ -421,11 +427,6 @@ static void remove_subsystem(struct ftrace_subsystem_dir *dir)
421 } 427 }
422} 428}
423 429
424static void *event_file_data(struct file *filp)
425{
426 return ACCESS_ONCE(file_inode(filp)->i_private);
427}
428
429static void remove_event_file_dir(struct ftrace_event_file *file) 430static void remove_event_file_dir(struct ftrace_event_file *file)
430{ 431{
431 struct dentry *dir = file->dir; 432 struct dentry *dir = file->dir;
@@ -1549,6 +1550,9 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file)
1549 trace_create_file("filter", 0644, file->dir, file, 1550 trace_create_file("filter", 0644, file->dir, file,
1550 &ftrace_event_filter_fops); 1551 &ftrace_event_filter_fops);
1551 1552
1553 trace_create_file("trigger", 0644, file->dir, file,
1554 &event_trigger_fops);
1555
1552 trace_create_file("format", 0444, file->dir, call, 1556 trace_create_file("format", 0444, file->dir, call,
1553 &ftrace_event_format_fops); 1557 &ftrace_event_format_fops);
1554 1558
@@ -1645,6 +1649,8 @@ trace_create_new_event(struct ftrace_event_call *call,
1645 file->event_call = call; 1649 file->event_call = call;
1646 file->tr = tr; 1650 file->tr = tr;
1647 atomic_set(&file->sm_ref, 0); 1651 atomic_set(&file->sm_ref, 0);
1652 atomic_set(&file->tm_ref, 0);
1653 INIT_LIST_HEAD(&file->triggers);
1648 list_add(&file->list, &tr->events); 1654 list_add(&file->list, &tr->events);
1649 1655
1650 return file; 1656 return file;
@@ -2311,6 +2317,9 @@ int event_trace_del_tracer(struct trace_array *tr)
2311{ 2317{
2312 mutex_lock(&event_mutex); 2318 mutex_lock(&event_mutex);
2313 2319
2320 /* Disable any event triggers and associated soft-disabled events */
2321 clear_event_triggers(tr);
2322
2314 /* Disable any running events */ 2323 /* Disable any running events */
2315 __ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0); 2324 __ftrace_set_clr_event_nolock(tr, NULL, NULL, NULL, 0);
2316 2325
@@ -2377,6 +2386,8 @@ static __init int event_trace_enable(void)
2377 2386
2378 register_event_cmds(); 2387 register_event_cmds();
2379 2388
2389 register_trigger_cmds();
2390
2380 return 0; 2391 return 0;
2381} 2392}
2382 2393
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
new file mode 100644
index 000000000000..60a6a6d66dc0
--- /dev/null
+++ b/kernel/trace/trace_events_trigger.c
@@ -0,0 +1,278 @@
1/*
2 * trace_events_trigger - trace event triggers
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com>
19 */
20
21#include <linux/module.h>
22#include <linux/ctype.h>
23#include <linux/mutex.h>
24#include <linux/slab.h>
25
26#include "trace.h"
27
28static LIST_HEAD(trigger_commands);
29static DEFINE_MUTEX(trigger_cmd_mutex);
30
31/**
32 * event_triggers_call - Call triggers associated with a trace event
33 * @file: The ftrace_event_file associated with the event
34 *
35 * For each trigger associated with an event, invoke the trigger
36 * function registered with the associated trigger command.
37 *
38 * Called from tracepoint handlers (with rcu_read_lock_sched() held).
39 *
40 * Return: an enum event_trigger_type value containing a set bit for
41 * any trigger that should be deferred, ETT_NONE if nothing to defer.
42 */
43void event_triggers_call(struct ftrace_event_file *file)
44{
45 struct event_trigger_data *data;
46
47 if (list_empty(&file->triggers))
48 return;
49
50 list_for_each_entry_rcu(data, &file->triggers, list)
51 data->ops->func(data);
52}
53EXPORT_SYMBOL_GPL(event_triggers_call);
54
55static void *trigger_next(struct seq_file *m, void *t, loff_t *pos)
56{
57 struct ftrace_event_file *event_file = event_file_data(m->private);
58
59 return seq_list_next(t, &event_file->triggers, pos);
60}
61
62static void *trigger_start(struct seq_file *m, loff_t *pos)
63{
64 struct ftrace_event_file *event_file;
65
66 /* ->stop() is called even if ->start() fails */
67 mutex_lock(&event_mutex);
68 event_file = event_file_data(m->private);
69 if (unlikely(!event_file))
70 return ERR_PTR(-ENODEV);
71
72 return seq_list_start(&event_file->triggers, *pos);
73}
74
75static void trigger_stop(struct seq_file *m, void *t)
76{
77 mutex_unlock(&event_mutex);
78}
79
80static int trigger_show(struct seq_file *m, void *v)
81{
82 struct event_trigger_data *data;
83
84 data = list_entry(v, struct event_trigger_data, list);
85 data->ops->print(m, data->ops, data);
86
87 return 0;
88}
89
90static const struct seq_operations event_triggers_seq_ops = {
91 .start = trigger_start,
92 .next = trigger_next,
93 .stop = trigger_stop,
94 .show = trigger_show,
95};
96
97static int event_trigger_regex_open(struct inode *inode, struct file *file)
98{
99 int ret = 0;
100
101 mutex_lock(&event_mutex);
102
103 if (unlikely(!event_file_data(file))) {
104 mutex_unlock(&event_mutex);
105 return -ENODEV;
106 }
107
108 if (file->f_mode & FMODE_READ) {
109 ret = seq_open(file, &event_triggers_seq_ops);
110 if (!ret) {
111 struct seq_file *m = file->private_data;
112 m->private = file;
113 }
114 }
115
116 mutex_unlock(&event_mutex);
117
118 return ret;
119}
120
121static int trigger_process_regex(struct ftrace_event_file *file, char *buff)
122{
123 char *command, *next = buff;
124 struct event_command *p;
125 int ret = -EINVAL;
126
127 command = strsep(&next, ": \t");
128 command = (command[0] != '!') ? command : command + 1;
129
130 mutex_lock(&trigger_cmd_mutex);
131 list_for_each_entry(p, &trigger_commands, list) {
132 if (strcmp(p->name, command) == 0) {
133 ret = p->func(p, file, buff, command, next);
134 goto out_unlock;
135 }
136 }
137 out_unlock:
138 mutex_unlock(&trigger_cmd_mutex);
139
140 return ret;
141}
142
143static ssize_t event_trigger_regex_write(struct file *file,
144 const char __user *ubuf,
145 size_t cnt, loff_t *ppos)
146{
147 struct ftrace_event_file *event_file;
148 ssize_t ret;
149 char *buf;
150
151 if (!cnt)
152 return 0;
153
154 if (cnt >= PAGE_SIZE)
155 return -EINVAL;
156
157 buf = (char *)__get_free_page(GFP_TEMPORARY);
158 if (!buf)
159 return -ENOMEM;
160
161 if (copy_from_user(buf, ubuf, cnt)) {
162 free_page((unsigned long)buf);
163 return -EFAULT;
164 }
165 buf[cnt] = '\0';
166 strim(buf);
167
168 mutex_lock(&event_mutex);
169 event_file = event_file_data(file);
170 if (unlikely(!event_file)) {
171 mutex_unlock(&event_mutex);
172 free_page((unsigned long)buf);
173 return -ENODEV;
174 }
175 ret = trigger_process_regex(event_file, buf);
176 mutex_unlock(&event_mutex);
177
178 free_page((unsigned long)buf);
179 if (ret < 0)
180 goto out;
181
182 *ppos += cnt;
183 ret = cnt;
184 out:
185 return ret;
186}
187
188static int event_trigger_regex_release(struct inode *inode, struct file *file)
189{
190 mutex_lock(&event_mutex);
191
192 if (file->f_mode & FMODE_READ)
193 seq_release(inode, file);
194
195 mutex_unlock(&event_mutex);
196
197 return 0;
198}
199
200static ssize_t
201event_trigger_write(struct file *filp, const char __user *ubuf,
202 size_t cnt, loff_t *ppos)
203{
204 return event_trigger_regex_write(filp, ubuf, cnt, ppos);
205}
206
207static int
208event_trigger_open(struct inode *inode, struct file *filp)
209{
210 return event_trigger_regex_open(inode, filp);
211}
212
213static int
214event_trigger_release(struct inode *inode, struct file *file)
215{
216 return event_trigger_regex_release(inode, file);
217}
218
219const struct file_operations event_trigger_fops = {
220 .open = event_trigger_open,
221 .read = seq_read,
222 .write = event_trigger_write,
223 .llseek = ftrace_filter_lseek,
224 .release = event_trigger_release,
225};
226
227static int trace_event_trigger_enable_disable(struct ftrace_event_file *file,
228 int trigger_enable)
229{
230 int ret = 0;
231
232 if (trigger_enable) {
233 if (atomic_inc_return(&file->tm_ref) > 1)
234 return ret;
235 set_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &file->flags);
236 ret = trace_event_enable_disable(file, 1, 1);
237 } else {
238 if (atomic_dec_return(&file->tm_ref) > 0)
239 return ret;
240 clear_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &file->flags);
241 ret = trace_event_enable_disable(file, 0, 1);
242 }
243
244 return ret;
245}
246
247/**
248 * clear_event_triggers - Clear all triggers associated with a trace array
249 * @tr: The trace array to clear
250 *
251 * For each trigger, the triggering event has its tm_ref decremented
252 * via trace_event_trigger_enable_disable(), and any associated event
253 * (in the case of enable/disable_event triggers) will have its sm_ref
254 * decremented via free()->trace_event_enable_disable(). That
255 * combination effectively reverses the soft-mode/trigger state added
256 * by trigger registration.
257 *
258 * Must be called with event_mutex held.
259 */
260void
261clear_event_triggers(struct trace_array *tr)
262{
263 struct ftrace_event_file *file;
264
265 list_for_each_entry(file, &tr->events, list) {
266 struct event_trigger_data *data;
267 list_for_each_entry_rcu(data, &file->triggers, list) {
268 trace_event_trigger_enable_disable(file, 0);
269 if (data->ops->free)
270 data->ops->free(data->ops, data);
271 }
272 }
273}
274
275__init int register_trigger_cmds(void)
276{
277 return 0;
278}
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index ea90eb5f6f17..936ec3960335 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -321,6 +321,8 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
321 if (!ftrace_file) 321 if (!ftrace_file)
322 return; 322 return;
323 323
324 if (test_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &ftrace_file->flags))
325 event_triggers_call(ftrace_file);
324 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) 326 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
325 return; 327 return;
326 328
@@ -369,6 +371,8 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
369 if (!ftrace_file) 371 if (!ftrace_file)
370 return; 372 return;
371 373
374 if (test_bit(FTRACE_EVENT_FL_TRIGGER_MODE_BIT, &ftrace_file->flags))
375 event_triggers_call(ftrace_file);
372 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) 376 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
373 return; 377 return;
374 378