mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
tracing: Remove get_trigger_ops() and add count_func() from trigger ops
The struct event_command has a callback function called get_trigger_ops(). This callback returns the "trigger_ops" to use for the trigger. These ops define the trigger function, how to init the trigger, how to print the trigger and how to free it. The only reason there's a callback function to get these ops is because some triggers have two types of operations. One is an "always on" operation, and the other is a "count down" operation. If a user passes in a parameter to say how many times the trigger should execute. For example: echo stacktrace:5 > events/kmem/kmem_cache_alloc/trigger It will trigger the stacktrace for the first 5 times the kmem_cache_alloc event is hit. Instead of having two different trigger_ops since the only difference between them is the tigger itself (the print, init and free functions are all the same), just use a single ops that the event_command points to and add a function field to the trigger_ops to have a count_func. When a trigger is added to an event, if there's a count attached to it and the trigger ops has the count_func field, the data allocated to represent this trigger will have a new flag set called COUNT. Then when the trigger executes, it will check if the COUNT data flag is set, and if so, it will call the ops count_func(). If that returns false, it returns without executing the trigger. This removes the need for duplicate event_trigger_ops structures. Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Andrew Morton <akpm@linux-foundation.org> Link: https://patch.msgid.link/20251125200932.274566147@kernel.org Reviewed-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
23c0e9cc76
commit
bdafb4d4cb
|
|
@ -1791,6 +1791,7 @@ extern void clear_event_triggers(struct trace_array *tr);
|
|||
|
||||
enum {
|
||||
EVENT_TRIGGER_FL_PROBE = BIT(0),
|
||||
EVENT_TRIGGER_FL_COUNT = BIT(1),
|
||||
};
|
||||
|
||||
struct event_trigger_data {
|
||||
|
|
@ -1822,6 +1823,10 @@ struct enable_trigger_data {
|
|||
bool hist;
|
||||
};
|
||||
|
||||
bool event_trigger_count(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event);
|
||||
|
||||
extern int event_enable_trigger_print(struct seq_file *m,
|
||||
struct event_trigger_data *data);
|
||||
extern void event_enable_trigger_free(struct event_trigger_data *data);
|
||||
|
|
@ -1909,6 +1914,11 @@ extern void event_file_put(struct trace_event_file *file);
|
|||
* registered the trigger (see struct event_command) along with
|
||||
* the trace record, rec.
|
||||
*
|
||||
* @count_func: If defined and a numeric parameter is passed to the
|
||||
* trigger, then this function will be called before @trigger
|
||||
* is called. If this function returns false, then @trigger is not
|
||||
* executed.
|
||||
*
|
||||
* @init: An optional initialization function called for the trigger
|
||||
* when the trigger is registered (via the event_command reg()
|
||||
* function). This can be used to perform per-trigger
|
||||
|
|
@ -1936,6 +1946,10 @@ struct event_trigger_ops {
|
|||
struct trace_buffer *buffer,
|
||||
void *rec,
|
||||
struct ring_buffer_event *rbe);
|
||||
bool (*count_func)(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer,
|
||||
void *rec,
|
||||
struct ring_buffer_event *rbe);
|
||||
int (*init)(struct event_trigger_data *data);
|
||||
void (*free)(struct event_trigger_data *data);
|
||||
int (*print)(struct seq_file *m,
|
||||
|
|
@ -1962,6 +1976,9 @@ struct event_trigger_ops {
|
|||
* @name: The unique name that identifies the event command. This is
|
||||
* the name used when setting triggers via trigger files.
|
||||
*
|
||||
* @trigger_ops: The event_trigger_ops implementation associated with
|
||||
* the command.
|
||||
*
|
||||
* @trigger_type: A unique id that identifies the event command
|
||||
* 'type'. This value has two purposes, the first to ensure that
|
||||
* only one trigger of the same type can be set at a given time
|
||||
|
|
@ -2013,17 +2030,11 @@ struct event_trigger_ops {
|
|||
* event command, filters set by the user for the command will be
|
||||
* ignored. This is usually implemented by the generic utility
|
||||
* function @set_trigger_filter() (see trace_event_triggers.c).
|
||||
*
|
||||
* @get_trigger_ops: The callback function invoked to retrieve the
|
||||
* event_trigger_ops implementation associated with the command.
|
||||
* This callback function allows a single event_command to
|
||||
* support multiple trigger implementations via different sets of
|
||||
* event_trigger_ops, depending on the value of the @param
|
||||
* string.
|
||||
*/
|
||||
struct event_command {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
const struct event_trigger_ops *trigger_ops;
|
||||
enum event_trigger_type trigger_type;
|
||||
int flags;
|
||||
int (*parse)(struct event_command *cmd_ops,
|
||||
|
|
@ -2040,7 +2051,6 @@ struct event_command {
|
|||
int (*set_filter)(char *filter_str,
|
||||
struct event_trigger_data *data,
|
||||
struct trace_event_file *file);
|
||||
const struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -513,21 +513,15 @@ static void eprobe_trigger_unreg_func(char *glob,
|
|||
|
||||
}
|
||||
|
||||
static const struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
|
||||
char *param)
|
||||
{
|
||||
return &eprobe_trigger_ops;
|
||||
}
|
||||
|
||||
static struct event_command event_trigger_cmd = {
|
||||
.name = "eprobe",
|
||||
.trigger_type = ETT_EVENT_EPROBE,
|
||||
.flags = EVENT_CMD_FL_NEEDS_REC,
|
||||
.trigger_ops = &eprobe_trigger_ops,
|
||||
.parse = eprobe_trigger_cmd_parse,
|
||||
.reg = eprobe_trigger_reg_func,
|
||||
.unreg = eprobe_trigger_unreg_func,
|
||||
.unreg_all = NULL,
|
||||
.get_trigger_ops = eprobe_trigger_get_ops,
|
||||
.set_filter = NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6363,12 +6363,6 @@ static const struct event_trigger_ops event_hist_trigger_named_ops = {
|
|||
.free = event_hist_trigger_named_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
|
||||
char *param)
|
||||
{
|
||||
return &event_hist_trigger_ops;
|
||||
}
|
||||
|
||||
static void hist_clear(struct event_trigger_data *data)
|
||||
{
|
||||
struct hist_trigger_data *hist_data = data->private_data;
|
||||
|
|
@ -6908,11 +6902,11 @@ static struct event_command trigger_hist_cmd = {
|
|||
.name = "hist",
|
||||
.trigger_type = ETT_EVENT_HIST,
|
||||
.flags = EVENT_CMD_FL_NEEDS_REC,
|
||||
.trigger_ops = &event_hist_trigger_ops,
|
||||
.parse = event_hist_trigger_parse,
|
||||
.reg = hist_register_trigger,
|
||||
.unreg = hist_unregister_trigger,
|
||||
.unreg_all = hist_unreg_all,
|
||||
.get_trigger_ops = event_hist_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
@ -6945,29 +6939,9 @@ hist_enable_trigger(struct event_trigger_data *data,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
hist_enable_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
if (!data->count)
|
||||
return;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
hist_enable_trigger(data, buffer, rec, event);
|
||||
}
|
||||
|
||||
static const struct event_trigger_ops hist_enable_trigger_ops = {
|
||||
.trigger = hist_enable_trigger,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops hist_enable_count_trigger_ops = {
|
||||
.trigger = hist_enable_count_trigger,
|
||||
.count_func = event_trigger_count,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
|
|
@ -6975,36 +6949,12 @@ static const struct event_trigger_ops hist_enable_count_trigger_ops = {
|
|||
|
||||
static const struct event_trigger_ops hist_disable_trigger_ops = {
|
||||
.trigger = hist_enable_trigger,
|
||||
.count_func = event_trigger_count,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops hist_disable_count_trigger_ops = {
|
||||
.trigger = hist_enable_count_trigger,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops *
|
||||
hist_enable_get_trigger_ops(char *cmd, char *param)
|
||||
{
|
||||
const struct event_trigger_ops *ops;
|
||||
bool enable;
|
||||
|
||||
enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
|
||||
|
||||
if (enable)
|
||||
ops = param ? &hist_enable_count_trigger_ops :
|
||||
&hist_enable_trigger_ops;
|
||||
else
|
||||
ops = param ? &hist_disable_count_trigger_ops :
|
||||
&hist_disable_trigger_ops;
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void hist_enable_unreg_all(struct trace_event_file *file)
|
||||
{
|
||||
struct event_trigger_data *test, *n;
|
||||
|
|
@ -7023,22 +6973,22 @@ static void hist_enable_unreg_all(struct trace_event_file *file)
|
|||
static struct event_command trigger_hist_enable_cmd = {
|
||||
.name = ENABLE_HIST_STR,
|
||||
.trigger_type = ETT_HIST_ENABLE,
|
||||
.trigger_ops = &hist_enable_trigger_ops,
|
||||
.parse = event_enable_trigger_parse,
|
||||
.reg = event_enable_register_trigger,
|
||||
.unreg = event_enable_unregister_trigger,
|
||||
.unreg_all = hist_enable_unreg_all,
|
||||
.get_trigger_ops = hist_enable_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
static struct event_command trigger_hist_disable_cmd = {
|
||||
.name = DISABLE_HIST_STR,
|
||||
.trigger_type = ETT_HIST_ENABLE,
|
||||
.trigger_ops = &hist_disable_trigger_ops,
|
||||
.parse = event_enable_trigger_parse,
|
||||
.reg = event_enable_register_trigger,
|
||||
.unreg = event_enable_unregister_trigger,
|
||||
.unreg_all = hist_enable_unreg_all,
|
||||
.get_trigger_ops = hist_enable_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,20 @@ void trigger_data_free(struct event_trigger_data *data)
|
|||
kfree(data);
|
||||
}
|
||||
|
||||
static inline void data_ops_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
const struct event_trigger_ops *ops = data->ops;
|
||||
|
||||
if (data->flags & EVENT_TRIGGER_FL_COUNT) {
|
||||
if (!ops->count_func(data, buffer, rec, event))
|
||||
return;
|
||||
}
|
||||
|
||||
ops->trigger(data, buffer, rec, event);
|
||||
}
|
||||
|
||||
/**
|
||||
* event_triggers_call - Call triggers associated with a trace event
|
||||
* @file: The trace_event_file associated with the event
|
||||
|
|
@ -70,7 +84,7 @@ event_triggers_call(struct trace_event_file *file,
|
|||
if (data->paused)
|
||||
continue;
|
||||
if (!rec) {
|
||||
data->ops->trigger(data, buffer, rec, event);
|
||||
data_ops_trigger(data, buffer, rec, event);
|
||||
continue;
|
||||
}
|
||||
filter = rcu_dereference_sched(data->filter);
|
||||
|
|
@ -80,7 +94,7 @@ event_triggers_call(struct trace_event_file *file,
|
|||
tt |= data->cmd_ops->trigger_type;
|
||||
continue;
|
||||
}
|
||||
data->ops->trigger(data, buffer, rec, event);
|
||||
data_ops_trigger(data, buffer, rec, event);
|
||||
}
|
||||
return tt;
|
||||
}
|
||||
|
|
@ -122,7 +136,7 @@ event_triggers_post_call(struct trace_event_file *file,
|
|||
if (data->paused)
|
||||
continue;
|
||||
if (data->cmd_ops->trigger_type & tt)
|
||||
data->ops->trigger(data, NULL, NULL, NULL);
|
||||
data_ops_trigger(data, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(event_triggers_post_call);
|
||||
|
|
@ -377,6 +391,36 @@ __init int unregister_event_command(struct event_command *cmd)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
/**
|
||||
* event_trigger_count - Optional count function for event triggers
|
||||
* @data: Trigger-specific data
|
||||
* @buffer: The ring buffer that the event is being written to
|
||||
* @rec: The trace entry for the event, NULL for unconditional invocation
|
||||
* @event: The event meta data in the ring buffer
|
||||
*
|
||||
* For triggers that can take a count parameter that doesn't do anything
|
||||
* special, they can use this function to assign to their .count_func
|
||||
* field.
|
||||
*
|
||||
* This simply does a count down of the @data->count field.
|
||||
*
|
||||
* If the @data->count is greater than zero, it will decrement it.
|
||||
*
|
||||
* Returns false if @data->count is zero, otherwise true.
|
||||
*/
|
||||
bool event_trigger_count(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
if (!data->count)
|
||||
return false;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* event_trigger_print - Generic event_trigger_ops @print implementation
|
||||
* @name: The name of the event trigger
|
||||
|
|
@ -807,9 +851,13 @@ int event_trigger_separate_filter(char *param_and_filter, char **param,
|
|||
* @private_data: User data to associate with the event trigger
|
||||
*
|
||||
* Allocate an event_trigger_data instance and initialize it. The
|
||||
* @cmd_ops are used along with the @cmd and @param to get the
|
||||
* trigger_ops to assign to the event_trigger_data. @private_data can
|
||||
* also be passed in and associated with the event_trigger_data.
|
||||
* @cmd_ops defines how the trigger will operate. If @param is set,
|
||||
* and @cmd_ops->trigger_ops->count_func is non NULL, then the
|
||||
* data->count is set to @param and before the trigger is executed, the
|
||||
* @cmd_ops->trigger_ops->count_func() is called. If that function returns
|
||||
* false, the @cmd_ops->trigger_ops->trigger() function will not be called.
|
||||
* @private_data can also be passed in and associated with the
|
||||
* event_trigger_data.
|
||||
*
|
||||
* Use trigger_data_free() to free an event_trigger_data object.
|
||||
*
|
||||
|
|
@ -821,18 +869,17 @@ struct event_trigger_data *trigger_data_alloc(struct event_command *cmd_ops,
|
|||
void *private_data)
|
||||
{
|
||||
struct event_trigger_data *trigger_data;
|
||||
const struct event_trigger_ops *trigger_ops;
|
||||
|
||||
trigger_ops = cmd_ops->get_trigger_ops(cmd, param);
|
||||
|
||||
trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
|
||||
if (!trigger_data)
|
||||
return NULL;
|
||||
|
||||
trigger_data->count = -1;
|
||||
trigger_data->ops = trigger_ops;
|
||||
trigger_data->ops = cmd_ops->trigger_ops;
|
||||
trigger_data->cmd_ops = cmd_ops;
|
||||
trigger_data->private_data = private_data;
|
||||
if (param && cmd_ops->trigger_ops->count_func)
|
||||
trigger_data->flags |= EVENT_TRIGGER_FL_COUNT;
|
||||
|
||||
INIT_LIST_HEAD(&trigger_data->list);
|
||||
INIT_LIST_HEAD(&trigger_data->named_list);
|
||||
|
|
@ -1271,31 +1318,28 @@ traceon_trigger(struct event_trigger_data *data,
|
|||
tracing_on();
|
||||
}
|
||||
|
||||
static void
|
||||
traceon_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
static bool
|
||||
traceon_count_func(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
struct trace_event_file *file = data->private_data;
|
||||
|
||||
if (file) {
|
||||
if (tracer_tracing_is_on(file->tr))
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
if (tracing_is_on())
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data->count)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
if (file)
|
||||
tracer_tracing_on(file->tr);
|
||||
else
|
||||
tracing_on();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1319,31 +1363,28 @@ traceoff_trigger(struct event_trigger_data *data,
|
|||
tracing_off();
|
||||
}
|
||||
|
||||
static void
|
||||
traceoff_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
static bool
|
||||
traceoff_count_func(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
struct trace_event_file *file = data->private_data;
|
||||
|
||||
if (file) {
|
||||
if (!tracer_tracing_is_on(file->tr))
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
if (!tracing_is_on())
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data->count)
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
if (file)
|
||||
tracer_tracing_off(file->tr);
|
||||
else
|
||||
tracing_off();
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1362,13 +1403,7 @@ traceoff_trigger_print(struct seq_file *m, struct event_trigger_data *data)
|
|||
|
||||
static const struct event_trigger_ops traceon_trigger_ops = {
|
||||
.trigger = traceon_trigger,
|
||||
.print = traceon_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops traceon_count_trigger_ops = {
|
||||
.trigger = traceon_count_trigger,
|
||||
.count_func = traceon_count_func,
|
||||
.print = traceon_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
|
|
@ -1376,41 +1411,19 @@ static const struct event_trigger_ops traceon_count_trigger_ops = {
|
|||
|
||||
static const struct event_trigger_ops traceoff_trigger_ops = {
|
||||
.trigger = traceoff_trigger,
|
||||
.count_func = traceoff_count_func,
|
||||
.print = traceoff_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops traceoff_count_trigger_ops = {
|
||||
.trigger = traceoff_count_trigger,
|
||||
.print = traceoff_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops *
|
||||
onoff_get_trigger_ops(char *cmd, char *param)
|
||||
{
|
||||
const struct event_trigger_ops *ops;
|
||||
|
||||
/* we register both traceon and traceoff to this callback */
|
||||
if (strcmp(cmd, "traceon") == 0)
|
||||
ops = param ? &traceon_count_trigger_ops :
|
||||
&traceon_trigger_ops;
|
||||
else
|
||||
ops = param ? &traceoff_count_trigger_ops :
|
||||
&traceoff_trigger_ops;
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static struct event_command trigger_traceon_cmd = {
|
||||
.name = "traceon",
|
||||
.trigger_type = ETT_TRACE_ONOFF,
|
||||
.trigger_ops = &traceon_trigger_ops,
|
||||
.parse = event_trigger_parse,
|
||||
.reg = register_trigger,
|
||||
.unreg = unregister_trigger,
|
||||
.get_trigger_ops = onoff_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
@ -1418,10 +1431,10 @@ static struct event_command trigger_traceoff_cmd = {
|
|||
.name = "traceoff",
|
||||
.trigger_type = ETT_TRACE_ONOFF,
|
||||
.flags = EVENT_CMD_FL_POST_TRIGGER,
|
||||
.trigger_ops = &traceoff_trigger_ops,
|
||||
.parse = event_trigger_parse,
|
||||
.reg = register_trigger,
|
||||
.unreg = unregister_trigger,
|
||||
.get_trigger_ops = onoff_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
@ -1439,20 +1452,6 @@ snapshot_trigger(struct event_trigger_data *data,
|
|||
tracing_snapshot();
|
||||
}
|
||||
|
||||
static void
|
||||
snapshot_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
if (!data->count)
|
||||
return;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
snapshot_trigger(data, buffer, rec, event);
|
||||
}
|
||||
|
||||
static int
|
||||
register_snapshot_trigger(char *glob,
|
||||
struct event_trigger_data *data,
|
||||
|
|
@ -1486,31 +1485,19 @@ snapshot_trigger_print(struct seq_file *m, struct event_trigger_data *data)
|
|||
|
||||
static const struct event_trigger_ops snapshot_trigger_ops = {
|
||||
.trigger = snapshot_trigger,
|
||||
.count_func = event_trigger_count,
|
||||
.print = snapshot_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops snapshot_count_trigger_ops = {
|
||||
.trigger = snapshot_count_trigger,
|
||||
.print = snapshot_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops *
|
||||
snapshot_get_trigger_ops(char *cmd, char *param)
|
||||
{
|
||||
return param ? &snapshot_count_trigger_ops : &snapshot_trigger_ops;
|
||||
}
|
||||
|
||||
static struct event_command trigger_snapshot_cmd = {
|
||||
.name = "snapshot",
|
||||
.trigger_type = ETT_SNAPSHOT,
|
||||
.trigger_ops = &snapshot_trigger_ops,
|
||||
.parse = event_trigger_parse,
|
||||
.reg = register_snapshot_trigger,
|
||||
.unreg = unregister_snapshot_trigger,
|
||||
.get_trigger_ops = snapshot_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
@ -1558,20 +1545,6 @@ stacktrace_trigger(struct event_trigger_data *data,
|
|||
trace_dump_stack(STACK_SKIP);
|
||||
}
|
||||
|
||||
static void
|
||||
stacktrace_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
if (!data->count)
|
||||
return;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
stacktrace_trigger(data, buffer, rec, event);
|
||||
}
|
||||
|
||||
static int
|
||||
stacktrace_trigger_print(struct seq_file *m, struct event_trigger_data *data)
|
||||
{
|
||||
|
|
@ -1581,32 +1554,20 @@ stacktrace_trigger_print(struct seq_file *m, struct event_trigger_data *data)
|
|||
|
||||
static const struct event_trigger_ops stacktrace_trigger_ops = {
|
||||
.trigger = stacktrace_trigger,
|
||||
.count_func = event_trigger_count,
|
||||
.print = stacktrace_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops stacktrace_count_trigger_ops = {
|
||||
.trigger = stacktrace_count_trigger,
|
||||
.print = stacktrace_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops *
|
||||
stacktrace_get_trigger_ops(char *cmd, char *param)
|
||||
{
|
||||
return param ? &stacktrace_count_trigger_ops : &stacktrace_trigger_ops;
|
||||
}
|
||||
|
||||
static struct event_command trigger_stacktrace_cmd = {
|
||||
.name = "stacktrace",
|
||||
.trigger_type = ETT_STACKTRACE,
|
||||
.trigger_ops = &stacktrace_trigger_ops,
|
||||
.flags = EVENT_CMD_FL_POST_TRIGGER,
|
||||
.parse = event_trigger_parse,
|
||||
.reg = register_trigger,
|
||||
.unreg = unregister_trigger,
|
||||
.get_trigger_ops = stacktrace_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
@ -1642,24 +1603,24 @@ event_enable_trigger(struct event_trigger_data *data,
|
|||
set_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &enable_data->file->flags);
|
||||
}
|
||||
|
||||
static void
|
||||
event_enable_count_trigger(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
static bool
|
||||
event_enable_count_func(struct event_trigger_data *data,
|
||||
struct trace_buffer *buffer, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
struct enable_trigger_data *enable_data = data->private_data;
|
||||
|
||||
if (!data->count)
|
||||
return;
|
||||
return false;
|
||||
|
||||
/* Skip if the event is in a state we want to switch to */
|
||||
if (enable_data->enable == !(enable_data->file->flags & EVENT_FILE_FL_SOFT_DISABLED))
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (data->count != -1)
|
||||
(data->count)--;
|
||||
|
||||
event_enable_trigger(data, buffer, rec, event);
|
||||
return true;
|
||||
}
|
||||
|
||||
int event_enable_trigger_print(struct seq_file *m,
|
||||
|
|
@ -1706,13 +1667,7 @@ void event_enable_trigger_free(struct event_trigger_data *data)
|
|||
|
||||
static const struct event_trigger_ops event_enable_trigger_ops = {
|
||||
.trigger = event_enable_trigger,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops event_enable_count_trigger_ops = {
|
||||
.trigger = event_enable_count_trigger,
|
||||
.count_func = event_enable_count_func,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
|
|
@ -1720,13 +1675,7 @@ static const struct event_trigger_ops event_enable_count_trigger_ops = {
|
|||
|
||||
static const struct event_trigger_ops event_disable_trigger_ops = {
|
||||
.trigger = event_enable_trigger,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
};
|
||||
|
||||
static const struct event_trigger_ops event_disable_count_trigger_ops = {
|
||||
.trigger = event_enable_count_trigger,
|
||||
.count_func = event_enable_count_func,
|
||||
.print = event_enable_trigger_print,
|
||||
.init = event_trigger_init,
|
||||
.free = event_enable_trigger_free,
|
||||
|
|
@ -1906,45 +1855,23 @@ void event_enable_unregister_trigger(char *glob,
|
|||
data->ops->free(data);
|
||||
}
|
||||
|
||||
static const struct event_trigger_ops *
|
||||
event_enable_get_trigger_ops(char *cmd, char *param)
|
||||
{
|
||||
const struct event_trigger_ops *ops;
|
||||
bool enable;
|
||||
|
||||
#ifdef CONFIG_HIST_TRIGGERS
|
||||
enable = ((strcmp(cmd, ENABLE_EVENT_STR) == 0) ||
|
||||
(strcmp(cmd, ENABLE_HIST_STR) == 0));
|
||||
#else
|
||||
enable = strcmp(cmd, ENABLE_EVENT_STR) == 0;
|
||||
#endif
|
||||
if (enable)
|
||||
ops = param ? &event_enable_count_trigger_ops :
|
||||
&event_enable_trigger_ops;
|
||||
else
|
||||
ops = param ? &event_disable_count_trigger_ops :
|
||||
&event_disable_trigger_ops;
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static struct event_command trigger_enable_cmd = {
|
||||
.name = ENABLE_EVENT_STR,
|
||||
.trigger_type = ETT_EVENT_ENABLE,
|
||||
.trigger_ops = &event_enable_trigger_ops,
|
||||
.parse = event_enable_trigger_parse,
|
||||
.reg = event_enable_register_trigger,
|
||||
.unreg = event_enable_unregister_trigger,
|
||||
.get_trigger_ops = event_enable_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
static struct event_command trigger_disable_cmd = {
|
||||
.name = DISABLE_EVENT_STR,
|
||||
.trigger_type = ETT_EVENT_ENABLE,
|
||||
.trigger_ops = &event_disable_trigger_ops,
|
||||
.parse = event_enable_trigger_parse,
|
||||
.reg = event_enable_register_trigger,
|
||||
.unreg = event_enable_unregister_trigger,
|
||||
.get_trigger_ops = event_enable_get_trigger_ops,
|
||||
.set_filter = set_trigger_filter,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user