aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-05-29 08:28:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-05-29 08:28:48 -0400
commit3d661e2a2d1cf0ad1ce54d690f05e755da59e6c9 (patch)
treea87b5aa09ec63289fd14dcdbdc761e1f72a4f4a8 /kernel
parent786b71f5b754273ccef6d9462e52062b3e1f9877 (diff)
parent2824f5033248600673e3e126a4d135363cbfd9ac (diff)
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
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace.c12
-rw-r--r--kernel/trace/trace.h11
-rw-r--r--kernel/trace/trace_events_trigger.c15
3 files changed, 28 insertions, 10 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 414d7210b2ec..bcd93031d042 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -893,7 +893,7 @@ int __trace_bputs(unsigned long ip, const char *str)
893EXPORT_SYMBOL_GPL(__trace_bputs); 893EXPORT_SYMBOL_GPL(__trace_bputs);
894 894
895#ifdef CONFIG_TRACER_SNAPSHOT 895#ifdef CONFIG_TRACER_SNAPSHOT
896static void tracing_snapshot_instance(struct trace_array *tr) 896void tracing_snapshot_instance(struct trace_array *tr)
897{ 897{
898 struct tracer *tracer = tr->current_trace; 898 struct tracer *tracer = tr->current_trace;
899 unsigned long flags; 899 unsigned long flags;
@@ -949,7 +949,7 @@ static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
949 struct trace_buffer *size_buf, int cpu_id); 949 struct trace_buffer *size_buf, int cpu_id);
950static void set_buffer_entries(struct trace_buffer *buf, unsigned long val); 950static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);
951 951
952static int alloc_snapshot(struct trace_array *tr) 952int tracing_alloc_snapshot_instance(struct trace_array *tr)
953{ 953{
954 int ret; 954 int ret;
955 955
@@ -995,7 +995,7 @@ int tracing_alloc_snapshot(void)
995 struct trace_array *tr = &global_trace; 995 struct trace_array *tr = &global_trace;
996 int ret; 996 int ret;
997 997
998 ret = alloc_snapshot(tr); 998 ret = tracing_alloc_snapshot_instance(tr);
999 WARN_ON(ret < 0); 999 WARN_ON(ret < 0);
1000 1000
1001 return ret; 1001 return ret;
@@ -5408,7 +5408,7 @@ static int tracing_set_tracer(struct trace_array *tr, const char *buf)
5408 5408
5409#ifdef CONFIG_TRACER_MAX_TRACE 5409#ifdef CONFIG_TRACER_MAX_TRACE
5410 if (t->use_max_tr && !had_max_tr) { 5410 if (t->use_max_tr && !had_max_tr) {
5411 ret = alloc_snapshot(tr); 5411 ret = tracing_alloc_snapshot_instance(tr);
5412 if (ret < 0) 5412 if (ret < 0)
5413 goto out; 5413 goto out;
5414 } 5414 }
@@ -6451,7 +6451,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
6451 } 6451 }
6452#endif 6452#endif
6453 if (!tr->allocated_snapshot) { 6453 if (!tr->allocated_snapshot) {
6454 ret = alloc_snapshot(tr); 6454 ret = tracing_alloc_snapshot_instance(tr);
6455 if (ret < 0) 6455 if (ret < 0)
6456 break; 6456 break;
6457 } 6457 }
@@ -7179,7 +7179,7 @@ ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash,
7179 return ret; 7179 return ret;
7180 7180
7181 out_reg: 7181 out_reg:
7182 ret = alloc_snapshot(tr); 7182 ret = tracing_alloc_snapshot_instance(tr);
7183 if (ret < 0) 7183 if (ret < 0)
7184 goto out; 7184 goto out;
7185 7185
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 6fb46a06c9dc..507954b4e058 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1817,6 +1817,17 @@ static inline void __init trace_event_init(void) { }
1817static inline void trace_event_eval_update(struct trace_eval_map **map, int len) { } 1817static inline void trace_event_eval_update(struct trace_eval_map **map, int len) { }
1818#endif 1818#endif
1819 1819
1820#ifdef CONFIG_TRACER_SNAPSHOT
1821void tracing_snapshot_instance(struct trace_array *tr);
1822int tracing_alloc_snapshot_instance(struct trace_array *tr);
1823#else
1824static inline void tracing_snapshot_instance(struct trace_array *tr) { }
1825static inline int tracing_alloc_snapshot_instance(struct trace_array *tr)
1826{
1827 return 0;
1828}
1829#endif
1830
1820extern struct trace_iterator *tracepoint_print_iter; 1831extern struct trace_iterator *tracepoint_print_iter;
1821 1832
1822#endif /* _LINUX_KERNEL_TRACE_H */ 1833#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index d251cabcf69a..8b5bdcf64871 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -483,9 +483,10 @@ clear_event_triggers(struct trace_array *tr)
483 struct trace_event_file *file; 483 struct trace_event_file *file;
484 484
485 list_for_each_entry(file, &tr->events, list) { 485 list_for_each_entry(file, &tr->events, list) {
486 struct event_trigger_data *data; 486 struct event_trigger_data *data, *n;
487 list_for_each_entry_rcu(data, &file->triggers, list) { 487 list_for_each_entry_safe(data, n, &file->triggers, list) {
488 trace_event_trigger_enable_disable(file, 0); 488 trace_event_trigger_enable_disable(file, 0);
489 list_del_rcu(&data->list);
489 if (data->ops->free) 490 if (data->ops->free)
490 data->ops->free(data->ops, data); 491 data->ops->free(data->ops, data);
491 } 492 }
@@ -642,6 +643,7 @@ event_trigger_callback(struct event_command *cmd_ops,
642 trigger_data->count = -1; 643 trigger_data->count = -1;
643 trigger_data->ops = trigger_ops; 644 trigger_data->ops = trigger_ops;
644 trigger_data->cmd_ops = cmd_ops; 645 trigger_data->cmd_ops = cmd_ops;
646 trigger_data->private_data = file;
645 INIT_LIST_HEAD(&trigger_data->list); 647 INIT_LIST_HEAD(&trigger_data->list);
646 INIT_LIST_HEAD(&trigger_data->named_list); 648 INIT_LIST_HEAD(&trigger_data->named_list);
647 649
@@ -1053,7 +1055,12 @@ static void
1053snapshot_trigger(struct event_trigger_data *data, void *rec, 1055snapshot_trigger(struct event_trigger_data *data, void *rec,
1054 struct ring_buffer_event *event) 1056 struct ring_buffer_event *event)
1055{ 1057{
1056 tracing_snapshot(); 1058 struct trace_event_file *file = data->private_data;
1059
1060 if (file)
1061 tracing_snapshot_instance(file->tr);
1062 else
1063 tracing_snapshot();
1057} 1064}
1058 1065
1059static void 1066static void
@@ -1076,7 +1083,7 @@ register_snapshot_trigger(char *glob, struct event_trigger_ops *ops,
1076{ 1083{
1077 int ret = register_trigger(glob, ops, data, file); 1084 int ret = register_trigger(glob, ops, data, file);
1078 1085
1079 if (ret > 0 && tracing_alloc_snapshot() != 0) { 1086 if (ret > 0 && tracing_alloc_snapshot_instance(file->tr) != 0) {
1080 unregister_trigger(glob, ops, data, file); 1087 unregister_trigger(glob, ops, data, file);
1081 ret = 0; 1088 ret = 0;
1082 } 1089 }