linux/kernel/trace/trace_events.c

// SPDX-License-Identifier: GPL-2.0
/*
 * event tracer
 *
 * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <[email protected]>
 *
 *  - Added format output of fields of the trace point.
 *    This was based off of work by Tom Zanussi <[email protected]>.
 *
 */

#define pr_fmt(fmt)

#include <linux/workqueue.h>
#include <linux/security.h>
#include <linux/spinlock.h>
#include <linux/kthread.h>
#include <linux/tracefs.h>
#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/sort.h>
#include <linux/slab.h>
#include <linux/delay.h>

#include <trace/events/sched.h>
#include <trace/syscall.h>

#include <asm/setup.h>

#include "trace_output.h"

#undef TRACE_SYSTEM
#define TRACE_SYSTEM

DEFINE_MUTEX();

LIST_HEAD();
static LIST_HEAD(ftrace_generic_fields);
static LIST_HEAD(ftrace_common_fields);
static bool eventdir_initialized;

static LIST_HEAD(module_strings);

struct module_string {};

#define GFP_TRACE

static struct kmem_cache *field_cachep;
static struct kmem_cache *file_cachep;

static inline int system_refcount(struct event_subsystem *system)
{}

static int system_refcount_inc(struct event_subsystem *system)
{}

static int system_refcount_dec(struct event_subsystem *system)
{}

/* Double loops, do not use break, only goto's work */
#define do_for_each_event_file(tr, file)

#define do_for_each_event_file_safe(tr, file)

#define while_for_each_event_file()

static struct ftrace_event_field *
__find_event_field(struct list_head *head, char *name)
{}

struct ftrace_event_field *
trace_find_event_field(struct trace_event_call *call, char *name)
{}

static int __trace_define_field(struct list_head *head, const char *type,
				const char *name, int offset, int size,
				int is_signed, int filter_type, int len)
{}

int trace_define_field(struct trace_event_call *call, const char *type,
		       const char *name, int offset, int size, int is_signed,
		       int filter_type)
{}
EXPORT_SYMBOL_GPL();

static int trace_define_field_ext(struct trace_event_call *call, const char *type,
		       const char *name, int offset, int size, int is_signed,
		       int filter_type, int len)
{}

#define __generic_field(type, item, filter_type)

#define __common_field(type, item)

static int trace_define_generic_fields(void)
{}

static int trace_define_common_fields(void)
{}

static void trace_destroy_fields(struct trace_event_call *call)
{}

/*
 * run-time version of trace_event_get_offsets_<call>() that returns the last
 * accessible offset of trace fields excluding __dynamic_array bytes
 */
int trace_event_get_offsets(struct trace_event_call *call)
{}

/*
 * Check if the referenced field is an array and return true,
 * as arrays are OK to dereference.
 */
static bool test_field(const char *fmt, struct trace_event_call *call)
{}

/*
 * Examine the print fmt of the event looking for unsafe dereference
 * pointers using %p* that could be recorded in the trace event and
 * much later referenced after the pointer was freed. Dereferencing
 * pointers are OK, if it is dereferenced into the event itself.
 */
static void test_event_printk(struct trace_event_call *call)
{}

int trace_event_raw_init(struct trace_event_call *call)
{}
EXPORT_SYMBOL_GPL();

bool trace_event_ignore_this_pid(struct trace_event_file *trace_file)
{}
EXPORT_SYMBOL_GPL();

void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
				 struct trace_event_file *trace_file,
				 unsigned long len)
{}
EXPORT_SYMBOL_GPL();

int trace_event_reg(struct trace_event_call *call,
		    enum trace_reg type, void *data)
{}
EXPORT_SYMBOL_GPL();

void trace_event_enable_cmd_record(bool enable)
{}

void trace_event_enable_tgid_record(bool enable)
{}

static int __ftrace_event_enable_disable(struct trace_event_file *file,
					 int enable, int soft_disable)
{}

int trace_event_enable_disable(struct trace_event_file *file,
			       int enable, int soft_disable)
{}

static int ftrace_event_enable_disable(struct trace_event_file *file,
				       int enable)
{}

static void ftrace_clear_events(struct trace_array *tr)
{}

static void
event_filter_pid_sched_process_exit(void *data, struct task_struct *task)
{}

static void
event_filter_pid_sched_process_fork(void *data,
				    struct task_struct *self,
				    struct task_struct *task)
{}

void trace_event_follow_fork(struct trace_array *tr, bool enable)
{}

static void
event_filter_pid_sched_switch_probe_pre(void *data, bool preempt,
					struct task_struct *prev,
					struct task_struct *next,
					unsigned int prev_state)
{}

static void
event_filter_pid_sched_switch_probe_post(void *data, bool preempt,
					 struct task_struct *prev,
					 struct task_struct *next,
					 unsigned int prev_state)
{}

static void
event_filter_pid_sched_wakeup_probe_pre(void *data, struct task_struct *task)
{}

static void
event_filter_pid_sched_wakeup_probe_post(void *data, struct task_struct *task)
{}

static void unregister_pid_events(struct trace_array *tr)
{}

static void __ftrace_clear_event_pids(struct trace_array *tr, int type)
{}

static void ftrace_clear_event_pids(struct trace_array *tr, int type)
{}

static void __put_system(struct event_subsystem *system)
{}

static void __get_system(struct event_subsystem *system)
{}

static void __get_system_dir(struct trace_subsystem_dir *dir)
{}

static void __put_system_dir(struct trace_subsystem_dir *dir)
{}

static void put_system(struct trace_subsystem_dir *dir)
{}

static void remove_subsystem(struct trace_subsystem_dir *dir)
{}

void event_file_get(struct trace_event_file *file)
{}

void event_file_put(struct trace_event_file *file)
{}

static void remove_event_file_dir(struct trace_event_file *file)
{}

/*
 * __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
 */
static int
__ftrace_set_clr_event_nolock(struct trace_array *tr, const char *match,
			      const char *sub, const char *event, int set)
{}

static int __ftrace_set_clr_event(struct trace_array *tr, const char *match,
				  const char *sub, const char *event, int set)
{}

int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
{}

/**
 * trace_set_clr_event - enable or disable an event
 * @system: system name to match (NULL for any system)
 * @event: event name to match (NULL for all events, within system)
 * @set: 1 to enable, 0 to disable
 *
 * This is a way for other parts of the kernel to enable or disable
 * event recording.
 *
 * Returns 0 on success, -EINVAL if the parameters do not match any
 * registered events.
 */
int trace_set_clr_event(const char *system, const char *event, int set)
{}
EXPORT_SYMBOL_GPL();

/**
 * trace_array_set_clr_event - enable or disable an event for a trace array.
 * @tr: concerned trace array.
 * @system: system name to match (NULL for any system)
 * @event: event name to match (NULL for all events, within system)
 * @enable: true to enable, false to disable
 *
 * This is a way for other parts of the kernel to enable or disable
 * event recording.
 *
 * Returns 0 on success, -EINVAL if the parameters do not match any
 * registered events.
 */
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
		const char *event, bool enable)
{}
EXPORT_SYMBOL_GPL();

/* 128 should be much more than enough */
#define EVENT_BUF_SIZE

static ssize_t
ftrace_event_write(struct file *file, const char __user *ubuf,
		   size_t cnt, loff_t *ppos)
{}

static void *
t_next(struct seq_file *m, void *v, loff_t *pos)
{}

static void *t_start(struct seq_file *m, loff_t *pos)
{}

static void *
s_next(struct seq_file *m, void *v, loff_t *pos)
{}

static void *s_start(struct seq_file *m, loff_t *pos)
{}

static int t_show(struct seq_file *m, void *v)
{}

static void t_stop(struct seq_file *m, void *p)
{}

static void *
__next(struct seq_file *m, void *v, loff_t *pos, int type)
{}

static void *
p_next(struct seq_file *m, void *v, loff_t *pos)
{}

static void *
np_next(struct seq_file *m, void *v, loff_t *pos)
{}

static void *__start(struct seq_file *m, loff_t *pos, int type)
	__acquires(RCU)
{}

static void *p_start(struct seq_file *m, loff_t *pos)
	__acquires(RCU)
{}

static void *np_start(struct seq_file *m, loff_t *pos)
	__acquires(RCU)
{}

static void p_stop(struct seq_file *m, void *p)
	__releases(RCU)
{}

static ssize_t
event_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
		  loff_t *ppos)
{}

static ssize_t
event_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
		   loff_t *ppos)
{}

static ssize_t
system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
		   loff_t *ppos)
{}

static ssize_t
system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
		    loff_t *ppos)
{}

enum {};

static void *f_next(struct seq_file *m, void *v, loff_t *pos)
{}

static int f_show(struct seq_file *m, void *v)
{}

static void *f_start(struct seq_file *m, loff_t *pos)
{}

static void f_stop(struct seq_file *m, void *p)
{}

static const struct seq_operations trace_format_seq_ops =;

static int trace_format_open(struct inode *inode, struct file *file)
{}

#ifdef CONFIG_PERF_EVENTS
static ssize_t
event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{}
#endif

static ssize_t
event_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
		  loff_t *ppos)
{}

static ssize_t
event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
		   loff_t *ppos)
{}

static LIST_HEAD(event_subsystems);

static int subsystem_open(struct inode *inode, struct file *filp)
{}

static int system_tr_open(struct inode *inode, struct file *filp)
{}

static int subsystem_release(struct inode *inode, struct file *file)
{}

static ssize_t
subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
		      loff_t *ppos)
{}

static ssize_t
subsystem_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
		       loff_t *ppos)
{}

static ssize_t
show_header_page_file(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{}

static ssize_t
show_header_event_file(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{}

static void ignore_task_cpu(void *data)
{}

static void register_pid_events(struct trace_array *tr)
{}

static ssize_t
event_pid_write(struct file *filp, const char __user *ubuf,
		size_t cnt, loff_t *ppos, int type)
{}

static ssize_t
ftrace_event_pid_write(struct file *filp, const char __user *ubuf,
		       size_t cnt, loff_t *ppos)
{}

static ssize_t
ftrace_event_npid_write(struct file *filp, const char __user *ubuf,
			size_t cnt, loff_t *ppos)
{}

static int ftrace_event_avail_open(struct inode *inode, struct file *file);
static int ftrace_event_set_open(struct inode *inode, struct file *file);
static int ftrace_event_set_pid_open(struct inode *inode, struct file *file);
static int ftrace_event_set_npid_open(struct inode *inode, struct file *file);
static int ftrace_event_release(struct inode *inode, struct file *file);

static const struct seq_operations show_event_seq_ops =;

static const struct seq_operations show_set_event_seq_ops =;

static const struct seq_operations show_set_pid_seq_ops =;

static const struct seq_operations show_set_no_pid_seq_ops =;

static const struct file_operations ftrace_avail_fops =;

static const struct file_operations ftrace_set_event_fops =;

static const struct file_operations ftrace_set_event_pid_fops =;

static const struct file_operations ftrace_set_event_notrace_pid_fops =;

static const struct file_operations ftrace_enable_fops =;

static const struct file_operations ftrace_event_format_fops =;

#ifdef CONFIG_PERF_EVENTS
static const struct file_operations ftrace_event_id_fops =;
#endif

static const struct file_operations ftrace_event_filter_fops =;

static const struct file_operations ftrace_subsystem_filter_fops =;

static const struct file_operations ftrace_system_enable_fops =;

static const struct file_operations ftrace_tr_enable_fops =;

static const struct file_operations ftrace_show_header_page_fops =;

static const struct file_operations ftrace_show_header_event_fops =;

static int
ftrace_event_open(struct inode *inode, struct file *file,
		  const struct seq_operations *seq_ops)
{}

static int ftrace_event_release(struct inode *inode, struct file *file)
{}

static int
ftrace_event_avail_open(struct inode *inode, struct file *file)
{}

static int
ftrace_event_set_open(struct inode *inode, struct file *file)
{}

static int
ftrace_event_set_pid_open(struct inode *inode, struct file *file)
{}

static int
ftrace_event_set_npid_open(struct inode *inode, struct file *file)
{}

static struct event_subsystem *
create_new_subsystem(const char *name)
{}

static int system_callback(const char *name, umode_t *mode, void **data,
		    const struct file_operations **fops)
{}

static struct eventfs_inode *
event_subsystem_dir(struct trace_array *tr, const char *name,
		    struct trace_event_file *file, struct eventfs_inode *parent)
{}

static int
event_define_fields(struct trace_event_call *call)
{}

static int event_callback(const char *name, umode_t *mode, void **data,
			  const struct file_operations **fops)
{}

/* The file is incremented on creation and freeing the enable file decrements it */
static void event_release(const char *name, void *data)
{}

static int
event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file)
{}

static void remove_event_from_tracers(struct trace_event_call *call)
{}

static void event_remove(struct trace_event_call *call)
{}

static int event_init(struct trace_event_call *call)
{}

static int
__register_event(struct trace_event_call *call, struct module *mod)
{}

static char *eval_replace(char *ptr, struct trace_eval_map *map, int len)
{}

static void update_event_printk(struct trace_event_call *call,
				struct trace_eval_map *map)
{}

static void add_str_to_module(struct module *module, char *str)
{}

static void update_event_fields(struct trace_event_call *call,
				struct trace_eval_map *map)
{}

void trace_event_eval_update(struct trace_eval_map **map, int len)
{}

static bool event_in_systems(struct trace_event_call *call,
			     const char *systems)
{}

static struct trace_event_file *
trace_create_new_event(struct trace_event_call *call,
		       struct trace_array *tr)
{}

#define MAX_BOOT_TRIGGERS

static struct boot_triggers {} bootup_triggers[MAX_BOOT_TRIGGERS];

static char bootup_trigger_buf[COMMAND_LINE_SIZE];
static int nr_boot_triggers;

static __init int setup_trace_triggers(char *str)
{}
__setup();

/* Add an event to a trace directory */
static int
__trace_add_new_event(struct trace_event_call *call, struct trace_array *tr)
{}

static void trace_early_triggers(struct trace_event_file *file, const char *name)
{}

/*
 * Just create a descriptor for early init. A descriptor is required
 * for enabling events at boot. We want to enable events before
 * the filesystem is initialized.
 */
static int
__trace_early_add_new_event(struct trace_event_call *call,
			    struct trace_array *tr)
{}

struct ftrace_module_file_ops;
static void __add_event_to_tracers(struct trace_event_call *call);

/* Add an additional event_call dynamically */
int trace_add_event_call(struct trace_event_call *call)
{}
EXPORT_SYMBOL_GPL();

/*
 * Must be called under locking of trace_types_lock, event_mutex and
 * trace_event_sem.
 */
static void __trace_remove_event_call(struct trace_event_call *call)
{}

static int probe_remove_event_call(struct trace_event_call *call)
{}

/* Remove an event_call */
int trace_remove_event_call(struct trace_event_call *call)
{}
EXPORT_SYMBOL_GPL();

#define for_each_event(event, start, end)

#ifdef CONFIG_MODULES

static void trace_module_add_events(struct module *mod)
{}

static void trace_module_remove_events(struct module *mod)
{}

static int trace_module_notify(struct notifier_block *self,
			       unsigned long val, void *data)
{}

static struct notifier_block trace_module_nb =;
#endif /* CONFIG_MODULES */

/* Create a new event directory structure for a trace directory. */
static void
__trace_add_event_dirs(struct trace_array *tr)
{}

/* Returns any file that matches the system and event */
struct trace_event_file *
__find_event_file(struct trace_array *tr, const char *system, const char *event)
{}

/* Returns valid trace event files that match system and event */
struct trace_event_file *
find_event_file(struct trace_array *tr, const char *system, const char *event)
{}

/**
 * trace_get_event_file - Find and return a trace event file
 * @instance: The name of the trace instance containing the event
 * @system: The name of the system containing the event
 * @event: The name of the event
 *
 * Return a trace event file given the trace instance name, trace
 * system, and trace event name.  If the instance name is NULL, it
 * refers to the top-level trace array.
 *
 * This function will look it up and return it if found, after calling
 * trace_array_get() to prevent the instance from going away, and
 * increment the event's module refcount to prevent it from being
 * removed.
 *
 * To release the file, call trace_put_event_file(), which will call
 * trace_array_put() and decrement the event's module refcount.
 *
 * Return: The trace event on success, ERR_PTR otherwise.
 */
struct trace_event_file *trace_get_event_file(const char *instance,
					      const char *system,
					      const char *event)
{}
EXPORT_SYMBOL_GPL();

/**
 * trace_put_event_file - Release a file from trace_get_event_file()
 * @file: The trace event file
 *
 * If a file was retrieved using trace_get_event_file(), this should
 * be called when it's no longer needed.  It will cancel the previous
 * trace_array_get() called by that function, and decrement the
 * event's module refcount.
 */
void trace_put_event_file(struct trace_event_file *file)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_DYNAMIC_FTRACE

/* Avoid typos */
#define ENABLE_EVENT_STR
#define DISABLE_EVENT_STR

struct event_probe_data {};

static void update_event_probe(struct event_probe_data *data)
{}

static void
event_enable_probe(unsigned long ip, unsigned long parent_ip,
		   struct trace_array *tr, struct ftrace_probe_ops *ops,
		   void *data)
{}

static void
event_enable_count_probe(unsigned long ip, unsigned long parent_ip,
			 struct trace_array *tr, struct ftrace_probe_ops *ops,
			 void *data)
{}

static int
event_enable_print(struct seq_file *m, unsigned long ip,
		   struct ftrace_probe_ops *ops, void *data)
{}

static int
event_enable_init(struct ftrace_probe_ops *ops, struct trace_array *tr,
		  unsigned long ip, void *init_data, void **data)
{}

static int free_probe_data(void *data)
{}

static void
event_enable_free(struct ftrace_probe_ops *ops, struct trace_array *tr,
		  unsigned long ip, void *data)
{}

static struct ftrace_probe_ops event_enable_probe_ops =;

static struct ftrace_probe_ops event_enable_count_probe_ops =;

static struct ftrace_probe_ops event_disable_probe_ops =;

static struct ftrace_probe_ops event_disable_count_probe_ops =;

static int
event_enable_func(struct trace_array *tr, struct ftrace_hash *hash,
		  char *glob, char *cmd, char *param, int enabled)
{}

static struct ftrace_func_command event_enable_cmd =;

static struct ftrace_func_command event_disable_cmd =;

static __init int register_event_cmds(void)
{}
#else
static inline int register_event_cmds(void) { return 0; }
#endif /* CONFIG_DYNAMIC_FTRACE */

/*
 * The top level array and trace arrays created by boot-time tracing
 * have already had its trace_event_file descriptors created in order
 * to allow for early events to be recorded.
 * This function is called after the tracefs has been initialized,
 * and we now have to create the files associated to the events.
 */
static void __trace_early_add_event_dirs(struct trace_array *tr)
{}

/*
 * For early boot up, the top trace array and the trace arrays created
 * by boot-time tracing require to have a list of events that can be
 * enabled. This must be done before the filesystem is set up in order
 * to allow events to be traced early.
 */
void __trace_early_add_events(struct trace_array *tr)
{}

/* Remove the event directory structure for a trace directory. */
static void
__trace_remove_event_dirs(struct trace_array *tr)
{}

static void __add_event_to_tracers(struct trace_event_call *call)
{}

extern struct trace_event_call *__start_ftrace_events[];
extern struct trace_event_call *__stop_ftrace_events[];

static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata;

static __init int setup_trace_event(char *str)
{}
__setup();

static int events_callback(const char *name, umode_t *mode, void **data,
			   const struct file_operations **fops)
{}

/* Expects to have event_mutex held when called */
static int
create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
{}

/**
 * event_trace_add_tracer - add a instance of a trace_array to events
 * @parent: The parent dentry to place the files/directories for events in
 * @tr: The trace array associated with these events
 *
 * When a new instance is created, it needs to set up its events
 * directory, as well as other files associated with events. It also
 * creates the event hierarchy in the @parent/events directory.
 *
 * Returns 0 on success.
 *
 * Must be called with event_mutex held.
 */
int event_trace_add_tracer(struct dentry *parent, struct trace_array *tr)
{}

/*
 * The top trace array already had its file descriptors created.
 * Now the files themselves need to be created.
 */
static __init int
early_event_add_tracer(struct dentry *parent, struct trace_array *tr)
{}

/* Must be called with event_mutex held */
int event_trace_del_tracer(struct trace_array *tr)
{}

static __init int event_trace_memsetup(void)
{}

__init void
early_enable_events(struct trace_array *tr, char *buf, bool disable_first)
{}

static __init int event_trace_enable(void)
{}

/*
 * event_trace_enable() is called from trace_event_init() first to
 * initialize events and perhaps start any events that are on the
 * command line. Unfortunately, there are some events that will not
 * start this early, like the system call tracepoints that need
 * to set the %SYSCALL_WORK_SYSCALL_TRACEPOINT flag of pid 1. But
 * event_trace_enable() is called before pid 1 starts, and this flag
 * is never set, making the syscall tracepoint never get reached, but
 * the event is enabled regardless (and not doing anything).
 */
static __init int event_trace_enable_again(void)
{}

early_initcall(event_trace_enable_again);

/* Init fields which doesn't related to the tracefs */
static __init int event_trace_init_fields(void)
{}

__init int event_trace_init(void)
{}

void __init trace_event_init(void)
{}

#ifdef CONFIG_EVENT_TRACE_STARTUP_TEST

static DEFINE_SPINLOCK(test_spinlock);
static DEFINE_SPINLOCK(test_spinlock_irq);
static DEFINE_MUTEX(test_mutex);

static __init void test_work(struct work_struct *dummy)
{}

static __init int event_test_thread(void *unused)
{}

/*
 * Do various things that may trigger events.
 */
static __init void event_test_stuff(void)
{}

/*
 * For every trace event defined, we will test each trace point separately,
 * and then by groups, and finally all trace points.
 */
static __init void event_trace_self_tests(void)
{}

#ifdef CONFIG_FUNCTION_TRACER

static DEFINE_PER_CPU(atomic_t, ftrace_test_event_disable);

static struct trace_event_file event_trace_file __initdata;

static void __init
function_test_events_call(unsigned long ip, unsigned long parent_ip,
			  struct ftrace_ops *op, struct ftrace_regs *regs)
{}

static struct ftrace_ops trace_ops __initdata  =;

static __init void event_trace_self_test_with_function(void)
{}
#else
static __init void event_trace_self_test_with_function(void)
{
}
#endif

static __init int event_trace_self_tests_init(void)
{}

late_initcall(event_trace_self_tests_init);

#endif