Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac07bcaa authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'tip/tracing/ftrace' of...

Merge branch 'tip/tracing/ftrace' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into tracing/ftrace
parents 37bd824a 35ebf1ca
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -108,7 +108,7 @@ struct ftrace_func_command {

struct seq_file;

struct ftrace_hook_ops {
struct ftrace_probe_ops {
	void			(*func)(unsigned long ip,
					unsigned long parent_ip,
					void **data);
@@ -116,19 +116,19 @@ struct ftrace_hook_ops {
	void			(*free)(void **data);
	int			(*print)(struct seq_file *m,
					 unsigned long ip,
					 struct ftrace_hook_ops *ops,
					 struct ftrace_probe_ops *ops,
					 void *data);
};

extern int
register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
			      void *data);
extern void
unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
				void *data);
extern void
unregister_ftrace_function_hook_func(char *glob, struct ftrace_hook_ops *ops);
extern void unregister_ftrace_function_hook_all(char *glob);
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
extern void unregister_ftrace_function_probe_all(char *glob);

enum {
	FTRACE_FL_FREE		= (1 << 0),
+52 −50
Original line number Diff line number Diff line
@@ -255,9 +255,9 @@ static struct pid * const ftrace_swapper_pid = &init_struct_pid;

static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;

struct ftrace_func_hook {
struct ftrace_func_probe {
	struct hlist_node	node;
	struct ftrace_hook_ops	*ops;
	struct ftrace_probe_ops	*ops;
	unsigned long		flags;
	unsigned long		ip;
	void			*data;
@@ -460,8 +460,8 @@ static void ftrace_bug(int failed, unsigned long ip)
static int
__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
{
	unsigned long ip, fl;
	unsigned long ftrace_addr;
	unsigned long ip, fl;

	ftrace_addr = (unsigned long)FTRACE_ADDR;

@@ -530,9 +530,9 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable)

static void ftrace_replace_code(int enable)
{
	int failed;
	struct dyn_ftrace *rec;
	struct ftrace_page *pg;
	int failed;

	do_for_each_ftrace_rec(pg, rec) {
		/*
@@ -830,11 +830,11 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos)

static int t_hash_show(struct seq_file *m, void *v)
{
	struct ftrace_func_hook *rec;
	struct ftrace_func_probe *rec;
	struct hlist_node *hnd = v;
	char str[KSYM_SYMBOL_LEN];

	rec = hlist_entry(hnd, struct ftrace_func_hook, node);
	rec = hlist_entry(hnd, struct ftrace_func_probe, node);

	if (rec->ops->print)
		return rec->ops->print(m, rec->ip, rec->ops, rec->data);
@@ -1208,14 +1208,15 @@ ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)

static void ftrace_match_records(char *buff, int len, int enable)
{
	char *search;
	unsigned int search_len;
	struct ftrace_page *pg;
	struct dyn_ftrace *rec;
	unsigned long flag;
	char *search;
	int type;
	unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
	unsigned search_len;
	int not;

	flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
	type = ftrace_setup_glob(buff, len, &search, &not);

	search_len = strlen(search);
@@ -1263,14 +1264,16 @@ ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,

static void ftrace_match_module_records(char *buff, char *mod, int enable)
{
	char *search = buff;
	unsigned search_len = 0;
	struct ftrace_page *pg;
	struct dyn_ftrace *rec;
	int type = MATCH_FULL;
	unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
	unsigned search_len = 0;
	char *search = buff;
	unsigned long flag;
	int not = 0;

	flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;

	/* blank or '*' mean the same */
	if (strcmp(buff, "*") == 0)
		buff[0] = 0;
@@ -1348,9 +1351,9 @@ static int __init ftrace_mod_cmd_init(void)
device_initcall(ftrace_mod_cmd_init);

static void
function_trace_hook_call(unsigned long ip, unsigned long parent_ip)
function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
{
	struct ftrace_func_hook *entry;
	struct ftrace_func_probe *entry;
	struct hlist_head *hhd;
	struct hlist_node *n;
	unsigned long key;
@@ -1376,18 +1379,18 @@ function_trace_hook_call(unsigned long ip, unsigned long parent_ip)
	ftrace_preempt_enable(resched);
}

static struct ftrace_ops trace_hook_ops __read_mostly =
static struct ftrace_ops trace_probe_ops __read_mostly =
{
	.func = function_trace_hook_call,
	.func = function_trace_probe_call,
};

static int ftrace_hook_registered;
static int ftrace_probe_registered;

static void __enable_ftrace_function_hook(void)
static void __enable_ftrace_function_probe(void)
{
	int i;

	if (ftrace_hook_registered)
	if (ftrace_probe_registered)
		return;

	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
@@ -1399,16 +1402,16 @@ static void __enable_ftrace_function_hook(void)
	if (i == FTRACE_FUNC_HASHSIZE)
		return;

	__register_ftrace_function(&trace_hook_ops);
	__register_ftrace_function(&trace_probe_ops);
	ftrace_startup(0);
	ftrace_hook_registered = 1;
	ftrace_probe_registered = 1;
}

static void __disable_ftrace_function_hook(void)
static void __disable_ftrace_function_probe(void)
{
	int i;

	if (!ftrace_hook_registered)
	if (!ftrace_probe_registered)
		return;

	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
@@ -1418,16 +1421,16 @@ static void __disable_ftrace_function_hook(void)
	}

	/* no more funcs left */
	__unregister_ftrace_function(&trace_hook_ops);
	__unregister_ftrace_function(&trace_probe_ops);
	ftrace_shutdown(0);
	ftrace_hook_registered = 0;
	ftrace_probe_registered = 0;
}


static void ftrace_free_entry_rcu(struct rcu_head *rhp)
{
	struct ftrace_func_hook *entry =
		container_of(rhp, struct ftrace_func_hook, rcu);
	struct ftrace_func_probe *entry =
		container_of(rhp, struct ftrace_func_probe, rcu);

	if (entry->ops->free)
		entry->ops->free(&entry->data);
@@ -1436,21 +1439,21 @@ static void ftrace_free_entry_rcu(struct rcu_head *rhp)


int
register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
			      void *data)
{
	struct ftrace_func_hook *entry;
	struct ftrace_func_probe *entry;
	struct ftrace_page *pg;
	struct dyn_ftrace *rec;
	unsigned long key;
	int type, len, not;
	unsigned long key;
	int count = 0;
	char *search;

	type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
	len = strlen(search);

	/* we do not support '!' for function hooks */
	/* we do not support '!' for function probes */
	if (WARN_ON(not))
		return -EINVAL;

@@ -1465,7 +1468,7 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,

		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
		if (!entry) {
			/* If we did not hook to any, then return error */
			/* If we did not process any, then return error */
			if (!count)
				count = -ENOMEM;
			goto out_unlock;
@@ -1495,7 +1498,7 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
		hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);

	} while_for_each_ftrace_rec();
	__enable_ftrace_function_hook();
	__enable_ftrace_function_probe();

 out_unlock:
	mutex_unlock(&ftrace_lock);
@@ -1504,15 +1507,15 @@ register_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
}

enum {
	HOOK_TEST_FUNC		= 1,
	HOOK_TEST_DATA		= 2
	PROBE_TEST_FUNC		= 1,
	PROBE_TEST_DATA		= 2
};

static void
__unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
				  void *data, int flags)
{
	struct ftrace_func_hook *entry;
	struct ftrace_func_probe *entry;
	struct hlist_node *n, *tmp;
	char str[KSYM_SYMBOL_LEN];
	int type = MATCH_FULL;
@@ -1527,7 +1530,7 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
		type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
		len = strlen(search);

		/* we do not support '!' for function hooks */
		/* we do not support '!' for function probes */
		if (WARN_ON(not))
			return;
	}
@@ -1539,10 +1542,10 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
		hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {

			/* break up if statements for readability */
			if ((flags & HOOK_TEST_FUNC) && entry->ops != ops)
			if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
				continue;

			if ((flags & HOOK_TEST_DATA) && entry->data != data)
			if ((flags & PROBE_TEST_DATA) && entry->data != data)
				continue;

			/* do this last, since it is the most expensive */
@@ -1557,27 +1560,27 @@ __unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
			call_rcu(&entry->rcu, ftrace_free_entry_rcu);
		}
	}
	__disable_ftrace_function_hook();
	__disable_ftrace_function_probe();
	mutex_unlock(&ftrace_lock);
}

void
unregister_ftrace_function_hook(char *glob, struct ftrace_hook_ops *ops,
unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
				void *data)
{
	__unregister_ftrace_function_hook(glob, ops, data,
					  HOOK_TEST_FUNC | HOOK_TEST_DATA);
	__unregister_ftrace_function_probe(glob, ops, data,
					  PROBE_TEST_FUNC | PROBE_TEST_DATA);
}

void
unregister_ftrace_function_hook_func(char *glob, struct ftrace_hook_ops *ops)
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
{
	__unregister_ftrace_function_hook(glob, ops, NULL, HOOK_TEST_FUNC);
	__unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
}

void unregister_ftrace_function_hook_all(char *glob)
void unregister_ftrace_function_probe_all(char *glob)
{
	__unregister_ftrace_function_hook(glob, NULL, NULL, 0);
	__unregister_ftrace_function_probe(glob, NULL, NULL, 0);
}

static LIST_HEAD(ftrace_commands);
@@ -1623,8 +1626,8 @@ int unregister_ftrace_command(struct ftrace_func_command *cmd)

static int ftrace_process_regex(char *buff, int len, int enable)
{
	struct ftrace_func_command *p;
	char *func, *command, *next = buff;
	struct ftrace_func_command *p;
	int ret = -EINVAL;

	func = strsep(&next, ":");
@@ -2392,7 +2395,6 @@ static __init int ftrace_init_debugfs(void)
			   "'set_ftrace_pid' entry\n");
	return 0;
}

fs_initcall(ftrace_init_debugfs);

/**
+1 −1
Original line number Diff line number Diff line
@@ -336,7 +336,7 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
	data->rt_priority = tsk->rt_priority;

	/* record this tasks comm */
	tracing_record_cmdline(current);
	tracing_record_cmdline(tsk);
}

static void
+16 −15
Original line number Diff line number Diff line
@@ -269,21 +269,21 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip, void **data)

static int
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
			 struct ftrace_hook_ops *ops, void *data);
			 struct ftrace_probe_ops *ops, void *data);

static struct ftrace_hook_ops traceon_hook_ops = {
static struct ftrace_probe_ops traceon_probe_ops = {
	.func			= ftrace_traceon,
	.print			= ftrace_trace_onoff_print,
};

static struct ftrace_hook_ops traceoff_hook_ops = {
static struct ftrace_probe_ops traceoff_probe_ops = {
	.func			= ftrace_traceoff,
	.print			= ftrace_trace_onoff_print,
};

static int
ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
			 struct ftrace_hook_ops *ops, void *data)
			 struct ftrace_probe_ops *ops, void *data)
{
	char str[KSYM_SYMBOL_LEN];
	long count = (long)data;
@@ -291,12 +291,14 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
	kallsyms_lookup(ip, NULL, NULL, NULL, str);
	seq_printf(m, "%s:", str);

	if (ops == &traceon_hook_ops)
	if (ops == &traceon_probe_ops)
		seq_printf(m, "traceon");
	else
		seq_printf(m, "traceoff");

	if (count != -1)
	if (count == -1)
		seq_printf(m, ":unlimited\n");
	else
		seq_printf(m, ":count=%ld", count);
	seq_putc(m, '\n');

@@ -306,15 +308,15 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip,
static int
ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
{
	struct ftrace_hook_ops *ops;
	struct ftrace_probe_ops *ops;

	/* we register both traceon and traceoff to this callback */
	if (strcmp(cmd, "traceon") == 0)
		ops = &traceon_hook_ops;
		ops = &traceon_probe_ops;
	else
		ops = &traceoff_hook_ops;
		ops = &traceoff_probe_ops;

	unregister_ftrace_function_hook_func(glob, ops);
	unregister_ftrace_function_probe_func(glob, ops);

	return 0;
}
@@ -322,7 +324,7 @@ ftrace_trace_onoff_unreg(char *glob, char *cmd, char *param)
static int
ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
{
	struct ftrace_hook_ops *ops;
	struct ftrace_probe_ops *ops;
	void *count = (void *)-1;
	char *number;
	int ret;
@@ -336,9 +338,9 @@ ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)

	/* we register both traceon and traceoff to this callback */
	if (strcmp(cmd, "traceon") == 0)
		ops = &traceon_hook_ops;
		ops = &traceon_probe_ops;
	else
		ops = &traceoff_hook_ops;
		ops = &traceoff_probe_ops;

	if (!param)
		goto out_reg;
@@ -357,7 +359,7 @@ ftrace_trace_onoff_callback(char *glob, char *cmd, char *param, int enable)
		return ret;

 out_reg:
	ret = register_ftrace_function_hook(glob, ops, count);
	ret = register_ftrace_function_probe(glob, ops, count);

	return ret;
}
@@ -397,6 +399,5 @@ static __init int init_function_trace(void)
	init_func_cmd_traceon();
	return register_tracer(&function_trace);
}

device_initcall(init_function_trace);
+1 −1
Original line number Diff line number Diff line
/*
 * trace irqs off criticall timings
 * trace irqs off critical timings
 *
 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
 * Copyright (C) 2008 Ingo Molnar <mingo@redhat.com>
Loading