7334 lines · 173.3 KB · C
RawDownload
/* * ring buffer based function tracer * * Copyright (C) 2007-2012 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 Nadia Yvette Chambers */#include <linux/ring_buffer.h>#include <generated/utsrelease.h>#include <linux/stacktrace.h>#include <linux/writeback.h>#include <linux/kallsyms.h>#include <linux/seq_file.h>#include <linux/notifier.h>#include <linux/irqflags.h>#include <linux/debugfs.h>#include <linux/tracefs.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/mount.h>#include <linux/rwsem.h>#include <linux/slab.h>#include <linux/ctype.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/nmi.h>#include <linux/fs.h>#include <linux/sched/rt.h> #include "trace.h"#include "trace_output.h" /* * 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. */bool 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; /* Pipe tracepoints to printk */struct trace_iterator *tracepoint_print_iter;int tracepoint_printk; /* 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 intdummy_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set){	return 0;} /* * To prevent the comm cache from being overwritten when no * tracing is active, only save the comm when a trace event * occurred. */static DEFINE_PER_CPU(bool, trace_cmdline_save); /* * 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; cpumask_var_t __read_mostly	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 * Set 1 if you want to dump buffers of all CPUs * Set 2 if you want to dump the buffer of the CPU that triggered oops */ enum ftrace_dump_mode ftrace_dump_on_oops; /* When set, tracing will stop when a WARN*() is hit */int __disable_trace_on_warning; #ifdef CONFIG_TRACE_ENUM_MAP_FILE/* Map of enums to their values, for "enum_map" file */struct trace_enum_map_head {	struct module			*mod;	unsigned long			length;}; union trace_enum_map_item; struct trace_enum_map_tail {	/*	 * "end" is first and points to NULL as it must be different	 * than "mod" or "enum_string"	 */	union trace_enum_map_item	*next;	const char			*end;	/* points to NULL */}; static DEFINE_MUTEX(trace_enum_mutex); /* * The trace_enum_maps are saved in an array with two extra elements, * one at the beginning, and one at the end. The beginning item contains * the count of the saved maps (head.length), and the module they * belong to if not built in (head.mod). The ending item contains a * pointer to the next array of saved enum_map items. */union trace_enum_map_item {	struct trace_enum_map		map;	struct trace_enum_map_head	head;	struct trace_enum_map_tail	tail;}; static union trace_enum_map_item *trace_enum_maps;#endif /* CONFIG_TRACE_ENUM_MAP_FILE */ static int tracing_set_tracer(struct trace_array *tr, const char *buf); #define MAX_TRACER_SIZE		100static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;static char *default_bootup_tracer; static bool allocate_snapshot; static int __init set_cmdline_ftrace(char *str){	strlcpy(bootup_tracer_buf, str, MAX_TRACER_SIZE);	default_bootup_tracer = bootup_tracer_buf;	/* We are using ftrace early, expand it */	ring_buffer_expanded = true;	return 1;}__setup("ftrace=", set_cmdline_ftrace); static int __init set_ftrace_dump_on_oops(char *str){	if (*str++ != '=' || !*str) {		ftrace_dump_on_oops = DUMP_ALL;		return 1;	} 	if (!strcmp("orig_cpu", str)) {		ftrace_dump_on_oops = DUMP_ORIG;                return 1;        }         return 0;}__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops); static int __init stop_trace_on_warning(char *str){	if ((strcmp(str, "=0") != 0 && strcmp(str, "=off") != 0))		__disable_trace_on_warning = 1;	return 1;}__setup("traceoff_on_warning", stop_trace_on_warning); static int __init boot_alloc_snapshot(char *str){	allocate_snapshot = true;	/* We also need the main ring buffer expanded */	ring_buffer_expanded = true;	return 1;}__setup("alloc_snapshot", boot_alloc_snapshot);  static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata; static int __init set_trace_boot_options(char *str){	strlcpy(trace_boot_options_buf, str, MAX_TRACER_SIZE);	return 0;}__setup("trace_options=", set_trace_boot_options); static char trace_boot_clock_buf[MAX_TRACER_SIZE] __initdata;static char *trace_boot_clock __initdata; static int __init set_trace_boot_clock(char *str){	strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE);	trace_boot_clock = trace_boot_clock_buf;	return 0;}__setup("trace_clock=", set_trace_boot_clock); static int __init set_tracepoint_printk(char *str){	if ((strcmp(str, "=0") != 0 && strcmp(str, "=off") != 0))		tracepoint_printk = 1;	return 1;}__setup("tp_printk", set_tracepoint_printk); unsigned long long ns2usecs(cycle_t nsec){	nsec += 500;	do_div(nsec, 1000);	return nsec;} /* trace_flags holds trace_options default values */#define TRACE_DEFAULT_FLAGS						\	(FUNCTION_DEFAULT_FLAGS |					\	 TRACE_ITER_PRINT_PARENT | TRACE_ITER_PRINTK |			\	 TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO |		\	 TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE |			\	 TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS) /* trace_options that are only supported by global_trace */#define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER_PRINTK |			\	       TRACE_ITER_PRINTK_MSGONLY | TRACE_ITER_RECORD_CMD)  /* * 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 = {	.trace_flags = TRACE_DEFAULT_FLAGS,}; LIST_HEAD(ftrace_trace_arrays); int trace_array_get(struct trace_array *this_tr){	struct trace_array *tr;	int ret = -ENODEV; 	mutex_lock(&trace_types_lock);	list_for_each_entry(tr, &ftrace_trace_arrays, list) {		if (tr == this_tr) {			tr->ref++;			ret = 0;			break;		}	}	mutex_unlock(&trace_types_lock); 	return ret;} static void __trace_array_put(struct trace_array *this_tr){	WARN_ON(!this_tr->ref);	this_tr->ref--;} void trace_array_put(struct trace_array *this_tr){	mutex_lock(&trace_types_lock);	__trace_array_put(this_tr);	mutex_unlock(&trace_types_lock);} int filter_check_discard(struct trace_event_file *file, void *rec,			 struct ring_buffer *buffer,			 struct ring_buffer_event *event){	if (unlikely(file->flags & EVENT_FILE_FL_FILTERED) &&	    !filter_match_preds(file->filter, rec)) {		ring_buffer_discard_commit(buffer, event);		return 1;	} 	return 0;}EXPORT_SYMBOL_GPL(filter_check_discard); int call_filter_check_discard(struct trace_event_call *call, void *rec,			      struct ring_buffer *buffer,			      struct ring_buffer_event *event){	if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) &&	    !filter_match_preds(call->filter, rec)) {		ring_buffer_discard_commit(buffer, event);		return 1;	} 	return 0;}EXPORT_SYMBOL_GPL(call_filter_check_discard); static cycle_t buffer_ftrace_now(struct trace_buffer *buf, int cpu){	u64 ts; 	/* Early boot up does not have a buffer yet */	if (!buf->buffer)		return trace_clock_local(); 	ts = ring_buffer_time_stamp(buf->buffer, cpu);	ring_buffer_normalize_time_stamp(buf->buffer, cpu, &ts); 	return ts;} cycle_t ftrace_now(int cpu){	return buffer_ftrace_now(&global_trace.trace_buffer, cpu);} /** * tracing_is_enabled - Show if global_trace has been disabled * * Shows if the global trace has been enabled or not. It uses the * mirror flag "buffer_disabled" to be used in fast paths such as for * the irqsoff tracer. But it may be inaccurate due to races. If you * need to know the accurate state, use tracing_is_on() which is a little * slower, but accurate. */int tracing_is_enabled(void){	/*	 * For quick access (irqsoff uses this in fast path), just	 * return the mirror variable of the state of the ring buffer.	 * It's a little racy, but we don't really care.	 */	smp_rmb();	return !global_trace.buffer_disabled;} /* * 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; /* * trace_types_lock is used to protect the trace_types list. */DEFINE_MUTEX(trace_types_lock); /* * serialize the access of the ring buffer * * ring buffer serializes readers, but it is low level protection. * The validity of the events (which returns by ring_buffer_peek() ..etc) * are not protected by ring buffer. * * The content of events may become garbage if we allow other process consumes * these events concurrently: *   A) the page of the consumed events may become a normal page *      (not reader page) in ring buffer, and this page will be rewrited *      by events producer. *   B) The page of the consumed events may become a page for splice_read, *      and this page will be returned to system. * * These primitives allow multi process access to different cpu ring buffer * concurrently. * * These primitives don't distinguish read-only and read-consume access. * Multi read-only access are also serialized. */ #ifdef CONFIG_SMPstatic DECLARE_RWSEM(all_cpu_access_lock);static DEFINE_PER_CPU(struct mutex, cpu_access_lock); static inline void trace_access_lock(int cpu){	if (cpu == RING_BUFFER_ALL_CPUS) {		/* gain it for accessing the whole ring buffer. */		down_write(&all_cpu_access_lock);	} else {		/* gain it for accessing a cpu ring buffer. */ 		/* Firstly block other trace_access_lock(RING_BUFFER_ALL_CPUS). */		down_read(&all_cpu_access_lock); 		/* Secondly block other access to this @cpu ring buffer. */		mutex_lock(&per_cpu(cpu_access_lock, cpu));	}} static inline void trace_access_unlock(int cpu){	if (cpu == RING_BUFFER_ALL_CPUS) {		up_write(&all_cpu_access_lock);	} else {		mutex_unlock(&per_cpu(cpu_access_lock, cpu));		up_read(&all_cpu_access_lock);	}} static inline void trace_access_lock_init(void){	int cpu; 	for_each_possible_cpu(cpu)		mutex_init(&per_cpu(cpu_access_lock, cpu));} #else static DEFINE_MUTEX(access_lock); static inline void trace_access_lock(int cpu){	(void)cpu;	mutex_lock(&access_lock);} static inline void trace_access_unlock(int cpu){	(void)cpu;	mutex_unlock(&access_lock);} static inline void trace_access_lock_init(void){} #endif #ifdef CONFIG_STACKTRACEstatic void __ftrace_trace_stack(struct ring_buffer *buffer,				 unsigned long flags,				 int skip, int pc, struct pt_regs *regs);static inline void ftrace_trace_stack(struct trace_array *tr,				      struct ring_buffer *buffer,				      unsigned long flags,				      int skip, int pc, struct pt_regs *regs); #elsestatic inline void __ftrace_trace_stack(struct ring_buffer *buffer,					unsigned long flags,					int skip, int pc, struct pt_regs *regs){}static inline void ftrace_trace_stack(struct trace_array *tr,				      struct ring_buffer *buffer,				      unsigned long flags,				      int skip, int pc, struct pt_regs *regs)

Lines 1–500 of 7334.