Skip to content

Commit

Permalink
tracing: Make the snapshot trigger work with instances
Browse files Browse the repository at this point in the history
The snapshot trigger currently only affects the main ring buffer, even when
it is used by the instances. This can be confusing as the snapshot trigger
is listed in the instance.

 > # cd /sys/kernel/tracing
 > # mkdir instances/foo
 > # echo snapshot > instances/foo/events/syscalls/sys_enter_fchownat/trigger
 > # echo top buffer > trace_marker
 > # echo foo buffer > instances/foo/trace_marker
 > # touch /tmp/bar
 > # chown rostedt /tmp/bar
 > # cat instances/foo/snapshot
 # tracer: nop
 #
 #
 # * Snapshot is freed *
 #
 # Snapshot commands:
 # echo 0 > snapshot : Clears and frees snapshot buffer
 # echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.
 #                      Takes a snapshot of the main buffer.
 # echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)
 #                      (Doesn't have to be '2' works with any number that
 #                       is not a '0' or '1')

 > # cat snapshot
 # tracer: nop
 #
 #                              _-----=> irqs-off
 #                             / _----=> need-resched
 #                            | / _---=> hardirq/softirq
 #                            || / _--=> preempt-depth
 #                            ||| /     delay
 #           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
 #              | |       |   ||||       |         |
             bash-1189  [000] ....   111.488323: tracing_mark_write: top buffer

Not only did the snapshot occur in the top level buffer, but the instance
snapshot buffer should have been allocated, and it is still free.

Cc: [email protected]
Fixes: 85f2b08 ("tracing: Add basic event trigger framework")
Signed-off-by: Steven Rostedt (VMware) <[email protected]>
  • Loading branch information
rostedt committed May 28, 2018
1 parent 86b389f commit 2824f50
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
12 changes: 6 additions & 6 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down
11 changes: 11 additions & 0 deletions kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
10 changes: 8 additions & 2 deletions kernel/trace/trace_events_trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,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);

Expand Down Expand Up @@ -1054,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
Expand All @@ -1077,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;
}
Expand Down

0 comments on commit 2824f50

Please sign in to comment.