Skip to content
  • Tom Zanussi's avatar
    tracing: Add basic event trigger framework · 85f2b082
    Tom Zanussi authored
    Add a 'trigger' file for each trace event, enabling 'trace event
    triggers' to be set for trace events.
    
    'trace event triggers' are patterned after the existing 'ftrace
    function triggers' implementation except that triggers are written to
    per-event 'trigger' files instead of to a single file such as the
    'set_ftrace_filter' used for ftrace function triggers.
    
    The implementation is meant to be entirely separate from ftrace
    function triggers, in order to keep the respective implementations
    relatively simple and to allow them to diverge.
    
    The event trigger functionality is built on top of SOFT_DISABLE
    functionality.  It adds a TRIGGER_MODE bit to the ftrace_event_file
    flags which is checked when any trace event fires.  Triggers set for a
    particular event need to be checked regardless of whether that event
    is actually enabled or not - getting an event to fire even if it's not
    enabled is what's already implemented by SOFT_DISABLE mode, so trigger
    mode directly reuses that.  Event trigger essentially inherit the soft
    disable logic in __ftrace_event_enable_disable() while adding a bit of
    logic and trigger reference counting via tm_ref on top of that in a
    new trace_event_trigger_enable_disable() function.  Because the base
    __ftrace_event_enable_disable() code now needs to be invoked from
    outside trace_events.c, a wrapper is also added for those usages.
    
    The triggers for an event are actually invoked via a new function,
    event_triggers_call(), and code is also added to invoke them for
    ftrace_raw_event calls as well as syscall events.
    
    The main part of the patch creates a new trace_events_trigger.c file
    to contain the trace event triggers implementation.
    
    The standard open, read, and release file operations are implemented
    here.
    
    The open() implementation sets up for the various open modes of the
    'trigger' file.  It creates and attaches the trigger iterator and sets
    up the command parser.  If opened for reading set up the trigger
    seq_ops.
    
    The read() implementation parses the event trigger written to the
    'trigger' file, looks up the trigger command, and passes it along to
    that event_command's func() implementation for command-specific
    processing.
    
    The release() implementation does whatever cleanup is needed to
    release the 'trigger' file, like releasing the parser and trigger
    iterator, etc.
    
    A couple of functions for event command registration and
    unregistration are added, along with a list to add them to and a mutex
    to protect them, as well as an (initially empty) registration function
    to add the set of commands that will be added by future commits, and
    call to it from the trace event initialization code.
    
    also added are a couple trigger-specific data structures needed for
    these implementations such as a trigger iterator and a struct for
    trigger-specific data.
    
    A couple structs consisting mostly of function meant to be implemented
    in command-specific ways, event_command and event_trigger_ops, are
    used by the generic event trigger command implementations.  They're
    being put into trace.h alongside the other trace_event data structures
    and functions, in the expectation that they'll be needed in several
    trace_event-related files such as trace_events_trigger.c and
    trace_events.c.
    
    The event_command.func() function is meant to be called by the trigger
    parsing code in order to add a trigger instance to the corresponding
    event.  It essentially coordinates adding a live trigger instance to
    the event, and arming the triggering the event.
    
    Every event_command func() implementation essentially does the
    same thing for any command:
    
       - choose ops - use the value of param to choose either a number or
         count version of event_trigger_ops specific to the command
       - do the register or unregister of those ops
       - associate a filter, if specified, with the triggering event
    
    The reg() and unreg() ops allow command-specific implementations for
    event_trigger_op registration and unregistration, and the
    get_trigger_ops() op allows command-specific event_trigger_ops
    selection to be parameterized.  When a trigger instance is added, the
    reg() op essentially adds that trigger to the triggering event and
    arms it, while unreg() does the opposite.  The set_filter() function
    is used to associate a filter with the trigger - if the command
    doesn't specify a set_filter() implementation, the command will ignore
    filters.
    
    Each command has an associated trigger_type, which serves double duty,
    both as a unique identifier for the command as well as a value that
    can be used for setting a trigger mode bit during trigger invocation.
    
    The signature of func() adds a pointer to the event_command struct,
    used to invoke those functions, along with a command_data param that
    can be passed to the reg/unreg functions.  This allows func()
    implementations to use command-specific blobs and supports code
    re-use.
    
    The event_trigger_ops.func() command corrsponds to the trigger 'probe'
    function that gets called when the triggering event is actually
    invoked.  The other functions are used to list the trigger when
    needed, along with a couple mundane book-keeping functions.
    
    This also moves event_file_data() into trace.h so it can be used
    outside of trace_events.c.
    
    Link: http://lkml.kernel.org/r/316d95061accdee070aac8e5750afba0192fa5b9.1382622043.git.tom.zanussi@linux.intel.com
    
    
    
    Signed-off-by: default avatarTom Zanussi <tom.zanussi@linux.intel.com>
    Idea-by: default avatarSteve Rostedt <rostedt@goodmis.org>
    Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
    85f2b082