Merge tag 'trace-v4.17-rc4-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fixes from Steven Rostedt: "While writing selftests for a new feature, I triggered two existing bugs that deal with triggers and instances. - a generic trigger bug where the triggers are not removed from a linked list properly when deleting an instance. - a bug specific to snapshots, where the snapshot is done in the top level buffer, when it is supposed to snapshot the buffer associated to the instance the snapshot trigger exists in" * tag 'trace-v4.17-rc4-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Make the snapshot trigger work with instances tracing: Fix crash when freeing instances with event triggers
This commit is contained in:
@@ -893,7 +893,7 @@ int __trace_bputs(unsigned long ip, const char *str)
|
||||
EXPORT_SYMBOL_GPL(__trace_bputs);
|
||||
|
||||
#ifdef CONFIG_TRACER_SNAPSHOT
|
||||
static void tracing_snapshot_instance(struct trace_array *tr)
|
||||
void tracing_snapshot_instance(struct trace_array *tr)
|
||||
{
|
||||
struct tracer *tracer = tr->current_trace;
|
||||
unsigned long flags;
|
||||
@@ -949,7 +949,7 @@ static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
|
||||
struct trace_buffer *size_buf, int cpu_id);
|
||||
static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);
|
||||
|
||||
static int alloc_snapshot(struct trace_array *tr)
|
||||
int tracing_alloc_snapshot_instance(struct trace_array *tr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -995,7 +995,7 @@ int tracing_alloc_snapshot(void)
|
||||
struct trace_array *tr = &global_trace;
|
||||
int ret;
|
||||
|
||||
ret = alloc_snapshot(tr);
|
||||
ret = tracing_alloc_snapshot_instance(tr);
|
||||
WARN_ON(ret < 0);
|
||||
|
||||
return ret;
|
||||
@@ -5408,7 +5408,7 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf)
|
||||
|
||||
#ifdef CONFIG_TRACER_MAX_TRACE
|
||||
if (t->use_max_tr && !had_max_tr) {
|
||||
ret = alloc_snapshot(tr);
|
||||
ret = tracing_alloc_snapshot_instance(tr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
@@ -6451,7 +6451,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||
}
|
||||
#endif
|
||||
if (!tr->allocated_snapshot) {
|
||||
ret = alloc_snapshot(tr);
|
||||
ret = tracing_alloc_snapshot_instance(tr);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
@@ -7179,7 +7179,7 @@ ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash,
|
||||
return ret;
|
||||
|
||||
out_reg:
|
||||
ret = alloc_snapshot(tr);
|
||||
ret = tracing_alloc_snapshot_instance(tr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
|
@@ -1817,6 +1817,17 @@ static inline void __init trace_event_init(void) { }
|
||||
static inline void trace_event_eval_update(struct trace_eval_map **map, int len) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACER_SNAPSHOT
|
||||
void tracing_snapshot_instance(struct trace_array *tr);
|
||||
int tracing_alloc_snapshot_instance(struct trace_array *tr);
|
||||
#else
|
||||
static inline void tracing_snapshot_instance(struct trace_array *tr) { }
|
||||
static inline int tracing_alloc_snapshot_instance(struct trace_array *tr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct trace_iterator *tracepoint_print_iter;
|
||||
|
||||
#endif /* _LINUX_KERNEL_TRACE_H */
|
||||
|
@@ -483,9 +483,10 @@ clear_event_triggers(struct trace_array *tr)
|
||||
struct trace_event_file *file;
|
||||
|
||||
list_for_each_entry(file, &tr->events, list) {
|
||||
struct event_trigger_data *data;
|
||||
list_for_each_entry_rcu(data, &file->triggers, list) {
|
||||
struct event_trigger_data *data, *n;
|
||||
list_for_each_entry_safe(data, n, &file->triggers, list) {
|
||||
trace_event_trigger_enable_disable(file, 0);
|
||||
list_del_rcu(&data->list);
|
||||
if (data->ops->free)
|
||||
data->ops->free(data->ops, data);
|
||||
}
|
||||
@@ -642,6 +643,7 @@ event_trigger_callback(struct event_command *cmd_ops,
|
||||
trigger_data->count = -1;
|
||||
trigger_data->ops = trigger_ops;
|
||||
trigger_data->cmd_ops = cmd_ops;
|
||||
trigger_data->private_data = file;
|
||||
INIT_LIST_HEAD(&trigger_data->list);
|
||||
INIT_LIST_HEAD(&trigger_data->named_list);
|
||||
|
||||
@@ -1053,7 +1055,12 @@ static void
|
||||
snapshot_trigger(struct event_trigger_data *data, void *rec,
|
||||
struct ring_buffer_event *event)
|
||||
{
|
||||
tracing_snapshot();
|
||||
struct trace_event_file *file = data->private_data;
|
||||
|
||||
if (file)
|
||||
tracing_snapshot_instance(file->tr);
|
||||
else
|
||||
tracing_snapshot();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1076,7 +1083,7 @@ register_snapshot_trigger(char *glob, struct event_trigger_ops *ops,
|
||||
{
|
||||
int ret = register_trigger(glob, ops, data, file);
|
||||
|
||||
if (ret > 0 && tracing_alloc_snapshot() != 0) {
|
||||
if (ret > 0 && tracing_alloc_snapshot_instance(file->tr) != 0) {
|
||||
unregister_trigger(glob, ops, data, file);
|
||||
ret = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user