aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-03-25 23:39:41 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-03-25 23:39:41 -0400
commit2c4a33aba5f9ea3a28f2e40351f078d95f00786b (patch)
tree657da8f44eaa6331bd8bfa4789f10b152bc8104c /kernel
parent87291347c49dc40aa339f587b209618201c2e527 (diff)
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/trace.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 815c878f409b..24c1f2382557 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1600,15 +1600,31 @@ void trace_buffer_unlock_commit(struct ring_buffer *buffer,
1600} 1600}
1601EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); 1601EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit);
1602 1602
1603static struct ring_buffer *temp_buffer;
1604
1603struct ring_buffer_event * 1605struct ring_buffer_event *
1604trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, 1606trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
1605 struct ftrace_event_file *ftrace_file, 1607 struct ftrace_event_file *ftrace_file,
1606 int type, unsigned long len, 1608 int type, unsigned long len,
1607 unsigned long flags, int pc) 1609 unsigned long flags, int pc)
1608{ 1610{
1611 struct ring_buffer_event *entry;
1612
1609 *current_rb = ftrace_file->tr->trace_buffer.buffer; 1613 *current_rb = ftrace_file->tr->trace_buffer.buffer;
1610 return trace_buffer_lock_reserve(*current_rb, 1614 entry = trace_buffer_lock_reserve(*current_rb,
1611 type, len, flags, pc); 1615 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;
1612} 1628}
1613EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve); 1629EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve);
1614 1630
@@ -6494,11 +6510,16 @@ __init static int tracer_alloc_buffers(void)
6494 6510
6495 raw_spin_lock_init(&global_trace.start_lock); 6511 raw_spin_lock_init(&global_trace.start_lock);
6496 6512
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
6497 /* TODO: make the number of buffers hot pluggable with CPUS */ 6518 /* TODO: make the number of buffers hot pluggable with CPUS */
6498 if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { 6519 if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
6499 printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); 6520 printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
6500 WARN_ON(1); 6521 WARN_ON(1);
6501 goto out_free_cpumask; 6522 goto out_free_temp_buffer;
6502 } 6523 }
6503 6524
6504 if (global_trace.buffer_disabled) 6525 if (global_trace.buffer_disabled)
@@ -6540,6 +6561,8 @@ __init static int tracer_alloc_buffers(void)
6540 6561
6541 return 0; 6562 return 0;
6542 6563
6564out_free_temp_buffer:
6565 ring_buffer_free(temp_buffer);
6543out_free_cpumask: 6566out_free_cpumask:
6544 free_percpu(global_trace.trace_buffer.data); 6567 free_percpu(global_trace.trace_buffer.data);
6545#ifdef CONFIG_TRACER_MAX_TRACE 6568#ifdef CONFIG_TRACER_MAX_TRACE