diff options
-rw-r--r-- | include/linux/ftrace_event.h | 15 | ||||
-rw-r--r-- | include/trace/ftrace.h | 22 | ||||
-rw-r--r-- | kernel/trace/trace_events.c | 30 |
3 files changed, 51 insertions, 16 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index ffe642eb84fa..9d3fe0658398 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -206,6 +206,21 @@ int ftrace_event_define_field(struct ftrace_event_call *call, | |||
206 | char *type, int len, char *item, int offset, | 206 | char *type, int len, char *item, int offset, |
207 | int field_size, int sign, int filter); | 207 | int field_size, int sign, int filter); |
208 | 208 | ||
209 | struct ftrace_event_buffer { | ||
210 | struct ring_buffer *buffer; | ||
211 | struct ring_buffer_event *event; | ||
212 | struct ftrace_event_file *ftrace_file; | ||
213 | void *entry; | ||
214 | unsigned long flags; | ||
215 | int pc; | ||
216 | }; | ||
217 | |||
218 | void *ftrace_event_buffer_reserve(struct ftrace_event_buffer *fbuffer, | ||
219 | struct ftrace_event_file *ftrace_file, | ||
220 | unsigned long len); | ||
221 | |||
222 | void ftrace_event_buffer_commit(struct ftrace_event_buffer *fbuffer); | ||
223 | |||
209 | enum { | 224 | enum { |
210 | TRACE_EVENT_FL_FILTERED_BIT, | 225 | TRACE_EVENT_FL_FILTERED_BIT, |
211 | TRACE_EVENT_FL_CAP_ANY_BIT, | 226 | TRACE_EVENT_FL_CAP_ANY_BIT, |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 54928faf2119..1cc2265caa52 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -532,37 +532,27 @@ static notrace void \ | |||
532 | ftrace_raw_event_##call(void *__data, proto) \ | 532 | ftrace_raw_event_##call(void *__data, proto) \ |
533 | { \ | 533 | { \ |
534 | struct ftrace_event_file *ftrace_file = __data; \ | 534 | struct ftrace_event_file *ftrace_file = __data; \ |
535 | struct ftrace_event_call *event_call = ftrace_file->event_call; \ | ||
536 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ | 535 | struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ |
537 | struct ring_buffer_event *event; \ | 536 | struct ftrace_event_buffer fbuffer; \ |
538 | struct ftrace_raw_##call *entry; \ | 537 | struct ftrace_raw_##call *entry; \ |
539 | struct ring_buffer *buffer; \ | ||
540 | unsigned long irq_flags; \ | ||
541 | int __data_size; \ | 538 | int __data_size; \ |
542 | int pc; \ | ||
543 | \ | 539 | \ |
544 | if (ftrace_trigger_soft_disabled(ftrace_file)) \ | 540 | if (ftrace_trigger_soft_disabled(ftrace_file)) \ |
545 | return; \ | 541 | return; \ |
546 | \ | 542 | \ |
547 | local_save_flags(irq_flags); \ | ||
548 | pc = preempt_count(); \ | ||
549 | \ | ||
550 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ | 543 | __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ |
551 | \ | 544 | \ |
552 | event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, \ | 545 | entry = ftrace_event_buffer_reserve(&fbuffer, ftrace_file, \ |
553 | event_call->event.type, \ | 546 | sizeof(*entry) + __data_size); \ |
554 | sizeof(*entry) + __data_size, \ | 547 | \ |
555 | irq_flags, pc); \ | 548 | if (!entry) \ |
556 | if (!event) \ | ||
557 | return; \ | 549 | return; \ |
558 | entry = ring_buffer_event_data(event); \ | ||
559 | \ | 550 | \ |
560 | tstruct \ | 551 | tstruct \ |
561 | \ | 552 | \ |
562 | { assign; } \ | 553 | { assign; } \ |
563 | \ | 554 | \ |
564 | event_trigger_unlock_commit(ftrace_file, buffer, event, entry, \ | 555 | ftrace_event_buffer_commit(&fbuffer); \ |
565 | irq_flags, pc); \ | ||
566 | } | 556 | } |
567 | /* | 557 | /* |
568 | * The ftrace_test_probe is compiled out, it is only here as a build time check | 558 | * The ftrace_test_probe is compiled out, it is only here as a build time check |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 22826c73a9da..b8f73b333a3c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -188,6 +188,36 @@ int trace_event_raw_init(struct ftrace_event_call *call) | |||
188 | } | 188 | } |
189 | EXPORT_SYMBOL_GPL(trace_event_raw_init); | 189 | EXPORT_SYMBOL_GPL(trace_event_raw_init); |
190 | 190 | ||
191 | void *ftrace_event_buffer_reserve(struct ftrace_event_buffer *fbuffer, | ||
192 | struct ftrace_event_file *ftrace_file, | ||
193 | unsigned long len) | ||
194 | { | ||
195 | struct ftrace_event_call *event_call = ftrace_file->event_call; | ||
196 | |||
197 | local_save_flags(fbuffer->flags); | ||
198 | fbuffer->pc = preempt_count(); | ||
199 | fbuffer->ftrace_file = ftrace_file; | ||
200 | |||
201 | fbuffer->event = | ||
202 | trace_event_buffer_lock_reserve(&fbuffer->buffer, ftrace_file, | ||
203 | event_call->event.type, len, | ||
204 | fbuffer->flags, fbuffer->pc); | ||
205 | if (!fbuffer->event) | ||
206 | return NULL; | ||
207 | |||
208 | fbuffer->entry = ring_buffer_event_data(fbuffer->event); | ||
209 | return fbuffer->entry; | ||
210 | } | ||
211 | EXPORT_SYMBOL_GPL(ftrace_event_buffer_reserve); | ||
212 | |||
213 | void ftrace_event_buffer_commit(struct ftrace_event_buffer *fbuffer) | ||
214 | { | ||
215 | event_trigger_unlock_commit(fbuffer->ftrace_file, fbuffer->buffer, | ||
216 | fbuffer->event, fbuffer->entry, | ||
217 | fbuffer->flags, fbuffer->pc); | ||
218 | } | ||
219 | EXPORT_SYMBOL_GPL(ftrace_event_buffer_commit); | ||
220 | |||
191 | int ftrace_event_reg(struct ftrace_event_call *call, | 221 | int ftrace_event_reg(struct ftrace_event_call *call, |
192 | enum trace_reg type, void *data) | 222 | enum trace_reg type, void *data) |
193 | { | 223 | { |