|
@@ -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,
|