diff options
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r-- | kernel/trace/trace.c | 27 |
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 | } |
1601 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); | 1601 | EXPORT_SYMBOL_GPL(trace_buffer_unlock_commit); |
1602 | 1602 | ||
1603 | static struct ring_buffer *temp_buffer; | ||
1604 | |||
1603 | struct ring_buffer_event * | 1605 | struct ring_buffer_event * |
1604 | trace_event_buffer_lock_reserve(struct ring_buffer **current_rb, | 1606 | trace_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 | } |
1613 | EXPORT_SYMBOL_GPL(trace_event_buffer_lock_reserve); | 1629 | EXPORT_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 | ||
6564 | out_free_temp_buffer: | ||
6565 | ring_buffer_free(temp_buffer); | ||
6543 | out_free_cpumask: | 6566 | out_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 |