aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/ftrace_event.h117
-rw-r--r--include/trace/ftrace.h23
2 files changed, 121 insertions, 19 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 03d2db22ad0d..4e4cc28623ad 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -370,6 +370,123 @@ extern enum event_trigger_type event_triggers_call(struct ftrace_event_file *fil
370extern void event_triggers_post_call(struct ftrace_event_file *file, 370extern void event_triggers_post_call(struct ftrace_event_file *file,
371 enum event_trigger_type tt); 371 enum event_trigger_type tt);
372 372
373/**
374 * ftrace_trigger_soft_disabled - do triggers and test if soft disabled
375 * @file: The file pointer of the event to test
376 *
377 * If any triggers without filters are attached to this event, they
378 * will be called here. If the event is soft disabled and has no
379 * triggers that require testing the fields, it will return true,
380 * otherwise false.
381 */
382static inline bool
383ftrace_trigger_soft_disabled(struct ftrace_event_file *file)
384{
385 unsigned long eflags = file->flags;
386
387 if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) {
388 if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE)
389 event_triggers_call(file, NULL);
390 if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED)
391 return true;
392 }
393 return false;
394}
395
396/*
397 * Helper function for event_trigger_unlock_commit{_regs}().
398 * If there are event triggers attached to this event that requires
399 * filtering against its fields, then they wil be called as the
400 * entry already holds the field information of the current event.
401 *
402 * It also checks if the event should be discarded or not.
403 * It is to be discarded if the event is soft disabled and the
404 * event was only recorded to process triggers, or if the event
405 * filter is active and this event did not match the filters.
406 *
407 * Returns true if the event is discarded, false otherwise.
408 */
409static inline bool
410__event_trigger_test_discard(struct ftrace_event_file *file,
411 struct ring_buffer *buffer,
412 struct ring_buffer_event *event,
413 void *entry,
414 enum event_trigger_type *tt)
415{
416 unsigned long eflags = file->flags;
417
418 if (eflags & FTRACE_EVENT_FL_TRIGGER_COND)
419 *tt = event_triggers_call(file, entry);
420
421 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags))
422 ring_buffer_discard_commit(buffer, event);
423 else if (!filter_check_discard(file, entry, buffer, event))
424 return false;
425
426 return true;
427}
428
429/**
430 * event_trigger_unlock_commit - handle triggers and finish event commit
431 * @file: The file pointer assoctiated to the event
432 * @buffer: The ring buffer that the event is being written to
433 * @event: The event meta data in the ring buffer
434 * @entry: The event itself
435 * @irq_flags: The state of the interrupts at the start of the event
436 * @pc: The state of the preempt count at the start of the event.
437 *
438 * This is a helper function to handle triggers that require data
439 * from the event itself. It also tests the event against filters and
440 * if the event is soft disabled and should be discarded.
441 */
442static inline void
443event_trigger_unlock_commit(struct ftrace_event_file *file,
444 struct ring_buffer *buffer,
445 struct ring_buffer_event *event,
446 void *entry, unsigned long irq_flags, int pc)
447{
448 enum event_trigger_type tt = ETT_NONE;
449
450 if (!__event_trigger_test_discard(file, buffer, event, entry, &tt))
451 trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
452
453 if (tt)
454 event_triggers_post_call(file, tt);
455}
456
457/**
458 * event_trigger_unlock_commit_regs - handle triggers and finish event commit
459 * @file: The file pointer assoctiated to the event
460 * @buffer: The ring buffer that the event is being written to
461 * @event: The event meta data in the ring buffer
462 * @entry: The event itself
463 * @irq_flags: The state of the interrupts at the start of the event
464 * @pc: The state of the preempt count at the start of the event.
465 *
466 * This is a helper function to handle triggers that require data
467 * from the event itself. It also tests the event against filters and
468 * if the event is soft disabled and should be discarded.
469 *
470 * Same as event_trigger_unlock_commit() but calls
471 * trace_buffer_unlock_commit_regs() instead of trace_buffer_unlock_commit().
472 */
473static inline void
474event_trigger_unlock_commit_regs(struct ftrace_event_file *file,
475 struct ring_buffer *buffer,
476 struct ring_buffer_event *event,
477 void *entry, unsigned long irq_flags, int pc,
478 struct pt_regs *regs)
479{
480 enum event_trigger_type tt = ETT_NONE;
481
482 if (!__event_trigger_test_discard(file, buffer, event, entry, &tt))
483 trace_buffer_unlock_commit_regs(buffer, event,
484 irq_flags, pc, regs);
485
486 if (tt)
487 event_triggers_post_call(file, tt);
488}
489
373enum { 490enum {
374 FILTER_OTHER = 0, 491 FILTER_OTHER = 0,
375 FILTER_STATIC_STRING, 492 FILTER_STATIC_STRING,
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h
index 0962968b8b37..1a8b28db3775 100644
--- a/include/trace/ftrace.h
+++ b/include/trace/ftrace.h
@@ -546,8 +546,6 @@ ftrace_raw_event_##call(void *__data, proto) \
546 struct ftrace_event_file *ftrace_file = __data; \ 546 struct ftrace_event_file *ftrace_file = __data; \
547 struct ftrace_event_call *event_call = ftrace_file->event_call; \ 547 struct ftrace_event_call *event_call = ftrace_file->event_call; \
548 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\ 548 struct ftrace_data_offsets_##call __maybe_unused __data_offsets;\
549 unsigned long eflags = ftrace_file->flags; \
550 enum event_trigger_type __tt = ETT_NONE; \
551 struct ring_buffer_event *event; \ 549 struct ring_buffer_event *event; \
552 struct ftrace_raw_##call *entry; \ 550 struct ftrace_raw_##call *entry; \
553 struct ring_buffer *buffer; \ 551 struct ring_buffer *buffer; \
@@ -555,12 +553,8 @@ ftrace_raw_event_##call(void *__data, proto) \
555 int __data_size; \ 553 int __data_size; \
556 int pc; \ 554 int pc; \
557 \ 555 \
558 if (!(eflags & FTRACE_EVENT_FL_TRIGGER_COND)) { \ 556 if (ftrace_trigger_soft_disabled(ftrace_file)) \
559 if (eflags & FTRACE_EVENT_FL_TRIGGER_MODE) \ 557 return; \
560 event_triggers_call(ftrace_file, NULL); \
561 if (eflags & FTRACE_EVENT_FL_SOFT_DISABLED) \
562 return; \
563 } \
564 \ 558 \
565 local_save_flags(irq_flags); \ 559 local_save_flags(irq_flags); \
566 pc = preempt_count(); \ 560 pc = preempt_count(); \
@@ -579,17 +573,8 @@ ftrace_raw_event_##call(void *__data, proto) \
579 \ 573 \
580 { assign; } \ 574 { assign; } \
581 \ 575 \
582 if (eflags & FTRACE_EVENT_FL_TRIGGER_COND) \ 576 event_trigger_unlock_commit(ftrace_file, buffer, event, entry, \
583 __tt = event_triggers_call(ftrace_file, entry); \ 577 irq_flags, pc); \
584 \
585 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, \
586 &ftrace_file->flags)) \
587 ring_buffer_discard_commit(buffer, event); \
588 else if (!filter_check_discard(ftrace_file, entry, buffer, event)) \
589 trace_buffer_unlock_commit(buffer, event, irq_flags, pc); \
590 \
591 if (__tt) \
592 event_triggers_post_call(ftrace_file, __tt); \
593} 578}
594/* 579/*
595 * The ftrace_test_probe is compiled out, it is only here as a build time check 580 * The ftrace_test_probe is compiled out, it is only here as a build time check