@ -370,6 +370,123 @@ extern enum event_trigger_type event_triggers_call(struct ftrace_event_file *fil
extern void event_triggers_post_call ( struct ftrace_event_file * file ,
enum event_trigger_type tt ) ;
/**
* ftrace_trigger_soft_disabled - do triggers and test if soft disabled
* @ file : The file pointer of the event to test
*
* If any triggers without filters are attached to this event , they
* will be called here . If the event is soft disabled and has no
* triggers that require testing the fields , it will return true ,
* otherwise false .
*/
static inline bool
ftrace_trigger_soft_disabled ( struct ftrace_event_file * file )
{
unsigned long eflags = file - > flags ;
if ( ! ( eflags & FTRACE_EVENT_FL_TRIGGER_COND ) ) {
if ( eflags & FTRACE_EVENT_FL_TRIGGER_MODE )
event_triggers_call ( file , NULL ) ;
if ( eflags & FTRACE_EVENT_FL_SOFT_DISABLED )
return true ;
}
return false ;
}
/*
* Helper function for event_trigger_unlock_commit { _regs } ( ) .
* If there are event triggers attached to this event that requires
* filtering against its fields , then they wil be called as the
* entry already holds the field information of the current event .
*
* It also checks if the event should be discarded or not .
* It is to be discarded if the event is soft disabled and the
* event was only recorded to process triggers , or if the event
* filter is active and this event did not match the filters .
*
* Returns true if the event is discarded , false otherwise .
*/
static inline bool
__event_trigger_test_discard ( struct ftrace_event_file * file ,
struct ring_buffer * buffer ,
struct ring_buffer_event * event ,
void * entry ,
enum event_trigger_type * tt )
{
unsigned long eflags = file - > flags ;
if ( eflags & FTRACE_EVENT_FL_TRIGGER_COND )
* tt = event_triggers_call ( file , entry ) ;
if ( test_bit ( FTRACE_EVENT_FL_SOFT_DISABLED_BIT , & file - > flags ) )
ring_buffer_discard_commit ( buffer , event ) ;
else if ( ! filter_check_discard ( file , entry , buffer , event ) )
return false ;
return true ;
}
/**
* event_trigger_unlock_commit - handle triggers and finish event commit
* @ file : The file pointer assoctiated to the event
* @ buffer : The ring buffer that the event is being written to
* @ event : The event meta data in the ring buffer
* @ entry : The event itself
* @ irq_flags : The state of the interrupts at the start of the event
* @ pc : The state of the preempt count at the start of the event .
*
* This is a helper function to handle triggers that require data
* from the event itself . It also tests the event against filters and
* if the event is soft disabled and should be discarded .
*/
static inline void
event_trigger_unlock_commit ( struct ftrace_event_file * file ,
struct ring_buffer * buffer ,
struct ring_buffer_event * event ,
void * entry , unsigned long irq_flags , int pc )
{
enum event_trigger_type tt = ETT_NONE ;
if ( ! __event_trigger_test_discard ( file , buffer , event , entry , & tt ) )
trace_buffer_unlock_commit ( buffer , event , irq_flags , pc ) ;
if ( tt )
event_triggers_post_call ( file , tt ) ;
}
/**
* event_trigger_unlock_commit_regs - handle triggers and finish event commit
* @ file : The file pointer assoctiated to the event
* @ buffer : The ring buffer that the event is being written to
* @ event : The event meta data in the ring buffer
* @ entry : The event itself
* @ irq_flags : The state of the interrupts at the start of the event
* @ pc : The state of the preempt count at the start of the event .
*
* This is a helper function to handle triggers that require data
* from the event itself . It also tests the event against filters and
* if the event is soft disabled and should be discarded .
*
* Same as event_trigger_unlock_commit ( ) but calls
* trace_buffer_unlock_commit_regs ( ) instead of trace_buffer_unlock_commit ( ) .
*/
static inline void
event_trigger_unlock_commit_regs ( struct ftrace_event_file * file ,
struct ring_buffer * buffer ,
struct ring_buffer_event * event ,
void * entry , unsigned long irq_flags , int pc ,
struct pt_regs * regs )
{
enum event_trigger_type tt = ETT_NONE ;
if ( ! __event_trigger_test_discard ( file , buffer , event , entry , & tt ) )
trace_buffer_unlock_commit_regs ( buffer , event ,
irq_flags , pc , regs ) ;
if ( tt )
event_triggers_post_call ( file , tt ) ;
}
enum {
FILTER_OTHER = 0 ,
FILTER_STATIC_STRING ,