aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-22 19:35:21 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-22 19:35:21 -0500
commit60eaa0190f6b39dce18eb1975d9773ed8bc9a534 (patch)
treeaef5a45a59af0f493fe44a267fc6333fb245dc2e /include/linux
parentdf32e43a54d04eda35d2859beaf90e3864d53288 (diff)
parent92fdd98cf8bdec4d6b0c510e2f073ac4fd059be8 (diff)
Merge tag 'trace-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracing updates from Steven Rostedt: "This pull request has a new feature to ftrace, namely the trace event triggers by Tom Zanussi. A trigger is a way to enable an action when an event is hit. The actions are: o trace on/off - enable or disable tracing o snapshot - save the current trace buffer in the snapshot o stacktrace - dump the current stack trace to the ringbuffer o enable/disable events - enable or disable another event Namhyung Kim added updates to the tracing uprobes code. Having the uprobes add support for fetch methods. The rest are various bug fixes with the new code, and minor ones for the old code" * tag 'trace-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (38 commits) tracing: Fix buggered tee(2) on tracing_pipe tracing: Have trace buffer point back to trace_array ftrace: Fix synchronization location disabling and freeing ftrace_ops ftrace: Have function graph only trace based on global_ops filters ftrace: Synchronize setting function_trace_op with ftrace_trace_function tracing: Show available event triggers when no trigger is set tracing: Consolidate event trigger code tracing: Fix counter for traceon/off event triggers tracing: Remove double-underscore naming in syscall trigger invocations tracing/kprobes: Add trace event trigger invocations tracing/probes: Fix build break on !CONFIG_KPROBE_EVENT tracing/uprobes: Add @+file_offset fetch method uprobes: Allocate ->utask before handler_chain() for tracing handlers tracing/uprobes: Add support for full argument access methods tracing/uprobes: Fetch args before reserving a ring buffer tracing/uprobes: Pass 'is_return' to traceprobe_parse_probe_arg() tracing/probes: Implement 'memory' fetch method for uprobes tracing/probes: Add fetch{,_size} member into deref fetch method tracing/probes: Move 'symbol' fetch method to kprobes tracing/probes: Implement 'stack' fetch method for uprobes ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--include/linux/ftrace_event.h139
2 files changed, 139 insertions, 2 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 31ea4b428360..f4233b195dab 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -570,8 +570,6 @@ static inline int
570ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } 570ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; }
571#endif /* CONFIG_DYNAMIC_FTRACE */ 571#endif /* CONFIG_DYNAMIC_FTRACE */
572 572
573loff_t ftrace_filter_lseek(struct file *file, loff_t offset, int whence);
574
575/* totally disable ftrace - can not re-enable after this */ 573/* totally disable ftrace - can not re-enable after this */
576void ftrace_kill(void); 574void ftrace_kill(void);
577 575
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 8c9b7a1c4138..4e4cc28623ad 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,