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

Changed files
+25 -2
kernel
trace
+25 -2
kernel/trace/trace.c
··· 1600 1600 } 1601 1601 EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); 1602 1602 1603 + static struct ring_buffer *temp_buffer; 1604 + 1603 1605 struct ring_buffer_event * 1604 1606 trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, 1605 1607 struct ftrace_event_file *ftrace_file, 1606 1608 int type, unsigned long len, 1607 1609 unsigned long flags, int pc) 1608 1610 { 1611 + struct ring_buffer_event *entry; 1612 + 1609 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 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 } 1613 1629 EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve); 1614 1630 ··· 6510 6494 6511 6495 raw_spin_lock_init(&global_trace.start_lock); 6512 6496 6497 + /* Used for event triggers */ 6498 + temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE); 6499 + if (!temp_buffer) 6500 + goto out_free_cpumask; 6501 + 6513 6502 /* TODO: make the number of buffers hot pluggable with CPUS */ 6514 6503 if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { 6515 6504 printk(KERN_ERR "tracer: failed to allocate ring buffer!\n"); 6516 6505 WARN_ON(1); 6517 - goto out_free_cpumask; 6506 + goto out_free_temp_buffer; 6518 6507 } 6519 6508 6520 6509 if (global_trace.buffer_disabled) ··· 6561 6540 6562 6541 return 0; 6563 6542 6543 + out_free_temp_buffer: 6544 + ring_buffer_free(temp_buffer); 6564 6545 out_free_cpumask: 6565 6546 free_percpu(global_trace.trace_buffer.data); 6566 6547 #ifdef CONFIG_TRACER_MAX_TRACE