2009-04-13 23:20:49 +08:00
|
|
|
#ifndef _LINUX_FTRACE_EVENT_H
|
|
|
|
#define _LINUX_FTRACE_EVENT_H
|
|
|
|
|
|
|
|
#include <linux/ring_buffer.h>
|
2009-09-13 07:04:54 +08:00
|
|
|
#include <linux/trace_seq.h>
|
2009-05-27 02:25:22 +08:00
|
|
|
#include <linux/percpu.h>
|
2009-09-18 12:10:28 +08:00
|
|
|
#include <linux/hardirq.h>
|
2010-01-28 09:32:29 +08:00
|
|
|
#include <linux/perf_event.h>
|
2009-04-13 23:20:49 +08:00
|
|
|
|
|
|
|
struct trace_array;
|
tracing: Consolidate max_tr into main trace_array structure
Currently, the way the latency tracers and snapshot feature works
is to have a separate trace_array called "max_tr" that holds the
snapshot buffer. For latency tracers, this snapshot buffer is used
to swap the running buffer with this buffer to save the current max
latency.
The only items needed for the max_tr is really just a copy of the buffer
itself, the per_cpu data pointers, the time_start timestamp that states
when the max latency was triggered, and the cpu that the max latency
was triggered on. All other fields in trace_array are unused by the
max_tr, making the max_tr mostly bloat.
This change removes the max_tr completely, and adds a new structure
called trace_buffer, that holds the buffer pointer, the per_cpu data
pointers, the time_start timestamp, and the cpu where the latency occurred.
The trace_array, now has two trace_buffers, one for the normal trace and
one for the max trace or snapshot. By doing this, not only do we remove
the bloat from the max_trace but the instances of traces can now use
their own snapshot feature and not have just the top level global_trace have
the snapshot feature and latency tracers for itself.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2013-03-05 22:24:35 +08:00
|
|
|
struct trace_buffer;
|
2009-04-13 23:20:49 +08:00
|
|
|
struct tracer;
|
2009-04-11 02:53:50 +08:00
|
|
|
struct dentry;
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2009-05-27 02:25:22 +08:00
|
|
|
struct trace_print_flags {
|
|
|
|
unsigned long mask;
|
|
|
|
const char *name;
|
|
|
|
};
|
|
|
|
|
2011-04-19 09:35:28 +08:00
|
|
|
struct trace_print_flags_u64 {
|
|
|
|
unsigned long long mask;
|
|
|
|
const char *name;
|
|
|
|
};
|
|
|
|
|
2009-05-27 02:25:22 +08:00
|
|
|
const char *ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
|
|
|
|
unsigned long flags,
|
|
|
|
const struct trace_print_flags *flag_array);
|
|
|
|
|
2009-05-21 07:21:47 +08:00
|
|
|
const char *ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
|
|
|
|
const struct trace_print_flags *symbol_array);
|
|
|
|
|
2011-04-19 09:35:28 +08:00
|
|
|
#if BITS_PER_LONG == 32
|
|
|
|
const char *ftrace_print_symbols_seq_u64(struct trace_seq *p,
|
|
|
|
unsigned long long val,
|
|
|
|
const struct trace_print_flags_u64
|
|
|
|
*symbol_array);
|
|
|
|
#endif
|
|
|
|
|
2010-04-01 19:40:58 +08:00
|
|
|
const char *ftrace_print_hex_seq(struct trace_seq *p,
|
|
|
|
const unsigned char *buf, int len);
|
|
|
|
|
2013-02-21 10:32:38 +08:00
|
|
|
struct trace_iterator;
|
|
|
|
struct trace_event;
|
|
|
|
|
|
|
|
int ftrace_raw_output_prep(struct trace_iterator *iter,
|
|
|
|
struct trace_event *event);
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
/*
|
|
|
|
* The trace entry - the most basic unit of tracing. This is what
|
|
|
|
* is printed in the end as a single line in the trace output, such as:
|
|
|
|
*
|
|
|
|
* bash-15816 [01] 235.197585: idle_cpu <- irq_enter
|
|
|
|
*/
|
|
|
|
struct trace_entry {
|
2009-03-26 23:03:29 +08:00
|
|
|
unsigned short type;
|
2009-04-13 23:20:49 +08:00
|
|
|
unsigned char flags;
|
|
|
|
unsigned char preempt_count;
|
|
|
|
int pid;
|
|
|
|
};
|
|
|
|
|
2009-03-26 23:03:29 +08:00
|
|
|
#define FTRACE_MAX_EVENT \
|
|
|
|
((1 << (sizeof(((struct trace_entry *)0)->type) * 8)) - 1)
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
/*
|
|
|
|
* Trace iterator - used by printout routines who present trace
|
|
|
|
* results to users and which routines might sleep, etc:
|
|
|
|
*/
|
|
|
|
struct trace_iterator {
|
|
|
|
struct trace_array *tr;
|
|
|
|
struct tracer *trace;
|
tracing: Consolidate max_tr into main trace_array structure
Currently, the way the latency tracers and snapshot feature works
is to have a separate trace_array called "max_tr" that holds the
snapshot buffer. For latency tracers, this snapshot buffer is used
to swap the running buffer with this buffer to save the current max
latency.
The only items needed for the max_tr is really just a copy of the buffer
itself, the per_cpu data pointers, the time_start timestamp that states
when the max latency was triggered, and the cpu that the max latency
was triggered on. All other fields in trace_array are unused by the
max_tr, making the max_tr mostly bloat.
This change removes the max_tr completely, and adds a new structure
called trace_buffer, that holds the buffer pointer, the per_cpu data
pointers, the time_start timestamp, and the cpu where the latency occurred.
The trace_array, now has two trace_buffers, one for the normal trace and
one for the max trace or snapshot. By doing this, not only do we remove
the bloat from the max_trace but the instances of traces can now use
their own snapshot feature and not have just the top level global_trace have
the snapshot feature and latency tracers for itself.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
2013-03-05 22:24:35 +08:00
|
|
|
struct trace_buffer *trace_buffer;
|
2009-04-13 23:20:49 +08:00
|
|
|
void *private;
|
|
|
|
int cpu_file;
|
|
|
|
struct mutex mutex;
|
2012-06-28 08:46:14 +08:00
|
|
|
struct ring_buffer_iter **buffer_iter;
|
2009-06-02 03:16:05 +08:00
|
|
|
unsigned long iter_flags;
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2010-06-03 18:26:24 +08:00
|
|
|
/* trace_seq for __print_flags() and __print_symbolic() etc. */
|
|
|
|
struct trace_seq tmp_seq;
|
|
|
|
|
2013-08-03 01:16:43 +08:00
|
|
|
cpumask_var_t started;
|
|
|
|
|
|
|
|
/* it's true when current open file is snapshot */
|
|
|
|
bool snapshot;
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
/* The below is zeroed out in pipe_read */
|
|
|
|
struct trace_seq seq;
|
|
|
|
struct trace_entry *ent;
|
2010-04-01 07:49:26 +08:00
|
|
|
unsigned long lost_events;
|
2009-12-07 22:11:39 +08:00
|
|
|
int leftover;
|
2011-07-15 04:36:53 +08:00
|
|
|
int ent_size;
|
2009-04-13 23:20:49 +08:00
|
|
|
int cpu;
|
|
|
|
u64 ts;
|
|
|
|
|
|
|
|
loff_t pos;
|
|
|
|
long idx;
|
|
|
|
|
2013-08-03 01:16:43 +08:00
|
|
|
/* All new field here will be zeroed out in pipe_read */
|
2009-04-13 23:20:49 +08:00
|
|
|
};
|
|
|
|
|
2012-11-14 04:18:22 +08:00
|
|
|
enum trace_iter_flags {
|
|
|
|
TRACE_FILE_LAT_FMT = 1,
|
|
|
|
TRACE_FILE_ANNOTATE = 2,
|
|
|
|
TRACE_FILE_TIME_IN_NS = 4,
|
|
|
|
};
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
|
|
|
|
typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
|
2010-04-23 06:46:14 +08:00
|
|
|
int flags, struct trace_event *event);
|
|
|
|
|
|
|
|
struct trace_event_functions {
|
2009-04-13 23:20:49 +08:00
|
|
|
trace_print_func trace;
|
|
|
|
trace_print_func raw;
|
|
|
|
trace_print_func hex;
|
|
|
|
trace_print_func binary;
|
|
|
|
};
|
|
|
|
|
2010-04-23 06:46:14 +08:00
|
|
|
struct trace_event {
|
|
|
|
struct hlist_node node;
|
|
|
|
struct list_head list;
|
|
|
|
int type;
|
|
|
|
struct trace_event_functions *funcs;
|
|
|
|
};
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
extern int register_ftrace_event(struct trace_event *event);
|
|
|
|
extern int unregister_ftrace_event(struct trace_event *event);
|
|
|
|
|
|
|
|
/* Return values for print_line callback */
|
|
|
|
enum print_line_t {
|
|
|
|
TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */
|
|
|
|
TRACE_TYPE_HANDLED = 1,
|
|
|
|
TRACE_TYPE_UNHANDLED = 2, /* Relay to other output functions */
|
|
|
|
TRACE_TYPE_NO_CONSUME = 3 /* Handled but ask to not consume */
|
|
|
|
};
|
|
|
|
|
2009-08-07 07:25:54 +08:00
|
|
|
void tracing_generic_entry_update(struct trace_entry *entry,
|
|
|
|
unsigned long flags,
|
|
|
|
int pc);
|
2012-08-02 22:32:10 +08:00
|
|
|
struct ftrace_event_file;
|
|
|
|
|
|
|
|
struct ring_buffer_event *
|
|
|
|
trace_event_buffer_lock_reserve(struct ring_buffer **current_buffer,
|
|
|
|
struct ftrace_event_file *ftrace_file,
|
|
|
|
int type, unsigned long len,
|
|
|
|
unsigned long flags, int pc);
|
2009-04-13 23:20:49 +08:00
|
|
|
struct ring_buffer_event *
|
2009-09-03 02:17:06 +08:00
|
|
|
trace_current_buffer_lock_reserve(struct ring_buffer **current_buffer,
|
|
|
|
int type, unsigned long len,
|
2009-04-13 23:20:49 +08:00
|
|
|
unsigned long flags, int pc);
|
2009-09-03 02:17:06 +08:00
|
|
|
void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
|
|
|
|
struct ring_buffer_event *event,
|
2009-04-13 23:20:49 +08:00
|
|
|
unsigned long flags, int pc);
|
2012-11-02 08:54:21 +08:00
|
|
|
void trace_buffer_unlock_commit(struct ring_buffer *buffer,
|
|
|
|
struct ring_buffer_event *event,
|
|
|
|
unsigned long flags, int pc);
|
|
|
|
void trace_buffer_unlock_commit_regs(struct ring_buffer *buffer,
|
|
|
|
struct ring_buffer_event *event,
|
|
|
|
unsigned long flags, int pc,
|
|
|
|
struct pt_regs *regs);
|
2009-09-03 02:17:06 +08:00
|
|
|
void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
|
|
|
|
struct ring_buffer_event *event);
|
2009-04-13 23:20:49 +08:00
|
|
|
|
|
|
|
void tracing_record_cmdline(struct task_struct *tsk);
|
|
|
|
|
2009-07-20 10:20:53 +08:00
|
|
|
struct event_filter;
|
|
|
|
|
2010-04-22 00:27:06 +08:00
|
|
|
enum trace_reg {
|
|
|
|
TRACE_REG_REGISTER,
|
|
|
|
TRACE_REG_UNREGISTER,
|
2012-03-14 07:03:02 +08:00
|
|
|
#ifdef CONFIG_PERF_EVENTS
|
2010-04-22 00:27:06 +08:00
|
|
|
TRACE_REG_PERF_REGISTER,
|
|
|
|
TRACE_REG_PERF_UNREGISTER,
|
2012-02-15 22:51:49 +08:00
|
|
|
TRACE_REG_PERF_OPEN,
|
|
|
|
TRACE_REG_PERF_CLOSE,
|
2012-02-15 22:51:50 +08:00
|
|
|
TRACE_REG_PERF_ADD,
|
|
|
|
TRACE_REG_PERF_DEL,
|
2012-03-14 07:03:02 +08:00
|
|
|
#endif
|
2010-04-22 00:27:06 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ftrace_event_call;
|
|
|
|
|
2010-04-20 22:47:33 +08:00
|
|
|
struct ftrace_event_class {
|
|
|
|
char *system;
|
2010-04-22 00:27:06 +08:00
|
|
|
void *probe;
|
|
|
|
#ifdef CONFIG_PERF_EVENTS
|
|
|
|
void *perf_probe;
|
|
|
|
#endif
|
|
|
|
int (*reg)(struct ftrace_event_call *event,
|
2012-02-15 22:51:49 +08:00
|
|
|
enum trace_reg type, void *data);
|
2010-04-22 22:35:55 +08:00
|
|
|
int (*define_fields)(struct ftrace_event_call *);
|
|
|
|
struct list_head *(*get_fields)(struct ftrace_event_call *);
|
|
|
|
struct list_head fields;
|
2010-04-22 23:46:44 +08:00
|
|
|
int (*raw_init)(struct ftrace_event_call *);
|
2010-04-20 22:47:33 +08:00
|
|
|
};
|
|
|
|
|
2010-06-08 23:22:06 +08:00
|
|
|
extern int ftrace_event_reg(struct ftrace_event_call *event,
|
2012-02-15 22:51:49 +08:00
|
|
|
enum trace_reg type, void *data);
|
2010-06-08 23:22:06 +08:00
|
|
|
|
2010-04-23 23:12:36 +08:00
|
|
|
enum {
|
|
|
|
TRACE_EVENT_FL_FILTERED_BIT,
|
2010-11-18 08:39:17 +08:00
|
|
|
TRACE_EVENT_FL_CAP_ANY_BIT,
|
2011-11-01 09:09:35 +08:00
|
|
|
TRACE_EVENT_FL_NO_SET_FILTER_BIT,
|
2012-05-11 03:55:43 +08:00
|
|
|
TRACE_EVENT_FL_IGNORE_ENABLE_BIT,
|
2013-03-05 12:05:12 +08:00
|
|
|
TRACE_EVENT_FL_WAS_ENABLED_BIT,
|
2010-04-23 23:12:36 +08:00
|
|
|
};
|
|
|
|
|
2012-05-04 11:09:03 +08:00
|
|
|
/*
|
|
|
|
* Event flags:
|
|
|
|
* FILTERED - The event has a filter attached
|
|
|
|
* CAP_ANY - Any user can enable for perf
|
|
|
|
* NO_SET_FILTER - Set when filter has error and is to be ignored
|
2013-03-05 11:27:04 +08:00
|
|
|
* IGNORE_ENABLE - For ftrace internal events, do not enable with debugfs file
|
2013-03-05 12:05:12 +08:00
|
|
|
* WAS_ENABLED - Set and stays set when an event was ever enabled
|
|
|
|
* (used for module unloading, if a module event is enabled,
|
|
|
|
* it is best to clear the buffers that used it).
|
2012-05-04 11:09:03 +08:00
|
|
|
*/
|
2010-04-23 23:12:36 +08:00
|
|
|
enum {
|
2010-07-02 11:07:32 +08:00
|
|
|
TRACE_EVENT_FL_FILTERED = (1 << TRACE_EVENT_FL_FILTERED_BIT),
|
2010-11-18 08:39:17 +08:00
|
|
|
TRACE_EVENT_FL_CAP_ANY = (1 << TRACE_EVENT_FL_CAP_ANY_BIT),
|
2011-11-01 09:09:35 +08:00
|
|
|
TRACE_EVENT_FL_NO_SET_FILTER = (1 << TRACE_EVENT_FL_NO_SET_FILTER_BIT),
|
2012-05-11 03:55:43 +08:00
|
|
|
TRACE_EVENT_FL_IGNORE_ENABLE = (1 << TRACE_EVENT_FL_IGNORE_ENABLE_BIT),
|
2013-03-05 12:05:12 +08:00
|
|
|
TRACE_EVENT_FL_WAS_ENABLED = (1 << TRACE_EVENT_FL_WAS_ENABLED_BIT),
|
2010-04-23 23:12:36 +08:00
|
|
|
};
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
struct ftrace_event_call {
|
2009-04-11 01:52:20 +08:00
|
|
|
struct list_head list;
|
2010-04-20 22:47:33 +08:00
|
|
|
struct ftrace_event_class *class;
|
2009-04-13 23:20:49 +08:00
|
|
|
char *name;
|
2010-04-23 22:00:22 +08:00
|
|
|
struct trace_event event;
|
2009-12-15 15:39:42 +08:00
|
|
|
const char *print_fmt;
|
2009-07-20 10:20:53 +08:00
|
|
|
struct event_filter *filter;
|
2012-05-04 11:09:03 +08:00
|
|
|
struct list_head *files;
|
2009-04-11 02:53:50 +08:00
|
|
|
void *mod;
|
2009-08-11 04:52:44 +08:00
|
|
|
void *data;
|
2013-03-13 00:38:06 +08:00
|
|
|
/*
|
|
|
|
* bit 0: filter_active
|
|
|
|
* bit 1: allow trace by non root (cap any)
|
|
|
|
* bit 2: failed to apply filter
|
|
|
|
* bit 3: ftrace internal event (do not enable)
|
|
|
|
* bit 4: Event was enabled by module
|
|
|
|
*/
|
2012-05-04 11:09:03 +08:00
|
|
|
int flags; /* static flags of different events */
|
|
|
|
|
|
|
|
#ifdef CONFIG_PERF_EVENTS
|
|
|
|
int perf_refcount;
|
|
|
|
struct hlist_head __percpu *perf_events;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
struct trace_array;
|
|
|
|
struct ftrace_subsystem_dir;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
FTRACE_EVENT_FL_ENABLED_BIT,
|
|
|
|
FTRACE_EVENT_FL_RECORDED_CMD_BIT,
|
2013-03-13 01:26:18 +08:00
|
|
|
FTRACE_EVENT_FL_SOFT_MODE_BIT,
|
|
|
|
FTRACE_EVENT_FL_SOFT_DISABLED_BIT,
|
2012-05-04 11:09:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ftrace event file flags:
|
2013-03-13 00:38:06 +08:00
|
|
|
* ENABLED - The event is enabled
|
2012-05-04 11:09:03 +08:00
|
|
|
* RECORDED_CMD - The comms should be recorded at sched_switch
|
2013-03-13 01:26:18 +08:00
|
|
|
* SOFT_MODE - The event is enabled/disabled by SOFT_DISABLED
|
|
|
|
* SOFT_DISABLED - When set, do not trace the event (even though its
|
|
|
|
* tracepoint may be enabled)
|
2012-05-04 11:09:03 +08:00
|
|
|
*/
|
|
|
|
enum {
|
|
|
|
FTRACE_EVENT_FL_ENABLED = (1 << FTRACE_EVENT_FL_ENABLED_BIT),
|
|
|
|
FTRACE_EVENT_FL_RECORDED_CMD = (1 << FTRACE_EVENT_FL_RECORDED_CMD_BIT),
|
2013-03-13 01:26:18 +08:00
|
|
|
FTRACE_EVENT_FL_SOFT_MODE = (1 << FTRACE_EVENT_FL_SOFT_MODE_BIT),
|
|
|
|
FTRACE_EVENT_FL_SOFT_DISABLED = (1 << FTRACE_EVENT_FL_SOFT_DISABLED_BIT),
|
2012-05-04 11:09:03 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct ftrace_event_file {
|
|
|
|
struct list_head list;
|
|
|
|
struct ftrace_event_call *event_call;
|
|
|
|
struct dentry *dir;
|
|
|
|
struct trace_array *tr;
|
|
|
|
struct ftrace_subsystem_dir *system;
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2010-04-23 23:12:36 +08:00
|
|
|
/*
|
|
|
|
* 32 bit flags:
|
2013-03-13 00:38:06 +08:00
|
|
|
* bit 0: enabled
|
|
|
|
* bit 1: enabled cmd record
|
2013-03-13 01:26:18 +08:00
|
|
|
* bit 2: enable/disable with the soft disable bit
|
|
|
|
* bit 3: soft disabled
|
2010-04-23 23:12:36 +08:00
|
|
|
*
|
2013-03-13 01:26:18 +08:00
|
|
|
* Note: The bits must be set atomically to prevent races
|
|
|
|
* from other writers. Reads of flags do not need to be in
|
|
|
|
* sync as they occur in critical sections. But the way flags
|
2012-05-04 11:09:03 +08:00
|
|
|
* is currently used, these changes do not affect the code
|
2010-05-14 22:19:13 +08:00
|
|
|
* except that when a change is made, it may have a slight
|
|
|
|
* delay in propagating the changes to other CPUs due to
|
2013-03-13 01:26:18 +08:00
|
|
|
* caching and such. Which is mostly OK ;-)
|
2010-04-23 23:12:36 +08:00
|
|
|
*/
|
2013-03-13 01:26:18 +08:00
|
|
|
unsigned long flags;
|
2013-05-09 13:44:29 +08:00
|
|
|
atomic_t sm_ref; /* soft-mode reference counter */
|
2009-04-13 23:20:49 +08:00
|
|
|
};
|
|
|
|
|
2010-11-18 09:11:42 +08:00
|
|
|
#define __TRACE_EVENT_FLAGS(name, value) \
|
|
|
|
static int __init trace_init_flags_##name(void) \
|
|
|
|
{ \
|
|
|
|
event_##name.flags = value; \
|
|
|
|
return 0; \
|
|
|
|
} \
|
|
|
|
early_initcall(trace_init_flags_##name);
|
|
|
|
|
2010-03-05 12:35:37 +08:00
|
|
|
#define PERF_MAX_TRACE_SIZE 2048
|
2009-09-18 12:10:28 +08:00
|
|
|
|
2009-09-13 07:04:54 +08:00
|
|
|
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2009-05-06 10:33:04 +08:00
|
|
|
extern void destroy_preds(struct ftrace_event_call *call);
|
2009-10-15 11:21:42 +08:00
|
|
|
extern int filter_match_preds(struct event_filter *filter, void *rec);
|
2009-09-03 02:17:06 +08:00
|
|
|
extern int filter_current_check_discard(struct ring_buffer *buffer,
|
|
|
|
struct ftrace_event_call *call,
|
2009-04-13 23:20:49 +08:00
|
|
|
void *rec,
|
|
|
|
struct ring_buffer_event *event);
|
|
|
|
|
2009-08-07 10:33:22 +08:00
|
|
|
enum {
|
|
|
|
FILTER_OTHER = 0,
|
|
|
|
FILTER_STATIC_STRING,
|
|
|
|
FILTER_DYN_STRING,
|
2009-08-07 10:33:43 +08:00
|
|
|
FILTER_PTR_STRING,
|
2012-02-15 22:51:53 +08:00
|
|
|
FILTER_TRACE_FN,
|
2009-08-07 10:33:22 +08:00
|
|
|
};
|
|
|
|
|
2010-11-13 11:32:11 +08:00
|
|
|
#define EVENT_STORAGE_SIZE 128
|
|
|
|
extern struct mutex event_storage_mutex;
|
|
|
|
extern char event_storage[EVENT_STORAGE_SIZE];
|
|
|
|
|
2009-12-08 11:14:20 +08:00
|
|
|
extern int trace_event_raw_init(struct ftrace_event_call *call);
|
2009-08-27 11:09:51 +08:00
|
|
|
extern int trace_define_field(struct ftrace_event_call *call, const char *type,
|
|
|
|
const char *name, int offset, int size,
|
|
|
|
int is_signed, int filter_type);
|
2009-08-14 04:34:53 +08:00
|
|
|
extern int trace_add_event_call(struct ftrace_event_call *call);
|
2013-07-30 01:50:33 +08:00
|
|
|
extern int trace_remove_event_call(struct ftrace_event_call *call);
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2013-04-20 05:10:27 +08:00
|
|
|
#define is_signed_type(type) (((type)(-1)) < (type)1)
|
2009-04-13 23:20:49 +08:00
|
|
|
|
2009-05-09 04:27:41 +08:00
|
|
|
int trace_set_clr_event(const char *system, const char *event, int set);
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
/*
|
|
|
|
* The double __builtin_constant_p is because gcc will give us an error
|
|
|
|
* if we try to allocate the static variable to fmt if it is not a
|
|
|
|
* constant. Even with the outer if statement optimizing out.
|
|
|
|
*/
|
|
|
|
#define event_trace_printk(ip, fmt, args...) \
|
|
|
|
do { \
|
|
|
|
__trace_printk_check_format(fmt, ##args); \
|
|
|
|
tracing_record_cmdline(current); \
|
|
|
|
if (__builtin_constant_p(fmt)) { \
|
|
|
|
static const char *trace_printk_fmt \
|
|
|
|
__attribute__((section("__trace_printk_fmt"))) = \
|
|
|
|
__builtin_constant_p(fmt) ? fmt : NULL; \
|
|
|
|
\
|
|
|
|
__trace_bprintk(ip, trace_printk_fmt, ##args); \
|
|
|
|
} else \
|
|
|
|
__trace_printk(ip, fmt, ##args); \
|
|
|
|
} while (0)
|
|
|
|
|
2013-07-13 05:07:27 +08:00
|
|
|
/**
|
|
|
|
* tracepoint_string - register constant persistent string to trace system
|
|
|
|
* @str - a constant persistent string that will be referenced in tracepoints
|
|
|
|
*
|
|
|
|
* If constant strings are being used in tracepoints, it is faster and
|
|
|
|
* more efficient to just save the pointer to the string and reference
|
|
|
|
* that with a printf "%s" instead of saving the string in the ring buffer
|
|
|
|
* and wasting space and time.
|
|
|
|
*
|
|
|
|
* The problem with the above approach is that userspace tools that read
|
|
|
|
* the binary output of the trace buffers do not have access to the string.
|
|
|
|
* Instead they just show the address of the string which is not very
|
|
|
|
* useful to users.
|
|
|
|
*
|
|
|
|
* With tracepoint_string(), the string will be registered to the tracing
|
|
|
|
* system and exported to userspace via the debugfs/tracing/printk_formats
|
|
|
|
* file that maps the string address to the string text. This way userspace
|
|
|
|
* tools that read the binary buffers have a way to map the pointers to
|
|
|
|
* the ASCII strings they represent.
|
|
|
|
*
|
|
|
|
* The @str used must be a constant string and persistent as it would not
|
|
|
|
* make sense to show a string that no longer exists. But it is still fine
|
|
|
|
* to be used with modules, because when modules are unloaded, if they
|
|
|
|
* had tracepoints, the ring buffers are cleared too. As long as the string
|
|
|
|
* does not change during the life of the module, it is fine to use
|
|
|
|
* tracepoint_string() within a module.
|
|
|
|
*/
|
|
|
|
#define tracepoint_string(str) \
|
|
|
|
({ \
|
|
|
|
static const char *___tp_str __tracepoint_string = str; \
|
|
|
|
___tp_str; \
|
|
|
|
})
|
|
|
|
#define __tracepoint_string __attribute__((section("__tracepoint_str")))
|
|
|
|
|
2009-12-21 14:27:35 +08:00
|
|
|
#ifdef CONFIG_PERF_EVENTS
|
2009-10-15 11:21:42 +08:00
|
|
|
struct perf_event;
|
2010-03-03 14:16:16 +08:00
|
|
|
|
|
|
|
DECLARE_PER_CPU(struct pt_regs, perf_trace_regs);
|
|
|
|
|
2010-05-19 20:02:22 +08:00
|
|
|
extern int perf_trace_init(struct perf_event *event);
|
|
|
|
extern void perf_trace_destroy(struct perf_event *event);
|
perf: Rework the PMU methods
Replace pmu::{enable,disable,start,stop,unthrottle} with
pmu::{add,del,start,stop}, all of which take a flags argument.
The new interface extends the capability to stop a counter while
keeping it scheduled on the PMU. We replace the throttled state with
the generic stopped state.
This also allows us to efficiently stop/start counters over certain
code paths (like IRQ handlers).
It also allows scheduling a counter without it starting, allowing for
a generic frozen state (useful for rotating stopped counters).
The stopped state is implemented in two different ways, depending on
how the architecture implemented the throttled state:
1) We disable the counter:
a) the pmu has per-counter enable bits, we flip that
b) we program a NOP event, preserving the counter state
2) We store the counter state and ignore all read/overflow events
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: paulus <paulus@samba.org>
Cc: stephane eranian <eranian@googlemail.com>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Cyrill Gorcunov <gorcunov@gmail.com>
Cc: Lin Ming <ming.m.lin@intel.com>
Cc: Yanmin <yanmin_zhang@linux.intel.com>
Cc: Deng-Cheng Zhu <dengcheng.zhu@gmail.com>
Cc: David Miller <davem@davemloft.net>
Cc: Michael Cree <mcree@orcon.net.nz>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2010-06-16 20:37:10 +08:00
|
|
|
extern int perf_trace_add(struct perf_event *event, int flags);
|
|
|
|
extern void perf_trace_del(struct perf_event *event, int flags);
|
2010-05-19 20:02:22 +08:00
|
|
|
extern int ftrace_profile_set_filter(struct perf_event *event, int event_id,
|
2009-10-15 11:21:42 +08:00
|
|
|
char *filter_str);
|
|
|
|
extern void ftrace_profile_free_filter(struct perf_event *event);
|
2010-05-19 16:52:27 +08:00
|
|
|
extern void *perf_trace_buf_prepare(int size, unsigned short type,
|
|
|
|
struct pt_regs *regs, int *rctxp);
|
2010-01-28 09:32:29 +08:00
|
|
|
|
|
|
|
static inline void
|
2010-03-05 12:35:37 +08:00
|
|
|
perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr,
|
2012-07-11 22:14:58 +08:00
|
|
|
u64 count, struct pt_regs *regs, void *head,
|
|
|
|
struct task_struct *task)
|
2010-01-28 09:32:29 +08:00
|
|
|
{
|
2012-07-11 22:14:58 +08:00
|
|
|
perf_tp_event(addr, count, raw_data, size, regs, head, rctx, task);
|
2010-01-28 09:32:29 +08:00
|
|
|
}
|
2009-10-15 11:21:42 +08:00
|
|
|
#endif
|
|
|
|
|
2009-04-13 23:20:49 +08:00
|
|
|
#endif /* _LINUX_FTRACE_EVENT_H */
|