Skip to content

Commit 2c4a33a

Browse files
committed
tracing: Fix traceon trigger condition to actually turn tracing on
While working on my tutorial for 2014 Linux Collaboration Summit I found that the traceon trigger did not work when conditions were used. The other triggers worked fine though. Looking into it, it is because of the way the triggers use the ring buffer to store the fields it will use for the condition. But if tracing is off, nothing is stored in the buffer, and the tracepoint exits before calling the trigger to test the condition. This is fine for all the triggers that only work when tracing is on, but for traceon trigger that is to work when tracing is off, nothing happens. The fix is simple, just use a temp ring buffer to record the event if tracing is off and the event has a trace event conditional trigger enabled. The rest of the tracepoint code will work just fine, but the tracepoint wont be recorded in the other buffers. Cc: Tom Zanussi <tom.zanussi@linux.intel.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
1 parent 8729134 commit 2c4a33a

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

kernel/trace/trace.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,15 +1600,31 @@ void trace_buffer_unlock_commit(struct ring_buffer *buffer,
16001600
}
16011601
EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit);
16021602

1603+
static struct ring_buffer *temp_buffer;
1604+
16031605
struct ring_buffer_event *
16041606
trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
16051607
struct ftrace_event_file *ftrace_file,
16061608
int type, unsigned long len,
16071609
unsigned long flags, int pc)
16081610
{
1611+
struct ring_buffer_event *entry;
1612+
16091613
*current_rb = ftrace_file->tr->trace_buffer.buffer;
1610-
return trace_buffer_lock_reserve(*current_rb,
1614+
entry = trace_buffer_lock_reserve(*current_rb,
16111615
type, len, flags, pc);
1616+
/*
1617+
* If tracing is off, but we have triggers enabled
1618+
* we still need to look at the event data. Use the temp_buffer
1619+
* to store the trace event for the tigger to use. It's recusive
1620+
* safe and will not be recorded anywhere.
1621+
*/
1622+
if (!entry && ftrace_file->flags & FTRACE_EVENT_FL_TRIGGER_COND) {
1623+
*current_rb = temp_buffer;
1624+
entry = trace_buffer_lock_reserve(*current_rb,
1625+
type, len, flags, pc);
1626+
}
1627+
return entry;
16121628
}
16131629
EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve);
16141630

@@ -6494,11 +6510,16 @@ __init static int tracer_alloc_buffers(void)
64946510

64956511
raw_spin_lock_init(&global_trace.start_lock);
64966512

6513+
/* Used for event triggers */
6514+
temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE);
6515+
if (!temp_buffer)
6516+
goto out_free_cpumask;
6517+
64976518
/* TODO: make the number of buffers hot pluggable with CPUS */
64986519
if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
64996520
printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
65006521
WARN_ON(1);
6501-
goto out_free_cpumask;
6522+
goto out_free_temp_buffer;
65026523
}
65036524

65046525
if (global_trace.buffer_disabled)
@@ -6540,6 +6561,8 @@ __init static int tracer_alloc_buffers(void)
65406561

65416562
return 0;
65426563

6564+
out_free_temp_buffer:
6565+
ring_buffer_free(temp_buffer);
65436566
out_free_cpumask:
65446567
free_percpu(global_trace.trace_buffer.data);
65456568
#ifdef CONFIG_TRACER_MAX_TRACE

0 commit comments

Comments
 (0)