diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/ftrace_event.h | 117 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 23 |
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 | |||
| 370 | extern void event_triggers_post_call(struct ftrace_event_file *file, | 370 | extern 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 | */ | ||
| 382 | static inline bool | ||
| 383 | ftrace_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 | */ | ||
| 409 | static 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 | */ | ||
| 442 | static inline void | ||
| 443 | event_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 | */ | ||
| 473 | static inline void | ||
| 474 | event_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 | |||
| 373 | enum { | 490 | enum { |
| 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 |
