trace.h 6.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#ifndef _LINUX_KERNEL_TRACE_H
#define _LINUX_KERNEL_TRACE_H

#include <linux/fs.h>
#include <asm/atomic.h>
#include <linux/sched.h>
#include <linux/clocksource.h>

/*
 * Function trace entry - function address and parent function addres:
 */
struct ftrace_entry {
	unsigned long		ip;
	unsigned long		parent_ip;
};

/*
 * Context switch trace entry - which task (and prio) we switched from/to:
 */
struct ctx_switch_entry {
	unsigned int		prev_pid;
	unsigned char		prev_prio;
	unsigned char		prev_state;
	unsigned int		next_pid;
	unsigned char		next_prio;
};

I
Ingo Molnar 已提交
28 29 30 31 32 33 34 35 36
/*
 * Special (free-form) trace entry:
 */
struct special_entry {
	unsigned long		arg1;
	unsigned long		arg2;
	unsigned long		arg3;
};

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
/*
 * 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 {
	char			type;
	char			cpu;
	char			flags;
	char			preempt_count;
	int			pid;
	cycle_t			t;
	union {
		struct ftrace_entry		fn;
		struct ctx_switch_entry		ctx;
I
Ingo Molnar 已提交
53
		struct special_entry		special;
54 55 56 57 58 59 60 61 62 63 64
	};
};

#define TRACE_ENTRY_SIZE	sizeof(struct trace_entry)

/*
 * The CPU trace array - it consists of thousands of trace entries
 * plus some other descriptor data: (for example which task started
 * the trace, etc.)
 */
struct trace_array_cpu {
65
	struct list_head	trace_pages;
66
	atomic_t		disabled;
67
	spinlock_t		lock;
I
Ingo Molnar 已提交
68
	struct lock_class_key	lock_key;
I
Ingo Molnar 已提交
69

I
Ingo Molnar 已提交
70
	/* these fields get copied into max-trace: */
71 72 73 74
	unsigned		trace_head_idx;
	unsigned		trace_tail_idx;
	void			*trace_head; /* producer */
	void			*trace_tail; /* consumer */
I
Ingo Molnar 已提交
75
	unsigned long		trace_idx;
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	unsigned long		saved_latency;
	unsigned long		critical_start;
	unsigned long		critical_end;
	unsigned long		critical_sequence;
	unsigned long		nice;
	unsigned long		policy;
	unsigned long		rt_priority;
	cycle_t			preempt_timestamp;
	pid_t			pid;
	uid_t			uid;
	char			comm[TASK_COMM_LEN];
};

struct trace_iterator;

/*
 * The trace array - an array of per-CPU trace arrays. This is the
 * highest level data structure that individual tracers deal with.
 * They have on/off state as well:
 */
struct trace_array {
	unsigned long		entries;
	long			ctrl;
	int			cpu;
	cycle_t			time_start;
101
	struct task_struct	*waiter;
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
	struct trace_array_cpu	*data[NR_CPUS];
};

/*
 * A specific tracer, represented by methods that operate on a trace array:
 */
struct tracer {
	const char		*name;
	void			(*init)(struct trace_array *tr);
	void			(*reset)(struct trace_array *tr);
	void			(*open)(struct trace_iterator *iter);
	void			(*close)(struct trace_iterator *iter);
	void			(*start)(struct trace_iterator *iter);
	void			(*stop)(struct trace_iterator *iter);
	void			(*ctrl_update)(struct trace_array *tr);
S
Steven Rostedt 已提交
117 118 119 120
#ifdef CONFIG_FTRACE_STARTUP_TEST
	int			(*selftest)(struct tracer *trace,
					    struct trace_array *tr);
#endif
121 122 123 124
	struct tracer		*next;
	int			print_max;
};

S
Steven Rostedt 已提交
125 126 127 128 129
struct trace_seq {
	unsigned char		buffer[PAGE_SIZE];
	unsigned int		len;
};

130 131 132 133 134
/*
 * Trace iterator - used by printout routines who present trace
 * results to users and which routines might sleep, etc:
 */
struct trace_iterator {
S
Steven Rostedt 已提交
135
	struct trace_seq	seq;
136 137
	struct trace_array	*tr;
	struct tracer		*trace;
I
Ingo Molnar 已提交
138

139
	struct trace_entry	*ent;
I
Ingo Molnar 已提交
140 141 142 143 144
	int			cpu;

	struct trace_entry	*prev_ent;
	int			prev_cpu;

145 146 147
	unsigned long		iter_flags;
	loff_t			pos;
	unsigned long		next_idx[NR_CPUS];
148 149 150
	struct list_head	*next_page[NR_CPUS];
	unsigned		next_page_idx[NR_CPUS];
	long			idx;
151 152
};

I
Ingo Molnar 已提交
153
void tracing_reset(struct trace_array_cpu *data);
154 155 156 157 158 159 160 161 162 163 164 165 166
int tracing_open_generic(struct inode *inode, struct file *filp);
struct dentry *tracing_init_dentry(void);
void ftrace(struct trace_array *tr,
			    struct trace_array_cpu *data,
			    unsigned long ip,
			    unsigned long parent_ip,
			    unsigned long flags);
void tracing_sched_switch_trace(struct trace_array *tr,
				struct trace_array_cpu *data,
				struct task_struct *prev,
				struct task_struct *next,
				unsigned long flags);
void tracing_record_cmdline(struct task_struct *tsk);
167 168 169 170 171 172

void tracing_sched_wakeup_trace(struct trace_array *tr,
				struct trace_array_cpu *data,
				struct task_struct *wakee,
				struct task_struct *cur,
				unsigned long flags);
I
Ingo Molnar 已提交
173 174 175 176 177
void trace_special(struct trace_array *tr,
		   struct trace_array_cpu *data,
		   unsigned long arg1,
		   unsigned long arg2,
		   unsigned long arg3);
178 179 180 181 182
void trace_function(struct trace_array *tr,
		    struct trace_array_cpu *data,
		    unsigned long ip,
		    unsigned long parent_ip,
		    unsigned long flags);
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

void tracing_start_function_trace(void);
void tracing_stop_function_trace(void);
int register_tracer(struct tracer *type);
void unregister_tracer(struct tracer *type);

extern unsigned long nsecs_to_usecs(unsigned long nsecs);

extern unsigned long tracing_max_latency;
extern unsigned long tracing_thresh;

void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu);
void update_max_tr_single(struct trace_array *tr,
			  struct task_struct *tsk, int cpu);

I
Ingo Molnar 已提交
198
extern cycle_t ftrace_now(int cpu);
199 200

#ifdef CONFIG_SCHED_TRACER
I
Ingo Molnar 已提交
201
extern void
202
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next);
203 204
extern void
wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr);
205 206 207 208 209
#else
static inline void
wakeup_sched_switch(struct task_struct *prev, struct task_struct *next)
{
}
210 211 212 213
static inline void
wakeup_sched_wakeup(struct task_struct *wakee, struct task_struct *curr)
{
}
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
#endif

#ifdef CONFIG_CONTEXT_SWITCH_TRACER
typedef void
(*tracer_switch_func_t)(void *private,
			struct task_struct *prev,
			struct task_struct *next);

struct tracer_switch_ops {
	tracer_switch_func_t		func;
	void				*private;
	struct tracer_switch_ops	*next;
};

extern int register_tracer_switch(struct tracer_switch_ops *ops);
extern int unregister_tracer_switch(struct tracer_switch_ops *ops);

#endif /* CONFIG_CONTEXT_SWITCH_TRACER */

#ifdef CONFIG_DYNAMIC_FTRACE
extern unsigned long ftrace_update_tot_cnt;
#endif

S
Steven Rostedt 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
#ifdef CONFIG_FTRACE_STARTUP_TEST
#ifdef CONFIG_FTRACE
extern int trace_selftest_startup_function(struct tracer *trace,
					   struct trace_array *tr);
#endif
#ifdef CONFIG_IRQSOFF_TRACER
extern int trace_selftest_startup_irqsoff(struct tracer *trace,
					  struct trace_array *tr);
#endif
#ifdef CONFIG_PREEMPT_TRACER
extern int trace_selftest_startup_preemptoff(struct tracer *trace,
					     struct trace_array *tr);
#endif
#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace,
						 struct trace_array *tr);
#endif
#ifdef CONFIG_SCHED_TRACER
extern int trace_selftest_startup_wakeup(struct tracer *trace,
					 struct trace_array *tr);
#endif
#ifdef CONFIG_CONTEXT_SWITCH_TRACER
extern int trace_selftest_startup_sched_switch(struct tracer *trace,
					       struct trace_array *tr);
#endif
#endif /* CONFIG_FTRACE_STARTUP_TEST */

I
Ingo Molnar 已提交
264 265
extern void *head_page(struct trace_array_cpu *data);

266
#endif /* _LINUX_KERNEL_TRACE_H */