static inline void trace_access_lock(int cpu)
{
	(void)cpu;
	mutex_lock(&access_lock);
}

static bool __read_mostly

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

static DEFINE_MUTEX(trace_eval_mutex);

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);

static DEFINE_MUTEX(tracepoint_printk_mutex);

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;


static struct dentry *trace_options_init_dentry(struct trace_array *tr)
{
	struct dentry *d_tracer;

	if (tr->options)
		return tr->options;

	d_tracer = tracing_get_dentry(tr);
	if (IS_ERR(d_tracer))
		return NULL;

	tr->options = tracefs_create_dir("options", d_tracer);
	if (!tr->options) {
		pr_warn("Could not create tracefs directory 'options'\n");
		return NULL;
	}

	return tr->options;
}

tracing: Fix possible double free on failure of allocating trace buffer

Jing Xia and Chunyan Zhang reported that on failing to allocate part of the
tracing buffer, memory is freed, but the pointers that point to them are not
initialized back to NULL, and later paths may try to free the freed memory
again. Jing and Chunyan fixed one of the locations that does this, but
missed a spot.

Link: http://lkml.kernel.org/r/20171226071253.8968-1-chunyan.zhang@spreadtrum.com

Cc: stable@vger.kernel.org
Fixes: 737223fbca3b1 ("tracing: Consolidate buffer allocation code")
Reported-by: Jing Xia <jing.xia@spreadtrum.com>
Reported-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);


static void __trace_userstack(struct trace_array *tr, unsigned long flags)
{
	ftrace_trace_userstack(tr, flags, preempt_count());
}

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;


static int tracing_open(struct inode *inode, struct file *file)
{
	struct trace_array *tr = inode->i_private;
	struct trace_iterator *iter;
	int ret = 0;

	if (trace_array_get(tr) < 0)
		return -ENODEV;

	/* If this file was open for write, then erase contents */
	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
		int cpu = tracing_get_cpu(inode);
		struct trace_buffer *trace_buf = &tr->trace_buffer;

#ifdef CONFIG_TRACER_MAX_TRACE
		if (tr->current_trace->print_max)
			trace_buf = &tr->max_buffer;
#endif

		if (cpu == RING_BUFFER_ALL_CPUS)
			tracing_reset_online_cpus(trace_buf);
		else
			tracing_reset(trace_buf, cpu);
	}

	if (file->f_mode & FMODE_READ) {
		iter = __tracing_open(inode, file, false);
		if (IS_ERR(iter))
			ret = PTR_ERR(iter);
		else if (tr->trace_flags & TRACE_ITER_LATENCY_FMT)
			iter->iter_flags |= TRACE_FILE_LAT_FMT;
	}

	if (ret < 0)
		trace_array_put(tr);

	return ret;
}

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;


static inline void set_cmdline(int idx, const char *cmdline)
{
	memcpy(get_saved_cmdlines(idx), cmdline, TASK_COMM_LEN);
}

static bool __read_mostly

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);

static DEFINE_MUTEX(tracepoint_printk_mutex);

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);


ftrace_trace_snapshot_callback(struct trace_array *tr, struct ftrace_hash *hash,
			       char *glob, char *cmd, char *param, int enable)
{
	struct ftrace_probe_ops *ops;
	void *count = (void *)-1;
	char *number;
	int ret;

	if (!tr)
		return -ENODEV;

	/* hash funcs only work with set_ftrace_filter */
	if (!enable)
		return -EINVAL;

	ops = param ? &snapshot_count_probe_ops :  &snapshot_probe_ops;

	if (glob[0] == '!')
		return unregister_ftrace_function_probe_func(glob+1, tr, ops);

	if (!param)
		goto out_reg;

	number = strsep(&param, ":");

	if (!strlen(number))
		goto out_reg;

	/*
	 * We use the callback data field (which is a pointer)
	 * as our counter.
	 */
	ret = kstrtoul(number, 0, (unsigned long *)&count);
	if (ret)
		return ret;

 out_reg:
	ret = alloc_snapshot(tr);
	if (ret < 0)
		goto out;

	ret = register_ftrace_function_probe(glob, tr, ops, count);

 out:
	return ret < 0 ? ret : 0;
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}


static void *saved_tgids_next(struct seq_file *m, void *v, loff_t *pos)
{
	int *ptr = v;

	if (*pos || m->count)
		ptr++;

	(*pos)++;

	for (; ptr <= &tgid_map[PID_MAX_DEFAULT]; ptr++) {
		if (trace_find_tgid(*ptr))
			return ptr;
	}

	return NULL;
}


int trace_array_vprintk(struct trace_array *tr,
			unsigned long ip, const char *fmt, va_list args)
{
	return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args);
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;


tracing_buffers_poll(struct file *filp, poll_table *poll_table)
{
	struct ftrace_buffer_info *info = filp->private_data;
	struct trace_iterator *iter = &info->iter;

	return trace_poll(iter, filp, poll_table);
}

struct trace_iterator *tracepoint_print_iter;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};

static const struct file_operations tracing_fops = {
	.open		= tracing_open,
	.read		= seq_read,
	.write		= tracing_write_stub,
	.llseek		= tracing_lseek,
	.release	= tracing_release,
};


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 int saved_tgids_show(struct seq_file *m, void *v)
{
	int pid = (int *)v - tgid_map;

	seq_printf(m, "%d %d\n", pid, trace_find_tgid(pid));
	return 0;
}


__init static int tracer_alloc_buffers(void)
{
	int ring_buf_size;
	int ret = -ENOMEM;

	/*
	 * Make sure we don't accidently add more trace options
	 * than we have bits for.
	 */
	BUILD_BUG_ON(TRACE_ITER_LAST_BIT > TRACE_FLAGS_MAX_SIZE);

	if (!alloc_cpumask_var(&tracing_buffer_mask, GFP_KERNEL))
		goto out;

	if (!alloc_cpumask_var(&global_trace.tracing_cpumask, GFP_KERNEL))
		goto out_free_buffer_mask;

	/* Only allocate trace_printk buffers if a trace_printk exists */
	if (__stop___trace_bprintk_fmt != __start___trace_bprintk_fmt)
		/* Must be called before global_trace.buffer is allocated */
		trace_printk_init_buffers();

	/* To save memory, keep the ring buffer size to its minimum */
	if (ring_buffer_expanded)
		ring_buf_size = trace_buf_size;
	else
		ring_buf_size = 1;

	cpumask_copy(tracing_buffer_mask, cpu_possible_mask);
	cpumask_copy(global_trace.tracing_cpumask, cpu_all_mask);

	raw_spin_lock_init(&global_trace.start_lock);

	/*
	 * The prepare callbacks allocates some memory for the ring buffer. We
	 * don't free the buffer if the if the CPU goes down. If we were to free
	 * the buffer, then the user would lose any trace that was in the
	 * buffer. The memory will be removed once the "instance" is removed.
	 */
	ret = cpuhp_setup_state_multi(CPUHP_TRACE_RB_PREPARE,
				      "trace/RB:preapre", trace_rb_cpu_prepare,
				      NULL);
	if (ret < 0)
		goto out_free_cpumask;
	/* Used for event triggers */
	ret = -ENOMEM;
	temp_buffer = ring_buffer_alloc(PAGE_SIZE, RB_FL_OVERWRITE);
	if (!temp_buffer)
		goto out_rm_hp_state;

	if (trace_create_savedcmd() < 0)
		goto out_free_temp_buffer;

	/* TODO: make the number of buffers hot pluggable with CPUS */
	if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
		printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
		WARN_ON(1);
		goto out_free_savedcmd;
	}

	if (global_trace.buffer_disabled)
		tracing_off();

	if (trace_boot_clock) {
		ret = tracing_set_clock(&global_trace, trace_boot_clock);
		if (ret < 0)
			pr_warn("Trace clock %s not defined, going back to default\n",
				trace_boot_clock);
	}

	/*
	 * register_tracer() might reference current_trace, so it
	 * needs to be set before we register anything. This is
	 * just a bootstrap of current_trace anyway.
	 */
	global_trace.current_trace = &nop_trace;

	global_trace.max_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED;

	ftrace_init_global_array_ops(&global_trace);

	init_trace_flags_index(&global_trace);

	register_tracer(&nop_trace);

	/* Function tracing may start here (via kernel command line) */
	init_function_trace();

	/* All seems OK, enable tracing */
	tracing_disabled = 0;

	atomic_notifier_chain_register(&panic_notifier_list,
				       &trace_panic_notifier);

	register_die_notifier(&trace_die_notifier);

	global_trace.flags = TRACE_ARRAY_FL_GLOBAL;

	INIT_LIST_HEAD(&global_trace.systems);
	INIT_LIST_HEAD(&global_trace.events);
	list_add(&global_trace.list, &ftrace_trace_arrays);

	apply_trace_boot_options();

	register_snapshot_cmd();

	return 0;

out_free_savedcmd:
	free_saved_cmdlines_buffer(savedcmd);
out_free_temp_buffer:
	ring_buffer_free(temp_buffer);
out_rm_hp_state:
	cpuhp_remove_multi_state(CPUHP_TRACE_RB_PREPARE);
out_free_cpumask:
	free_cpumask_var(global_trace.tracing_cpumask);
out_free_buffer_mask:
	free_cpumask_var(tracing_buffer_mask);
out:
	return ret;
}

bool ring_buffer_expanded;

static bool __read_mostly

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);

static DEFINE_MUTEX(tracepoint_printk_mutex);

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);


int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
{
	/* do nothing if flag is already set */
	if (!!(tr->trace_flags & mask) == !!enabled)
		return 0;

	/* Give the tracer a chance to approve the change */
	if (tr->current_trace->flag_changed)
		if (tr->current_trace->flag_changed(tr, mask, !!enabled))
			return -EINVAL;

	if (enabled)
		tr->trace_flags |= mask;
	else
		tr->trace_flags &= ~mask;

	if (mask == TRACE_ITER_RECORD_CMD)
		trace_event_enable_cmd_record(enabled);

	if (mask == TRACE_ITER_RECORD_TGID) {
		if (!tgid_map)
			tgid_map = kzalloc((PID_MAX_DEFAULT + 1) * sizeof(*tgid_map),
					   GFP_KERNEL);
		if (!tgid_map) {
			tr->trace_flags &= ~TRACE_ITER_RECORD_TGID;
			return -ENOMEM;
		}

		trace_event_enable_tgid_record(enabled);
	}

	if (mask == TRACE_ITER_EVENT_FORK)
		trace_event_follow_fork(tr, enabled);

	if (mask == TRACE_ITER_FUNC_FORK)
		ftrace_pid_follow_fork(tr, enabled);

	if (mask == TRACE_ITER_OVERWRITE) {
		ring_buffer_change_overwrite(tr->trace_buffer.buffer, enabled);
#ifdef CONFIG_TRACER_MAX_TRACE
		ring_buffer_change_overwrite(tr->max_buffer.buffer, enabled);
#endif
	}

	if (mask == TRACE_ITER_PRINTK) {
		trace_printk_start_stop_comm(enabled);
		trace_printk_control(enabled);
	}

	return 0;
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

#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)

#define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER_PRINTK |			\
	       TRACE_ITER_PRINTK_MSGONLY | TRACE_ITER_RECORD_CMD)

#define ZEROED_TRACE_FLAGS \
	(TRACE_ITER_EVENT_FORK | TRACE_ITER_FUNC_FORK)

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

#define TRACE_BUF_SIZE_DEFAULT	1441792UL /* 16384 * 88 (sizeof(entry)) */

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))


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;
}

bool ring_buffer_expanded;

static bool __read_mostly

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);

static DEFINE_MUTEX(tracepoint_printk_mutex);

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);


int tracing_alloc_snapshot(void)
{
	struct trace_array *tr = &global_trace;
	int ret;

	ret = alloc_snapshot(tr);
	WARN_ON(ret < 0);

	return ret;
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};


struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
					  int *ent_cpu, u64 *ent_ts)
{
	return __find_next_entry(iter, ent_cpu, NULL, ent_ts);
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};


int trace_run_command(const char *buf, int (*createfn)(int, char **))
{
	char **argv;
	int argc, ret;

	argc = 0;
	ret = 0;
	argv = argv_split(GFP_KERNEL, buf, &argc);
	if (!argv)
		return -ENOMEM;

	if (argc)
		ret = createfn(argc, argv);

	argv_free(argv);

	return ret;
}

int tracepoint_printk;

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static 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);

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static int trace_buffered_event_ref;

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};

static const struct file_operations tracing_fops = {
	.open		= tracing_open,
	.read		= seq_read,
	.write		= tracing_write_stub,
	.llseek		= tracing_lseek,
	.release	= tracing_release,
};

static const struct file_operations show_traces_fops = {
	.open		= show_traces_open,
	.read		= seq_read,
	.release	= seq_release,
	.llseek		= seq_lseek,
};

static const struct file_operations tracing_cpumask_fops = {
	.open		= tracing_open_generic_tr,
	.read		= tracing_cpumask_read,
	.write		= tracing_cpumask_write,
	.release	= tracing_release_generic_tr,
	.llseek		= generic_file_llseek,
};


void tracing_start(void)
{
	struct ring_buffer *buffer;
	unsigned long flags;

	if (tracing_disabled)
		return;

	raw_spin_lock_irqsave(&global_trace.start_lock, flags);
	if (--global_trace.stop_count) {
		if (global_trace.stop_count < 0) {
			/* Someone screwed up their debugging */
			WARN_ON_ONCE(1);
			global_trace.stop_count = 0;
		}
		goto out;
	}

	/* Prevent the buffers from switching */
	arch_spin_lock(&global_trace.max_lock);

	buffer = global_trace.trace_buffer.buffer;
	if (buffer)
		ring_buffer_record_enable(buffer);

#ifdef CONFIG_TRACER_MAX_TRACE
	buffer = global_trace.max_buffer.buffer;
	if (buffer)
		ring_buffer_record_enable(buffer);
#endif

	arch_spin_unlock(&global_trace.max_lock);

 out:
	raw_spin_unlock_irqrestore(&global_trace.start_lock, flags);
}

struct trace_iterator *tracepoint_print_iter;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};


static int tracing_wait_pipe(struct file *filp)
{
	struct trace_iterator *iter = filp->private_data;
	int ret;

	while (trace_empty(iter)) {

		if ((filp->f_flags & O_NONBLOCK)) {
			return -EAGAIN;
		}

		/*
		 * We block until we read something and tracing is disabled.
		 * We still block if tracing is disabled, but we have never
		 * read anything. This allows a user to cat this file, and
		 * then enable tracing. But after we have read something,
		 * we give an EOF when tracing is again disabled.
		 *
		 * iter->pos will be 0 if we haven't read anything.
		 */
		if (!tracer_tracing_is_on(iter->tr) && iter->pos)
			break;

		mutex_unlock(&iter->mutex);

		ret = wait_on_pipe(iter, false);

		mutex_lock(&iter->mutex);

		if (ret)
			return ret;
	}

	return 1;
}


void tracing_snapshot(void)
{
	struct trace_array *tr = &global_trace;

	tracing_snapshot_instance(tr);
}

struct trace_iterator *tracepoint_print_iter;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};

static const struct file_operations tracing_fops = {
	.open		= tracing_open,
	.read		= seq_read,
	.write		= tracing_write_stub,
	.llseek		= tracing_lseek,
	.release	= tracing_release,
};


static void s_stop(struct seq_file *m, void *p)
{
	struct trace_iterator *iter = m->private;

#ifdef CONFIG_TRACER_MAX_TRACE
	if (iter->snapshot && iter->trace->use_max_tr)
		return;
#endif

	if (!iter->snapshot)
		atomic_dec(&trace_record_taskinfo_disabled);

	trace_access_unlock(iter->cpu_file);
	trace_event_read_unlock();
}


enum print_line_t trace_handle_return(struct trace_seq *s)
{
	return trace_seq_has_overflowed(s) ?
		TRACE_TYPE_PARTIAL_LINE : TRACE_TYPE_HANDLED;
}

struct trace_iterator *tracepoint_print_iter;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

enum ftrace_dump_mode ftrace_dump_on_oops;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};

static const struct file_operations tracing_fops = {
	.open		= tracing_open,
	.read		= seq_read,
	.write		= tracing_write_stub,
	.llseek		= tracing_lseek,
	.release	= tracing_release,
};


trace_options_core_write(struct file *filp, const char __user *ubuf, size_t cnt,
			 loff_t *ppos)
{
	void *tr_index = filp->private_data;
	struct trace_array *tr;
	unsigned int index;
	unsigned long val;
	int ret;

	get_tr_index(tr_index, &tr, &index);

	ret = kstrtoul_from_user(ubuf, cnt, 10, &val);
	if (ret)
		return ret;

	if (val != 0 && val != 1)
		return -EINVAL;

	mutex_lock(&trace_types_lock);
	ret = set_tracer_flag(tr, 1 << index, val);
	mutex_unlock(&trace_types_lock);

	if (ret < 0)
		return ret;

	*ppos += cnt;

	return cnt;
}


void trace_printk_init_buffers(void)
{
	if (buffers_allocated)
		return;

	if (alloc_percpu_trace_buffer())
		return;

	/* trace_printk() is for debug use only. Don't use it in production. */

	pr_warn("\n");
	pr_warn("**********************************************************\n");
	pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
	pr_warn("**                                                      **\n");
	pr_warn("** trace_printk() being used. Allocating extra memory.  **\n");
	pr_warn("**                                                      **\n");
	pr_warn("** This means that this is a DEBUG kernel and it is     **\n");
	pr_warn("** unsafe for production use.                           **\n");
	pr_warn("**                                                      **\n");
	pr_warn("** If you see this message and you are not debugging    **\n");
	pr_warn("** the kernel, report this immediately to your vendor!  **\n");
	pr_warn("**                                                      **\n");
	pr_warn("**   NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE   **\n");
	pr_warn("**********************************************************\n");

	/* Expand the buffers to set size */
	tracing_update_buffers();

	buffers_allocated = 1;

	/*
	 * trace_printk_init_buffers() can be called by modules.
	 * If that happens, then we need to start cmdline recording
	 * directly here. If the global_trace.buffer is already
	 * allocated here, then this was called by module code.
	 */
	if (global_trace.trace_buffer.buffer)
		tracing_start_cmdline_record();
}

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static 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);

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};


void trace_buffer_unlock_commit_regs(struct trace_array *tr,
				     struct ring_buffer *buffer,
				     struct ring_buffer_event *event,
				     unsigned long flags, int pc,
				     struct pt_regs *regs)
{
	__buffer_unlock_commit(buffer, event);

	/*
	 * If regs is not set, then skip the following callers:
	 *   trace_buffer_unlock_commit_regs
	 *   event_trigger_unlock_commit
	 *   trace_event_buffer_commit
	 *   trace_event_raw_event_sched_switch
	 * Note, we can still get here via blktrace, wakeup tracer
	 * and mmiotrace, but that's ok if they lose a function or
	 * two. They are that meaningful.
	 */
	ftrace_trace_stack(tr, buffer, flags, regs ? 0 : 4, pc, regs);
	ftrace_trace_userstack(buffer, flags, pc);
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};


static ssize_t tracing_splice_read_pipe(struct file *filp,
					loff_t *ppos,
					struct pipe_inode_info *pipe,
					size_t len,
					unsigned int flags)
{
	struct page *pages_def[PIPE_DEF_BUFFERS];
	struct partial_page partial_def[PIPE_DEF_BUFFERS];
	struct trace_iterator *iter = filp->private_data;
	struct splice_pipe_desc spd = {
		.pages		= pages_def,
		.partial	= partial_def,
		.nr_pages	= 0, /* This gets updated below. */
		.nr_pages_max	= PIPE_DEF_BUFFERS,
		.ops		= &tracing_pipe_buf_ops,
		.spd_release	= tracing_spd_release_pipe,
	};
	ssize_t ret;
	size_t rem;
	unsigned int i;

	if (splice_grow_spd(pipe, &spd))
		return -ENOMEM;

	mutex_lock(&iter->mutex);

	if (iter->trace->splice_read) {
		ret = iter->trace->splice_read(iter, filp,
					       ppos, pipe, len, flags);
		if (ret)
			goto out_err;
	}

	ret = tracing_wait_pipe(filp);
	if (ret <= 0)
		goto out_err;

	if (!iter->ent && !trace_find_next_entry_inc(iter)) {
		ret = -EFAULT;
		goto out_err;
	}

	trace_event_read_lock();
	trace_access_lock(iter->cpu_file);

	/* Fill as many pages as possible. */
	for (i = 0, rem = len; i < spd.nr_pages_max && rem; i++) {
		spd.pages[i] = alloc_page(GFP_KERNEL);
		if (!spd.pages[i])
			break;

		rem = tracing_fill_pipe_page(rem, iter);

		/* Copy the data into the page, so we can start over. */
		ret = trace_seq_to_buffer(&iter->seq,
					  page_address(spd.pages[i]),
					  trace_seq_used(&iter->seq));
		if (ret < 0) {
			__free_page(spd.pages[i]);
			break;
		}
		spd.partial[i].offset = 0;
		spd.partial[i].len = trace_seq_used(&iter->seq);

		trace_seq_init(&iter->seq);
	}

	trace_access_unlock(iter->cpu_file);
	trace_event_read_unlock();
	mutex_unlock(&iter->mutex);

	spd.nr_pages = i;

	if (i)
		ret = splice_to_pipe(pipe, &spd);
	else
		ret = 0;
out:
	splice_shrink_spd(&spd);
	return ret;

out_err:
	mutex_unlock(&iter->mutex);
	goto out;
}

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

unsigned long __read_mostly	tracing_thresh;

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;


tracing_buffers_read(struct file *filp, char __user *ubuf,
		     size_t count, loff_t *ppos)
{
	struct ftrace_buffer_info *info = filp->private_data;
	struct trace_iterator *iter = &info->iter;
	ssize_t ret = 0;
	ssize_t size;

	if (!count)
		return 0;

#ifdef CONFIG_TRACER_MAX_TRACE
	if (iter->snapshot && iter->tr->current_trace->use_max_tr)
		return -EBUSY;
#endif

	if (!info->spare) {
		info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer,
							  iter->cpu_file);
		if (IS_ERR(info->spare)) {
			ret = PTR_ERR(info->spare);
			info->spare = NULL;
		} else {
			info->spare_cpu = iter->cpu_file;
		}
	}
	if (!info->spare)
		return ret;

	/* Do we have previous read data to read? */
	if (info->read < PAGE_SIZE)
		goto read;

 again:
	trace_access_lock(iter->cpu_file);
	ret = ring_buffer_read_page(iter->trace_buffer->buffer,
				    &info->spare,
				    count,
				    iter->cpu_file, 0);
	trace_access_unlock(iter->cpu_file);

	if (ret < 0) {
		if (trace_empty(iter)) {
			if ((filp->f_flags & O_NONBLOCK))
				return -EAGAIN;

			ret = wait_on_pipe(iter, false);
			if (ret)
				return ret;

			goto again;
		}
		return 0;
	}

	info->read = 0;
 read:
	size = PAGE_SIZE - info->read;
	if (size > count)
		size = count;

	ret = copy_to_user(ubuf, info->spare + info->read, size);
	if (ret == size)
		return -EFAULT;

	size -= ret;

	*ppos += size;
	info->read += size;

	return size;
}

struct trace_iterator *tracepoint_print_iter;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static struct ring_buffer *temp_buffer;

static struct trace_export __rcu *ftrace_exports_list

#define FTRACE_STACK_MAX_ENTRIES (PAGE_SIZE / sizeof(unsigned long))

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};


trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_table)
{
	struct trace_array *tr = iter->tr;

	/* Iterators are static, they should be filled or empty */
	if (trace_buffer_iter(iter, iter->cpu_file))
		return POLLIN | POLLRDNORM;

	if (tr->trace_flags & TRACE_ITER_BLOCK)
		/*
		 * Always select as readable when in blocking mode
		 */
		return POLLIN | POLLRDNORM;
	else
		return ring_buffer_poll_wait(iter->trace_buffer->buffer, iter->cpu_file,
					     filp, poll_table);
}

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);


static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu)
{
	struct dentry *d_tracer;

	if (tr->percpu_dir)
		return tr->percpu_dir;

	d_tracer = tracing_get_dentry(tr);
	if (IS_ERR(d_tracer))
		return NULL;

	tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer);

	WARN_ONCE(!tr->percpu_dir,
		  "Could not create tracefs directory 'per_cpu/%d'\n", cpu);

	return tr->percpu_dir;
}

static bool __read_mostly

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

static DEFINE_MUTEX(trace_eval_mutex);

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;


void tracing_off(void)
{
	tracer_tracing_off(&global_trace);
}

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static 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);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static void
create_trace_option_files(struct trace_array *tr, struct tracer *tracer);

struct ftrace_buffer_info {
	struct trace_iterator	iter;
	void			*spare;
	unsigned int		spare_cpu;
	unsigned int		read;
}

struct buffer_ref {
	struct ring_buffer	*buffer;
	void			*page;
	int			cpu;
	int			ref;
}

static void
init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);


int unregister_ftrace_export(struct trace_export *export)
{
	int ret;

	mutex_lock(&ftrace_export_lock);

	ret = rm_ftrace_export(&ftrace_exports_list, export);

	mutex_unlock(&ftrace_export_lock);

	return ret;
}

struct trace_iterator *tracepoint_print_iter;

int tracepoint_printk;

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static int tracing_disabled = 1;

int __disable_trace_on_warning;

struct trace_eval_map_head {
	struct module			*mod;
	unsigned long			length;
}

struct trace_eval_map_tail {
	/*
	 * "end" is first and points to NULL as it must be different
	 * than "mod" or "eval_string"
	 */
	union trace_eval_map_item	*next;
	const char			*end;	/* points to NULL */
}

union trace_eval_map_item {
	struct trace_eval_map		map;
	struct trace_eval_map_head	head;
	struct trace_eval_map_tail	tail;
}

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static struct tracer		*trace_types

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

struct trace_selftests {
	struct list_head		list;
	struct tracer			*type;
}

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static int *tgid_map;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

struct ftrace_stack {
	unsigned long		calls[FTRACE_STACK_MAX_ENTRIES];
}

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;

static const struct seq_operations tracer_seq_ops = {
	.start		= s_start,
	.next		= s_next,
	.stop		= s_stop,
	.show		= s_show,
};

static const struct seq_operations show_traces_seq_ops = {
	.start		= t_start,
	.next		= t_next,
	.stop		= t_stop,
	.show		= t_show,
};


static __init int register_snapshot_cmd(void)
{
	return register_ftrace_command(&ftrace_snapshot_cmd);
}

static bool __read_mostly

int tracepoint_printk;

static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

static struct tracer_opt dummy_tracer_opt[] = {
	{ }
};

static DEFINE_PER_CPU(bool, trace_taskinfo_save);

static int tracing_disabled = 1;

int __disable_trace_on_warning;

static DEFINE_MUTEX(trace_eval_mutex);

static union trace_eval_map_item *trace_eval_maps;

static int tracing_set_tracer(struct trace_array *tr, const char *buf);

static char bootup_tracer_buf[MAX_TRACER_SIZE]

static char *default_bootup_tracer;

static bool allocate_snapshot;

static char trace_boot_options_buf[MAX_TRACER_SIZE]

static char trace_boot_clock_buf[MAX_TRACER_SIZE]

static char *trace_boot_clock

static struct trace_array global_trace = {
	.trace_flags = TRACE_DEFAULT_FLAGS,
};

static unsigned long		trace_buf_size = TRACE_BUF_SIZE_DEFAULT;

static struct tracer		*trace_types

static DECLARE_RWSEM(all_cpu_access_lock);

static DEFINE_PER_CPU(struct mutex, cpu_access_lock);

static DEFINE_MUTEX(access_lock);

static 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);

static __always_inline struct

static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id);

static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);

static const char *trace_options[] = {
	TRACE_FLAGS
	NULL
};

static struct {
	u64 (*func)(void);
	const char *name;
	int in_ns;		/* is this clock in nanoseconds? */
} trace_clocks[] = {
	{ trace_clock_local,		"local",	1 },
	{ trace_clock_global,		"global",	1 },
	{ trace_clock_counter,		"counter",	0 },
	{ trace_clock_jiffies,		"uptime",	0 },
	{ trace_clock,			"perf",		1 },
	{ ktime_get_mono_fast_ns,	"mono",		1 },
	{ ktime_get_raw_fast_ns,	"mono_raw",	1 },
	{ ktime_get_boot_fast_ns,	"boot",		1 },
	ARCH_TRACE_CLOCKS
};

static bool selftests_can_run;

static LIST_HEAD(postponed_selftests);

static void add_tracer_options(struct trace_array *tr, struct tracer *t);

static void __init apply_trace_boot_options(void);

static int *tgid_map;

static arch_spinlock_t trace_cmdline_lock = __ARCH_SPIN_LOCK_UNLOCKED;

struct saved_cmdlines_buffer {
	unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1];
	unsigned *map_cmdline_to_pid;
	unsigned cmdline_num;
	int cmdline_idx;
	char *saved_cmdlines;
}

static struct saved_cmdlines_buffer *savedcmd;

static atomic_t trace_record_taskinfo_disabled

static int trace_buffered_event_ref;

static struct ring_buffer *temp_buffer;

static DEFINE_SPINLOCK(tracepoint_iter_lock);

static DEFINE_MUTEX(tracepoint_printk_mutex);

static DEFINE_MUTEX(ftrace_export_lock);

static struct trace_export __rcu *ftrace_exports_list

static DEFINE_STATIC_KEY_FALSE(ftrace_exports_enabled);

static DEFINE_PER_CPU(struct ftrace_stack, ftrace_stack);

static DEFINE_PER_CPU(int, ftrace_stack_reserve);

static DEFINE_PER_CPU(int, user_stack_count);

struct trace_buffer_struct {
	int nesting;
	char buffer[4][TRACE_BUF_SIZE];
}

static struct trace_buffer_struct *trace_percpu_buffer;

static int buffers_allocated;


static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
					struct trace_buffer *size_buf, int cpu_id)
{
	int cpu, ret = 0;

	if (cpu_id == RING_BUFFER_ALL_CPUS) {
		for_each_tracing_cpu(cpu) {
			ret = ring_buffer_resize(trace_buf->buffer,
				 per_cpu_ptr(size_buf->data, cpu)->entries, cpu);
			if (ret < 0)
				break;
			per_cpu_ptr(trace_buf->data, cpu)->entries =
				per_cpu_ptr(size_buf->data, cpu)->entries;
		}
	} else {
		ret = ring_buffer_resize(trace_buf->buffer,
				 per_cpu_ptr(size_buf->data, cpu_id)->entries, cpu_id);
		if (ret == 0)
			per_cpu_ptr(trace_buf->data, cpu_id)->entries =
				per_cpu_ptr(size_buf->data, cpu_id)->entries;
	}

	return ret;
}