Skip to content

Commit f217c44

Browse files
committed
Merge tag 'trace-fixes-v3.14-rc7-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing fix from Steven Rostedt: "While on my flight to Linux Collaboration Summit, I was working on my slides for the event trigger tutorial. I booted a 3.14-rc7 kernel to perform what I wanted to teach and cut and paste it into my slides. When I tried the traceon event trigger with a condition attached to it (turns tracing on only if a field of the trigger event matches a condition set by the user), nothing happened. Tracing would not turn on. I stopped working on my presentation in order to find what was wrong. It ended up being the way trace event triggers work when they have conditions. Instead of copying the fields, the condition code just looks at the fields that were copied into the ring buffer. This works great, unless tracing is off. That's because when the event is reserved on the ring buffer, the ring buffer returns a NULL pointer, this tells the tracing code that the ring buffer is disabled. This ends up being a problem for the traceon trigger if it is using this information to check its condition. Luckily the code that checks if tracing is on returns the ring buffer to use (because the ring buffer is determined by the event file also passed to that field). I was able to easily solve this bug by checking in that helper function if the returned ring buffer entry is NULL, and if so, also check the file flag if it has a trace event trigger condition, and if so, to pass back a temp ring buffer to use. This will allow the trace event trigger condition to still test the event fields, but nothing will be recorded" * tag 'trace-fixes-v3.14-rc7-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: tracing: Fix traceon trigger condition to actually turn tracing on
2 parents fce7fc7 + 2c4a33a commit f217c44

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)