aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ftrace_event.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/ftrace_event.h')
-rw-r--r--include/linux/ftrace_event.h143
1 files changed, 139 insertions, 4 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 8c9b7a1c4138..4cdb3a17bcb5 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -1,3 +1,4 @@
1
1#ifndef _LINUX_FTRACE_EVENT_H 2#ifndef _LINUX_FTRACE_EVENT_H
2#define _LINUX_FTRACE_EVENT_H 3#define _LINUX_FTRACE_EVENT_H
3 4
@@ -264,6 +265,8 @@ enum {
264 FTRACE_EVENT_FL_NO_SET_FILTER_BIT, 265 FTRACE_EVENT_FL_NO_SET_FILTER_BIT,
265 FTRACE_EVENT_FL_SOFT_MODE_BIT, 266 FTRACE_EVENT_FL_SOFT_MODE_BIT,
266 FTRACE_EVENT_FL_SOFT_DISABLED_BIT, 267 FTRACE_EVENT_FL_SOFT_DISABLED_BIT,
268 FTRACE_EVENT_FL_TRIGGER_MODE_BIT,
269 FTRACE_EVENT_FL_TRIGGER_COND_BIT,
267}; 270};
268 271
269/* 272/*
@@ -275,6 +278,8 @@ enum {
275 * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED 278 * SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED
276 * SOFT_DISABLED - When set, do not trace the event (even though its 279 * SOFT_DISABLED - When set, do not trace the event (even though its
277 * tracepoint may be enabled) 280 * tracepoint may be enabled)
281 * TRIGGER_MODE - When set, invoke the triggers associated with the event
282 * TRIGGER_COND - When set, one or more triggers has an associated filter
278 */ 283 */
279enum { 284enum {
280 FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT), 285 FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT),
@@ -283,6 +288,8 @@ enum {
283 FTRACE_EVENT_FL_NO_SET_FILTER = (1 << FTRACE_EVENT_FL_NO_SET_FILTER_BIT), 288 FTRACE_EVENT_FL_NO_SET_FILTER = (1 << FTRACE_EVENT_FL_NO_SET_FILTER_BIT),
284 FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT), 289 FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT),
285 FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT), 290 FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT),
291 FTRACE_EVENT_FL_TRIGGER_MODE = (1 << FTRACE_EVENT_FL_TRIGGER_MODE_BIT),
292 FTRACE_EVENT_FL_TRIGGER_COND = (1 << FTRACE_EVENT_FL_TRIGGER_COND_BIT),
286}; 293};
287 294
288struct ftrace_event_file { 295struct ftrace_event_file {
@@ -292,6 +299,7 @@ struct ftrace_event_file {
292 struct dentry *dir; 299 struct dentry *dir;
293 struct trace_array *tr; 300 struct trace_array *tr;
294 struct ftrace_subsystem_dir *system; 301 struct ftrace_subsystem_dir *system;
302 struct list_head triggers;
295 303
296 /* 304 /*
297 * 32 bit flags: 305 * 32 bit flags:
@@ -299,6 +307,7 @@ struct ftrace_event_file {
299 * bit 1: enabled cmd record 307 * bit 1: enabled cmd record
300 * bit 2: enable/disable with the soft disable bit 308 * bit 2: enable/disable with the soft disable bit
301 * bit 3: soft disabled 309 * bit 3: soft disabled
310 * bit 4: trigger enabled
302 * 311 *
303 * Note: The bits must be set atomically to prevent races 312 * Note: The bits must be set atomically to prevent races
304 * from other writers. Reads of flags do not need to be in 313 * from other writers. Reads of flags do not need to be in
@@ -310,6 +319,7 @@ struct ftrace_event_file {
310 */ 319 */
311 unsigned long flags; 320 unsigned long flags;
312 atomic_t sm_ref; /* soft-mode reference counter */ 321 atomic_t sm_ref; /* soft-mode reference counter */
322 atomic_t tm_ref; /* trigger-mode reference counter */
313}; 323};
314 324
315#define __TRACE_EVENT_FLAGS(name, value) \ 325#define __TRACE_EVENT_FLAGS(name, value) \
@@ -337,6 +347,14 @@ struct ftrace_event_file {
337 347
338#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */ 348#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
339 349
350enum event_trigger_type {
351 ETT_NONE = (0),
352 ETT_TRACE_ONOFF = (1 << 0),
353 ETT_SNAPSHOT = (1 << 1),
354 ETT_STACKTRACE = (1 << 2),
355 ETT_EVENT_ENABLE = (1 << 3),
356};
357
340extern void destroy_preds(struct ftrace_event_file *file); 358extern void destroy_preds(struct ftrace_event_file *file);
341extern void destroy_call_preds(struct ftrace_event_call *call); 359extern void destroy_call_preds(struct ftrace_event_call *call);
342extern int filter_match_preds(struct event_filter *filter, void *rec); 360extern int filter_match_preds(struct event_filter *filter, void *rec);
@@ -347,6 +365,127 @@ extern int filter_check_discard(struct ftrace_event_file *file, void *rec,
347extern int call_filter_check_discard(struct ftrace_event_call *call, void *rec, 365extern int call_filter_check_discard(struct ftrace_event_call *call, void *rec,
348 struct ring_buffer *buffer, 366 struct ring_buffer *buffer,
349 struct ring_buffer_event *event); 367 struct ring_buffer_event *event);
368extern enum event_trigger_type event_triggers_call(struct ftrace_event_file *file,
369 void *rec);
370extern void event_triggers_post_call(struct ftrace_event_file *file,
371 enum event_trigger_type tt);
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}
350 489
351enum { 490enum {
352 FILTER_OTHER = 0, 491 FILTER_OTHER = 0,
@@ -356,10 +495,6 @@ enum {
356 FILTER_TRACE_FN, 495 FILTER_TRACE_FN,
357}; 496};
358 497
359#define EVENT_STORAGE_SIZE 128
360extern struct mutex event_storage_mutex;
361extern char event_storage[EVENT_STORAGE_SIZE];
362
363extern int trace_event_raw_init(struct ftrace_event_call *call); 498extern int trace_event_raw_init(struct ftrace_event_call *call);
364extern int trace_define_field(struct ftrace_event_call *call, const char *type, 499extern int trace_define_field(struct ftrace_event_call *call, const char *type,
365 const char *name, int offset, int size, 500 const char *name, int offset, int size,