4480 lines · 99.4 KB · C
RawDownload
/* * ring buffer based function tracer * * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com> * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com> * * Originally taken from the RT patch by: *    Arnaldo Carvalho de Melo <acme@redhat.com> * * Based on code from the latency_tracer, that is: *  Copyright (C) 2004-2006 Ingo Molnar *  Copyright (C) 2004 William Lee Irwin III */#include <linux/ring_buffer.h>#include <linux/utsrelease.h>#include <linux/stacktrace.h>#include <linux/writeback.h>#include <linux/kallsyms.h>#include <linux/seq_file.h>#include <linux/smp_lock.h>#include <linux/notifier.h>#include <linux/irqflags.h>#include <linux/debugfs.h>#include <linux/pagemap.h>#include <linux/hardirq.h>#include <linux/linkage.h>#include <linux/uaccess.h>#include <linux/kprobes.h>#include <linux/ftrace.h>#include <linux/module.h>#include <linux/percpu.h>#include <linux/splice.h>#include <linux/kdebug.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/gfp.h>#include <linux/fs.h> #include "trace.h"#include "trace_output.h" #define TRACE_BUFFER_FLAGS	(RB_FL_OVERWRITE) /* * On boot up, the ring buffer is set to the minimum size, so that * we do not waste memory on systems that are not using tracing. */int ring_buffer_expanded; /* * We need to change this state when a selftest is running. * A selftest will lurk into the ring-buffer to count the * entries inserted during the selftest although some concurrent * insertions into the ring-buffer such as trace_printk could occurred * at the same time, giving false positive or negative results. */static bool __read_mostly tracing_selftest_running; /* * If a tracer is running, we do not want to run SELFTEST. */bool __read_mostly tracing_selftest_disabled; /* For tracers that don't implement custom flags */static struct tracer_opt dummy_tracer_opt[] = {	{ }}; static struct tracer_flags dummy_tracer_flags = {	.val = 0,	.opts = dummy_tracer_opt}; static int dummy_set_flag(u32 old_flags, u32 bit, int set){	return 0;} /* * Kill all tracing for good (never come back). * It is initialized to 1 but will turn to zero if the initialization * of the tracer is successful. But that is the only place that sets * this back to zero. */static int tracing_disabled = 1; DEFINE_PER_CPU(local_t, ftrace_cpu_disabled); static inline void ftrace_disable_cpu(void){	preempt_disable();	local_inc(&__get_cpu_var(ftrace_cpu_disabled));} static inline void ftrace_enable_cpu(void){	local_dec(&__get_cpu_var(ftrace_cpu_disabled));	preempt_enable();} static cpumask_var_t __read_mostly	tracing_buffer_mask; /* Define which cpu buffers are currently read in trace_pipe */static cpumask_var_t			tracing_reader_cpumask; #define for_each_tracing_cpu(cpu)	\	for_each_cpu(cpu, tracing_buffer_mask) /* * ftrace_dump_on_oops - variable to dump ftrace buffer on oops * * If there is an oops (or kernel panic) and the ftrace_dump_on_oops * is set, then ftrace_dump is called. This will output the contents * of the ftrace buffers to the console.  This is very useful for * capturing traces that lead to crashes and outputing it to a * serial console. * * It is default off, but you can enable it with either specifying * "ftrace_dump_on_oops" in the kernel command line, or setting * /proc/sys/kernel/ftrace_dump_on_oops to true. */int ftrace_dump_on_oops; static int tracing_set_tracer(const char *buf); #define MAX_TRACER_SIZE		100static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;static char *default_bootup_tracer; static int __init set_ftrace(char *str){	strncpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);	default_bootup_tracer = bootup_tracer_buf;	/* We are using ftrace early, expand it */	ring_buffer_expanded = 1;	return 1;}__setup("ftrace=", set_ftrace); static int __init set_ftrace_dump_on_oops(char *str){	ftrace_dump_on_oops = 1;	return 1;}__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); unsigned long long ns2usecs(cycle_t nsec){	nsec += 500;	do_div(nsec, 1000);	return nsec;} /* * The global_trace is the descriptor that holds the tracing * buffers for the live tracing. For each CPU, it contains * a link list of pages that will store trace entries. The * page descriptor of the pages in the memory is used to hold * the link list by linking the lru item in the page descriptor * to each of the pages in the buffer per CPU. * * For each active CPU there is a data field that holds the * pages for the buffer for that CPU. Each CPU has the same number * of pages allocated for its buffer. */static struct trace_array	global_trace; static DEFINE_PER_CPU(struct trace_array_cpu, global_trace_cpu); int filter_current_check_discard(struct ring_buffer *buffer,				 struct ftrace_event_call *call, void *rec,				 struct ring_buffer_event *event){	return filter_check_discard(call, rec, buffer, event);}EXPORT_SYMBOL_GPL(filter_current_check_discard); cycle_t ftrace_now(int cpu){	u64 ts; 	/* Early boot up does not have a buffer yet */	if (!global_trace.buffer)		return trace_clock_local(); 	ts = ring_buffer_time_stamp(global_trace.buffer, cpu);	ring_buffer_normalize_time_stamp(global_trace.buffer, cpu, &ts); 	return ts;} /* * The max_tr is used to snapshot the global_trace when a maximum * latency is reached. Some tracers will use this to store a maximum * trace while it continues examining live traces. * * The buffers for the max_tr are set up the same as the global_trace. * When a snapshot is taken, the link list of the max_tr is swapped * with the link list of the global_trace and the buffers are reset for * the global_trace so the tracing can continue. */static struct trace_array	max_tr; static DEFINE_PER_CPU(struct trace_array_cpu, max_data); /* tracer_enabled is used to toggle activation of a tracer */static int			tracer_enabled = 1; /** * tracing_is_enabled - return tracer_enabled status * * This function is used by other tracers to know the status * of the tracer_enabled flag.  Tracers may use this function * to know if it should enable their features when starting * up. See irqsoff tracer for an example (start_irqsoff_tracer). */int tracing_is_enabled(void){	return tracer_enabled;} /* * trace_buf_size is the size in bytes that is allocated * for a buffer. Note, the number of bytes is always rounded * to page size. * * This number is purposely set to a low number of 16384. * If the dump on oops happens, it will be much appreciated * to not have to wait for all that output. Anyway this can be * boot time and run time configurable. */#define TRACE_BUF_SIZE_DEFAULT	1441792UL /* 16384 * 88 (sizeof(entry)) */ static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT; /* trace_types holds a link list of available tracers. */static struct tracer		*trace_types __read_mostly; /* current_trace points to the tracer that is currently active */static struct tracer		*current_trace __read_mostly; /* * trace_types_lock is used to protect the trace_types list. * This lock is also used to keep user access serialized. * Accesses from userspace will grab this lock while userspace * activities happen inside the kernel. */static DEFINE_MUTEX(trace_types_lock); /* trace_wait is a waitqueue for tasks blocked on trace_poll */static DECLARE_WAIT_QUEUE_HEAD(trace_wait); /* trace_flags holds trace_options default values */unsigned long trace_flags = TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |	TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | TRACE_ITER_SLEEP_TIME |	TRACE_ITER_GRAPH_TIME; static int trace_stop_count;static DEFINE_SPINLOCK(tracing_start_lock); /** * trace_wake_up - wake up tasks waiting for trace input * * Simply wakes up any task that is blocked on the trace_wait * queue. These is used with trace_poll for tasks polling the trace. */void trace_wake_up(void){	int cpu; 	if (trace_flags & TRACE_ITER_BLOCK)		return;	/*	 * The runqueue_is_locked() can fail, but this is the best we	 * have for now:	 */	cpu = get_cpu();	if (!runqueue_is_locked(cpu))		wake_up(&trace_wait);	put_cpu();} static int __init set_buf_size(char *str){	unsigned long buf_size; 	if (!str)		return 0;	buf_size = memparse(str, &str);	/* nr_entries can not be zero */	if (buf_size == 0)		return 0;	trace_buf_size = buf_size;	return 1;}__setup("trace_buf_size=", set_buf_size); unsigned long nsecs_to_usecs(unsigned long nsecs){	return nsecs / 1000;} /* These must match the bit postions in trace_iterator_flags */static const char *trace_options[] = {	"print-parent",	"sym-offset",	"sym-addr",	"verbose",	"raw",	"hex",	"bin",	"block",	"stacktrace",	"sched-tree",	"trace_printk",	"ftrace_preempt",	"branch",	"annotate",	"userstacktrace",	"sym-userobj",	"printk-msg-only",	"context-info",	"latency-format",	"sleep-time",	"graph-time",	NULL}; static struct {	u64 (*func)(void);	const char *name;} trace_clocks[] = {	{ trace_clock_local,	"local" },	{ trace_clock_global,	"global" },}; int trace_clock_id; /* * trace_parser_get_init - gets the buffer for trace parser */int trace_parser_get_init(struct trace_parser *parser, int size){	memset(parser, 0, sizeof(*parser)); 	parser->buffer = kmalloc(size, GFP_KERNEL);	if (!parser->buffer)		return 1; 	parser->size = size;	return 0;} /* * trace_parser_put - frees the buffer for trace parser */void trace_parser_put(struct trace_parser *parser){	kfree(parser->buffer);} /* * trace_get_user - reads the user input string separated by  space * (matched by isspace(ch)) * * For each string found the 'struct trace_parser' is updated, * and the function returns. * * Returns number of bytes read. * * See kernel/trace/trace.h for 'struct trace_parser' details. */int trace_get_user(struct trace_parser *parser, const char __user *ubuf,	size_t cnt, loff_t *ppos){	char ch;	size_t read = 0;	ssize_t ret; 	if (!*ppos)		trace_parser_clear(parser); 	ret = get_user(ch, ubuf++);	if (ret)		goto out; 	read++;	cnt--; 	/*	 * The parser is not finished with the last write,	 * continue reading the user input without skipping spaces.	 */	if (!parser->cont) {		/* skip white space */		while (cnt && isspace(ch)) {			ret = get_user(ch, ubuf++);			if (ret)				goto out;			read++;			cnt--;		} 		/* only spaces were written */		if (isspace(ch)) {			*ppos += read;			ret = read;			goto out;		} 		parser->idx = 0;	} 	/* read the non-space input */	while (cnt && !isspace(ch)) {		if (parser->idx < parser->size - 1)			parser->buffer[parser->idx++] = ch;		else {			ret = -EINVAL;			goto out;		}		ret = get_user(ch, ubuf++);		if (ret)			goto out;		read++;		cnt--;	} 	/* We either got finished input or we have to wait for another call. */	if (isspace(ch)) {		parser->buffer[parser->idx] = 0;		parser->cont = false;	} else {		parser->cont = true;		parser->buffer[parser->idx++] = ch;	} 	*ppos += read;	ret = read; out:	return ret;} ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt){	int len;	int ret; 	if (!cnt)		return 0; 	if (s->len <= s->readpos)		return -EBUSY; 	len = s->len - s->readpos;	if (cnt > len)		cnt = len;	ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);	if (ret == cnt)		return -EFAULT; 	cnt -= ret; 	s->readpos += cnt;	return cnt;} static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt){	int len;	void *ret; 	if (s->len <= s->readpos)		return -EBUSY; 	len = s->len - s->readpos;	if (cnt > len)		cnt = len;	ret = memcpy(buf, s->buffer + s->readpos, cnt);	if (!ret)		return -EFAULT; 	s->readpos += cnt;	return cnt;} /* * ftrace_max_lock is used to protect the swapping of buffers * when taking a max snapshot. The buffers themselves are * protected by per_cpu spinlocks. But the action of the swap * needs its own lock. * * This is defined as a raw_spinlock_t in order to help * with performance when lockdep debugging is enabled. * * It is also used in other places outside the update_max_tr * so it needs to be defined outside of the

Lines 1–500 of 4480.