xref: /linux-6.15/kernel/trace/ftrace.c (revision bd69c30b)
116444a8aSArnaldo Carvalho de Melo /*
216444a8aSArnaldo Carvalho de Melo  * Infrastructure for profiling code inserted by 'gcc -pg'.
316444a8aSArnaldo Carvalho de Melo  *
416444a8aSArnaldo Carvalho de Melo  * Copyright (C) 2007-2008 Steven Rostedt <[email protected]>
516444a8aSArnaldo Carvalho de Melo  * Copyright (C) 2004-2008 Ingo Molnar <[email protected]>
616444a8aSArnaldo Carvalho de Melo  *
716444a8aSArnaldo Carvalho de Melo  * Originally ported from the -rt patch by:
816444a8aSArnaldo Carvalho de Melo  *   Copyright (C) 2007 Arnaldo Carvalho de Melo <[email protected]>
916444a8aSArnaldo Carvalho de Melo  *
1016444a8aSArnaldo Carvalho de Melo  * Based on code in the latency_tracer, that is:
1116444a8aSArnaldo Carvalho de Melo  *
1216444a8aSArnaldo Carvalho de Melo  *  Copyright (C) 2004-2006 Ingo Molnar
1316444a8aSArnaldo Carvalho de Melo  *  Copyright (C) 2004 William Lee Irwin III
1416444a8aSArnaldo Carvalho de Melo  */
1516444a8aSArnaldo Carvalho de Melo 
163d083395SSteven Rostedt #include <linux/stop_machine.h>
173d083395SSteven Rostedt #include <linux/clocksource.h>
183d083395SSteven Rostedt #include <linux/kallsyms.h>
195072c59fSSteven Rostedt #include <linux/seq_file.h>
204a2b8ddaSFrederic Weisbecker #include <linux/suspend.h>
215072c59fSSteven Rostedt #include <linux/debugfs.h>
223d083395SSteven Rostedt #include <linux/hardirq.h>
232d8b820bSIngo Molnar #include <linux/kthread.h>
245072c59fSSteven Rostedt #include <linux/uaccess.h>
252d8b820bSIngo Molnar #include <linux/ftrace.h>
26b0fc494fSSteven Rostedt #include <linux/sysctl.h>
275a0e3ad6STejun Heo #include <linux/slab.h>
285072c59fSSteven Rostedt #include <linux/ctype.h>
293d083395SSteven Rostedt #include <linux/list.h>
3059df055fSSteven Rostedt #include <linux/hash.h>
313f379b03SPaul E. McKenney #include <linux/rcupdate.h>
3216444a8aSArnaldo Carvalho de Melo 
33ad8d75ffSSteven Rostedt #include <trace/events/sched.h>
348aef2d28SSteven Rostedt 
35395a59d0SAbhishek Sagar #include <asm/ftrace.h>
362af15d6aSSteven Rostedt #include <asm/setup.h>
37395a59d0SAbhishek Sagar 
380706f1c4SSteven Rostedt #include "trace_output.h"
39bac429f0SSteven Rostedt #include "trace_stat.h"
403d083395SSteven Rostedt 
416912896eSSteven Rostedt #define FTRACE_WARN_ON(cond)			\
420778d9adSSteven Rostedt 	({					\
430778d9adSSteven Rostedt 		int ___r = cond;		\
440778d9adSSteven Rostedt 		if (WARN_ON(___r))		\
456912896eSSteven Rostedt 			ftrace_kill();		\
460778d9adSSteven Rostedt 		___r;				\
470778d9adSSteven Rostedt 	})
486912896eSSteven Rostedt 
496912896eSSteven Rostedt #define FTRACE_WARN_ON_ONCE(cond)		\
500778d9adSSteven Rostedt 	({					\
510778d9adSSteven Rostedt 		int ___r = cond;		\
520778d9adSSteven Rostedt 		if (WARN_ON_ONCE(___r))		\
536912896eSSteven Rostedt 			ftrace_kill();		\
540778d9adSSteven Rostedt 		___r;				\
550778d9adSSteven Rostedt 	})
566912896eSSteven Rostedt 
578fc0c701SSteven Rostedt /* hash bits for specific function selection */
588fc0c701SSteven Rostedt #define FTRACE_HASH_BITS 7
598fc0c701SSteven Rostedt #define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
6033dc9b12SSteven Rostedt #define FTRACE_HASH_DEFAULT_BITS 10
6133dc9b12SSteven Rostedt #define FTRACE_HASH_MAX_BITS 12
628fc0c701SSteven Rostedt 
634eebcc81SSteven Rostedt /* ftrace_enabled is a method to turn ftrace on or off */
644eebcc81SSteven Rostedt int ftrace_enabled __read_mostly;
65d61f82d0SSteven Rostedt static int last_ftrace_enabled;
66b0fc494fSSteven Rostedt 
6760a7ecf4SSteven Rostedt /* Quick disabling of function tracer. */
6860a7ecf4SSteven Rostedt int function_trace_stop;
6960a7ecf4SSteven Rostedt 
70756d17eeS[email protected] /* List for set_ftrace_pid's pids. */
71756d17eeS[email protected] LIST_HEAD(ftrace_pids);
72756d17eeS[email protected] struct ftrace_pid {
73756d17eeS[email protected] 	struct list_head list;
74756d17eeS[email protected] 	struct pid *pid;
75756d17eeS[email protected] };
76756d17eeS[email protected] 
774eebcc81SSteven Rostedt /*
784eebcc81SSteven Rostedt  * ftrace_disabled is set when an anomaly is discovered.
794eebcc81SSteven Rostedt  * ftrace_disabled is much stronger than ftrace_enabled.
804eebcc81SSteven Rostedt  */
814eebcc81SSteven Rostedt static int ftrace_disabled __read_mostly;
824eebcc81SSteven Rostedt 
8352baf119SSteven Rostedt static DEFINE_MUTEX(ftrace_lock);
84b0fc494fSSteven Rostedt 
8516444a8aSArnaldo Carvalho de Melo static struct ftrace_ops ftrace_list_end __read_mostly =
8616444a8aSArnaldo Carvalho de Melo {
8716444a8aSArnaldo Carvalho de Melo 	.func		= ftrace_stub,
8816444a8aSArnaldo Carvalho de Melo };
8916444a8aSArnaldo Carvalho de Melo 
9016444a8aSArnaldo Carvalho de Melo static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
9116444a8aSArnaldo Carvalho de Melo ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
9260a7ecf4SSteven Rostedt ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
93df4fc315SSteven Rostedt ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
9416444a8aSArnaldo Carvalho de Melo 
953f379b03SPaul E. McKenney /*
963f379b03SPaul E. McKenney  * Traverse the ftrace_list, invoking all entries.  The reason that we
973f379b03SPaul E. McKenney  * can use rcu_dereference_raw() is that elements removed from this list
983f379b03SPaul E. McKenney  * are simply leaked, so there is no need to interact with a grace-period
993f379b03SPaul E. McKenney  * mechanism.  The rcu_dereference_raw() calls are needed to handle
1003f379b03SPaul E. McKenney  * concurrent insertions into the ftrace_list.
1013f379b03SPaul E. McKenney  *
1023f379b03SPaul E. McKenney  * Silly Alpha and silly pointer-speculation compiler optimizations!
1033f379b03SPaul E. McKenney  */
104f2252935SIngo Molnar static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
10516444a8aSArnaldo Carvalho de Melo {
1063f379b03SPaul E. McKenney 	struct ftrace_ops *op = rcu_dereference_raw(ftrace_list); /*see above*/
10716444a8aSArnaldo Carvalho de Melo 
10816444a8aSArnaldo Carvalho de Melo 	while (op != &ftrace_list_end) {
10916444a8aSArnaldo Carvalho de Melo 		op->func(ip, parent_ip);
1103f379b03SPaul E. McKenney 		op = rcu_dereference_raw(op->next); /*see above*/
11116444a8aSArnaldo Carvalho de Melo 	};
11216444a8aSArnaldo Carvalho de Melo }
11316444a8aSArnaldo Carvalho de Melo 
114df4fc315SSteven Rostedt static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip)
115df4fc315SSteven Rostedt {
1160ef8cde5SSteven Rostedt 	if (!test_tsk_trace_trace(current))
117df4fc315SSteven Rostedt 		return;
118df4fc315SSteven Rostedt 
119df4fc315SSteven Rostedt 	ftrace_pid_function(ip, parent_ip);
120df4fc315SSteven Rostedt }
121df4fc315SSteven Rostedt 
122df4fc315SSteven Rostedt static void set_ftrace_pid_function(ftrace_func_t func)
123df4fc315SSteven Rostedt {
124df4fc315SSteven Rostedt 	/* do not set ftrace_pid_function to itself! */
125df4fc315SSteven Rostedt 	if (func != ftrace_pid_func)
126df4fc315SSteven Rostedt 		ftrace_pid_function = func;
127df4fc315SSteven Rostedt }
128df4fc315SSteven Rostedt 
12916444a8aSArnaldo Carvalho de Melo /**
1303d083395SSteven Rostedt  * clear_ftrace_function - reset the ftrace function
13116444a8aSArnaldo Carvalho de Melo  *
1323d083395SSteven Rostedt  * This NULLs the ftrace function and in essence stops
1333d083395SSteven Rostedt  * tracing.  There may be lag
13416444a8aSArnaldo Carvalho de Melo  */
1353d083395SSteven Rostedt void clear_ftrace_function(void)
13616444a8aSArnaldo Carvalho de Melo {
1373d083395SSteven Rostedt 	ftrace_trace_function = ftrace_stub;
13860a7ecf4SSteven Rostedt 	__ftrace_trace_function = ftrace_stub;
139df4fc315SSteven Rostedt 	ftrace_pid_function = ftrace_stub;
1403d083395SSteven Rostedt }
14116444a8aSArnaldo Carvalho de Melo 
14260a7ecf4SSteven Rostedt #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
14360a7ecf4SSteven Rostedt /*
14460a7ecf4SSteven Rostedt  * For those archs that do not test ftrace_trace_stop in their
14560a7ecf4SSteven Rostedt  * mcount call site, we need to do it from C.
14660a7ecf4SSteven Rostedt  */
14760a7ecf4SSteven Rostedt static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
14860a7ecf4SSteven Rostedt {
14960a7ecf4SSteven Rostedt 	if (function_trace_stop)
15060a7ecf4SSteven Rostedt 		return;
15160a7ecf4SSteven Rostedt 
15260a7ecf4SSteven Rostedt 	__ftrace_trace_function(ip, parent_ip);
15360a7ecf4SSteven Rostedt }
15460a7ecf4SSteven Rostedt #endif
15560a7ecf4SSteven Rostedt 
156491d0dcfSSteven Rostedt static void update_ftrace_function(void)
157491d0dcfSSteven Rostedt {
158491d0dcfSSteven Rostedt 	ftrace_func_t func;
159491d0dcfSSteven Rostedt 
160491d0dcfSSteven Rostedt 	/*
161491d0dcfSSteven Rostedt 	 * If there's only one function registered, then call that
162491d0dcfSSteven Rostedt 	 * function directly. Otherwise, we need to iterate over the
163491d0dcfSSteven Rostedt 	 * registered callers.
164491d0dcfSSteven Rostedt 	 */
165491d0dcfSSteven Rostedt 	if (ftrace_list == &ftrace_list_end ||
166491d0dcfSSteven Rostedt 	    ftrace_list->next == &ftrace_list_end)
167491d0dcfSSteven Rostedt 		func = ftrace_list->func;
168491d0dcfSSteven Rostedt 	else
169491d0dcfSSteven Rostedt 		func = ftrace_list_func;
170491d0dcfSSteven Rostedt 
171491d0dcfSSteven Rostedt 	/* If we filter on pids, update to use the pid function */
172491d0dcfSSteven Rostedt 	if (!list_empty(&ftrace_pids)) {
173491d0dcfSSteven Rostedt 		set_ftrace_pid_function(func);
174491d0dcfSSteven Rostedt 		func = ftrace_pid_func;
175491d0dcfSSteven Rostedt 	}
176491d0dcfSSteven Rostedt #ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
177491d0dcfSSteven Rostedt 	ftrace_trace_function = func;
178491d0dcfSSteven Rostedt #else
179491d0dcfSSteven Rostedt 	__ftrace_trace_function = func;
180491d0dcfSSteven Rostedt 	ftrace_trace_function = ftrace_test_stop_func;
181491d0dcfSSteven Rostedt #endif
182491d0dcfSSteven Rostedt }
183491d0dcfSSteven Rostedt 
184e309b41dSIngo Molnar static int __register_ftrace_function(struct ftrace_ops *ops)
1853d083395SSteven Rostedt {
18616444a8aSArnaldo Carvalho de Melo 	ops->next = ftrace_list;
18716444a8aSArnaldo Carvalho de Melo 	/*
18816444a8aSArnaldo Carvalho de Melo 	 * We are entering ops into the ftrace_list but another
18916444a8aSArnaldo Carvalho de Melo 	 * CPU might be walking that list. We need to make sure
19016444a8aSArnaldo Carvalho de Melo 	 * the ops->next pointer is valid before another CPU sees
19116444a8aSArnaldo Carvalho de Melo 	 * the ops pointer included into the ftrace_list.
19216444a8aSArnaldo Carvalho de Melo 	 */
1933f379b03SPaul E. McKenney 	rcu_assign_pointer(ftrace_list, ops);
1943d083395SSteven Rostedt 
195491d0dcfSSteven Rostedt 	if (ftrace_enabled)
196491d0dcfSSteven Rostedt 		update_ftrace_function();
1973d083395SSteven Rostedt 
19816444a8aSArnaldo Carvalho de Melo 	return 0;
19916444a8aSArnaldo Carvalho de Melo }
20016444a8aSArnaldo Carvalho de Melo 
201e309b41dSIngo Molnar static int __unregister_ftrace_function(struct ftrace_ops *ops)
20216444a8aSArnaldo Carvalho de Melo {
20316444a8aSArnaldo Carvalho de Melo 	struct ftrace_ops **p;
20416444a8aSArnaldo Carvalho de Melo 
20516444a8aSArnaldo Carvalho de Melo 	/*
2063d083395SSteven Rostedt 	 * If we are removing the last function, then simply point
2073d083395SSteven Rostedt 	 * to the ftrace_stub.
20816444a8aSArnaldo Carvalho de Melo 	 */
20916444a8aSArnaldo Carvalho de Melo 	if (ftrace_list == ops && ops->next == &ftrace_list_end) {
21016444a8aSArnaldo Carvalho de Melo 		ftrace_trace_function = ftrace_stub;
21116444a8aSArnaldo Carvalho de Melo 		ftrace_list = &ftrace_list_end;
212e6ea44e9SSteven Rostedt 		return 0;
21316444a8aSArnaldo Carvalho de Melo 	}
21416444a8aSArnaldo Carvalho de Melo 
21516444a8aSArnaldo Carvalho de Melo 	for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
21616444a8aSArnaldo Carvalho de Melo 		if (*p == ops)
21716444a8aSArnaldo Carvalho de Melo 			break;
21816444a8aSArnaldo Carvalho de Melo 
219e6ea44e9SSteven Rostedt 	if (*p != ops)
220e6ea44e9SSteven Rostedt 		return -1;
22116444a8aSArnaldo Carvalho de Melo 
22216444a8aSArnaldo Carvalho de Melo 	*p = (*p)->next;
22316444a8aSArnaldo Carvalho de Melo 
224491d0dcfSSteven Rostedt 	if (ftrace_enabled)
225491d0dcfSSteven Rostedt 		update_ftrace_function();
22616444a8aSArnaldo Carvalho de Melo 
227e6ea44e9SSteven Rostedt 	return 0;
2283d083395SSteven Rostedt }
2293d083395SSteven Rostedt 
230df4fc315SSteven Rostedt static void ftrace_update_pid_func(void)
231df4fc315SSteven Rostedt {
232491d0dcfSSteven Rostedt 	/* Only do something if we are tracing something */
233df4fc315SSteven Rostedt 	if (ftrace_trace_function == ftrace_stub)
23410dd3ebeSKOSAKI Motohiro 		return;
235df4fc315SSteven Rostedt 
236491d0dcfSSteven Rostedt 	update_ftrace_function();
237df4fc315SSteven Rostedt }
238df4fc315SSteven Rostedt 
239493762fcSSteven Rostedt #ifdef CONFIG_FUNCTION_PROFILER
240493762fcSSteven Rostedt struct ftrace_profile {
241493762fcSSteven Rostedt 	struct hlist_node		node;
242493762fcSSteven Rostedt 	unsigned long			ip;
243493762fcSSteven Rostedt 	unsigned long			counter;
2440706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2450706f1c4SSteven Rostedt 	unsigned long long		time;
246e330b3bcSChase Douglas 	unsigned long long		time_squared;
2470706f1c4SSteven Rostedt #endif
248493762fcSSteven Rostedt };
249493762fcSSteven Rostedt 
250493762fcSSteven Rostedt struct ftrace_profile_page {
251493762fcSSteven Rostedt 	struct ftrace_profile_page	*next;
252493762fcSSteven Rostedt 	unsigned long			index;
253493762fcSSteven Rostedt 	struct ftrace_profile		records[];
254493762fcSSteven Rostedt };
255493762fcSSteven Rostedt 
256cafb168aSSteven Rostedt struct ftrace_profile_stat {
257cafb168aSSteven Rostedt 	atomic_t			disabled;
258cafb168aSSteven Rostedt 	struct hlist_head		*hash;
259cafb168aSSteven Rostedt 	struct ftrace_profile_page	*pages;
260cafb168aSSteven Rostedt 	struct ftrace_profile_page	*start;
261cafb168aSSteven Rostedt 	struct tracer_stat		stat;
262cafb168aSSteven Rostedt };
263cafb168aSSteven Rostedt 
264493762fcSSteven Rostedt #define PROFILE_RECORDS_SIZE						\
265493762fcSSteven Rostedt 	(PAGE_SIZE - offsetof(struct ftrace_profile_page, records))
266493762fcSSteven Rostedt 
267493762fcSSteven Rostedt #define PROFILES_PER_PAGE					\
268493762fcSSteven Rostedt 	(PROFILE_RECORDS_SIZE / sizeof(struct ftrace_profile))
269493762fcSSteven Rostedt 
270fb9fb015SSteven Rostedt static int ftrace_profile_bits __read_mostly;
271fb9fb015SSteven Rostedt static int ftrace_profile_enabled __read_mostly;
272fb9fb015SSteven Rostedt 
273fb9fb015SSteven Rostedt /* ftrace_profile_lock - synchronize the enable and disable of the profiler */
274493762fcSSteven Rostedt static DEFINE_MUTEX(ftrace_profile_lock);
275493762fcSSteven Rostedt 
276cafb168aSSteven Rostedt static DEFINE_PER_CPU(struct ftrace_profile_stat, ftrace_profile_stats);
277493762fcSSteven Rostedt 
278493762fcSSteven Rostedt #define FTRACE_PROFILE_HASH_SIZE 1024 /* must be power of 2 */
279493762fcSSteven Rostedt 
280493762fcSSteven Rostedt static void *
281493762fcSSteven Rostedt function_stat_next(void *v, int idx)
282493762fcSSteven Rostedt {
283493762fcSSteven Rostedt 	struct ftrace_profile *rec = v;
284493762fcSSteven Rostedt 	struct ftrace_profile_page *pg;
285493762fcSSteven Rostedt 
286493762fcSSteven Rostedt 	pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK);
287493762fcSSteven Rostedt 
288493762fcSSteven Rostedt  again:
2890296e425SLi Zefan 	if (idx != 0)
290493762fcSSteven Rostedt 		rec++;
2910296e425SLi Zefan 
292493762fcSSteven Rostedt 	if ((void *)rec >= (void *)&pg->records[pg->index]) {
293493762fcSSteven Rostedt 		pg = pg->next;
294493762fcSSteven Rostedt 		if (!pg)
295493762fcSSteven Rostedt 			return NULL;
296493762fcSSteven Rostedt 		rec = &pg->records[0];
297493762fcSSteven Rostedt 		if (!rec->counter)
298493762fcSSteven Rostedt 			goto again;
299493762fcSSteven Rostedt 	}
300493762fcSSteven Rostedt 
301493762fcSSteven Rostedt 	return rec;
302493762fcSSteven Rostedt }
303493762fcSSteven Rostedt 
304493762fcSSteven Rostedt static void *function_stat_start(struct tracer_stat *trace)
305493762fcSSteven Rostedt {
306cafb168aSSteven Rostedt 	struct ftrace_profile_stat *stat =
307cafb168aSSteven Rostedt 		container_of(trace, struct ftrace_profile_stat, stat);
308cafb168aSSteven Rostedt 
309cafb168aSSteven Rostedt 	if (!stat || !stat->start)
310cafb168aSSteven Rostedt 		return NULL;
311cafb168aSSteven Rostedt 
312cafb168aSSteven Rostedt 	return function_stat_next(&stat->start->records[0], 0);
313493762fcSSteven Rostedt }
314493762fcSSteven Rostedt 
3150706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
3160706f1c4SSteven Rostedt /* function graph compares on total time */
3170706f1c4SSteven Rostedt static int function_stat_cmp(void *p1, void *p2)
3180706f1c4SSteven Rostedt {
3190706f1c4SSteven Rostedt 	struct ftrace_profile *a = p1;
3200706f1c4SSteven Rostedt 	struct ftrace_profile *b = p2;
3210706f1c4SSteven Rostedt 
3220706f1c4SSteven Rostedt 	if (a->time < b->time)
3230706f1c4SSteven Rostedt 		return -1;
3240706f1c4SSteven Rostedt 	if (a->time > b->time)
3250706f1c4SSteven Rostedt 		return 1;
3260706f1c4SSteven Rostedt 	else
3270706f1c4SSteven Rostedt 		return 0;
3280706f1c4SSteven Rostedt }
3290706f1c4SSteven Rostedt #else
3300706f1c4SSteven Rostedt /* not function graph compares against hits */
331493762fcSSteven Rostedt static int function_stat_cmp(void *p1, void *p2)
332493762fcSSteven Rostedt {
333493762fcSSteven Rostedt 	struct ftrace_profile *a = p1;
334493762fcSSteven Rostedt 	struct ftrace_profile *b = p2;
335493762fcSSteven Rostedt 
336493762fcSSteven Rostedt 	if (a->counter < b->counter)
337493762fcSSteven Rostedt 		return -1;
338493762fcSSteven Rostedt 	if (a->counter > b->counter)
339493762fcSSteven Rostedt 		return 1;
340493762fcSSteven Rostedt 	else
341493762fcSSteven Rostedt 		return 0;
342493762fcSSteven Rostedt }
3430706f1c4SSteven Rostedt #endif
344493762fcSSteven Rostedt 
345493762fcSSteven Rostedt static int function_stat_headers(struct seq_file *m)
346493762fcSSteven Rostedt {
3470706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
34834886c8bSSteven Rostedt 	seq_printf(m, "  Function                               "
349e330b3bcSChase Douglas 		   "Hit    Time            Avg             s^2\n"
35034886c8bSSteven Rostedt 		      "  --------                               "
351e330b3bcSChase Douglas 		   "---    ----            ---             ---\n");
3520706f1c4SSteven Rostedt #else
353493762fcSSteven Rostedt 	seq_printf(m, "  Function                               Hit\n"
354493762fcSSteven Rostedt 		      "  --------                               ---\n");
3550706f1c4SSteven Rostedt #endif
356493762fcSSteven Rostedt 	return 0;
357493762fcSSteven Rostedt }
358493762fcSSteven Rostedt 
359493762fcSSteven Rostedt static int function_stat_show(struct seq_file *m, void *v)
360493762fcSSteven Rostedt {
361493762fcSSteven Rostedt 	struct ftrace_profile *rec = v;
362493762fcSSteven Rostedt 	char str[KSYM_SYMBOL_LEN];
3633aaba20fSLi Zefan 	int ret = 0;
3640706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
36534886c8bSSteven Rostedt 	static struct trace_seq s;
36634886c8bSSteven Rostedt 	unsigned long long avg;
367e330b3bcSChase Douglas 	unsigned long long stddev;
3680706f1c4SSteven Rostedt #endif
3693aaba20fSLi Zefan 	mutex_lock(&ftrace_profile_lock);
3703aaba20fSLi Zefan 
3713aaba20fSLi Zefan 	/* we raced with function_profile_reset() */
3723aaba20fSLi Zefan 	if (unlikely(rec->counter == 0)) {
3733aaba20fSLi Zefan 		ret = -EBUSY;
3743aaba20fSLi Zefan 		goto out;
3753aaba20fSLi Zefan 	}
376493762fcSSteven Rostedt 
377493762fcSSteven Rostedt 	kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
3780706f1c4SSteven Rostedt 	seq_printf(m, "  %-30.30s  %10lu", str, rec->counter);
379493762fcSSteven Rostedt 
3800706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
3810706f1c4SSteven Rostedt 	seq_printf(m, "    ");
38234886c8bSSteven Rostedt 	avg = rec->time;
38334886c8bSSteven Rostedt 	do_div(avg, rec->counter);
38434886c8bSSteven Rostedt 
385e330b3bcSChase Douglas 	/* Sample standard deviation (s^2) */
386e330b3bcSChase Douglas 	if (rec->counter <= 1)
387e330b3bcSChase Douglas 		stddev = 0;
388e330b3bcSChase Douglas 	else {
389e330b3bcSChase Douglas 		stddev = rec->time_squared - rec->counter * avg * avg;
390e330b3bcSChase Douglas 		/*
391e330b3bcSChase Douglas 		 * Divide only 1000 for ns^2 -> us^2 conversion.
392e330b3bcSChase Douglas 		 * trace_print_graph_duration will divide 1000 again.
393e330b3bcSChase Douglas 		 */
394e330b3bcSChase Douglas 		do_div(stddev, (rec->counter - 1) * 1000);
395e330b3bcSChase Douglas 	}
396e330b3bcSChase Douglas 
39734886c8bSSteven Rostedt 	trace_seq_init(&s);
39834886c8bSSteven Rostedt 	trace_print_graph_duration(rec->time, &s);
39934886c8bSSteven Rostedt 	trace_seq_puts(&s, "    ");
40034886c8bSSteven Rostedt 	trace_print_graph_duration(avg, &s);
401e330b3bcSChase Douglas 	trace_seq_puts(&s, "    ");
402e330b3bcSChase Douglas 	trace_print_graph_duration(stddev, &s);
4030706f1c4SSteven Rostedt 	trace_print_seq(m, &s);
4040706f1c4SSteven Rostedt #endif
4050706f1c4SSteven Rostedt 	seq_putc(m, '\n');
4063aaba20fSLi Zefan out:
4073aaba20fSLi Zefan 	mutex_unlock(&ftrace_profile_lock);
4080706f1c4SSteven Rostedt 
4093aaba20fSLi Zefan 	return ret;
410493762fcSSteven Rostedt }
411493762fcSSteven Rostedt 
412cafb168aSSteven Rostedt static void ftrace_profile_reset(struct ftrace_profile_stat *stat)
413493762fcSSteven Rostedt {
414493762fcSSteven Rostedt 	struct ftrace_profile_page *pg;
415493762fcSSteven Rostedt 
416cafb168aSSteven Rostedt 	pg = stat->pages = stat->start;
417493762fcSSteven Rostedt 
418493762fcSSteven Rostedt 	while (pg) {
419493762fcSSteven Rostedt 		memset(pg->records, 0, PROFILE_RECORDS_SIZE);
420493762fcSSteven Rostedt 		pg->index = 0;
421493762fcSSteven Rostedt 		pg = pg->next;
422493762fcSSteven Rostedt 	}
423493762fcSSteven Rostedt 
424cafb168aSSteven Rostedt 	memset(stat->hash, 0,
425493762fcSSteven Rostedt 	       FTRACE_PROFILE_HASH_SIZE * sizeof(struct hlist_head));
426493762fcSSteven Rostedt }
427493762fcSSteven Rostedt 
428cafb168aSSteven Rostedt int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
429493762fcSSteven Rostedt {
430493762fcSSteven Rostedt 	struct ftrace_profile_page *pg;
431318e0a73SSteven Rostedt 	int functions;
432318e0a73SSteven Rostedt 	int pages;
433493762fcSSteven Rostedt 	int i;
434493762fcSSteven Rostedt 
435493762fcSSteven Rostedt 	/* If we already allocated, do nothing */
436cafb168aSSteven Rostedt 	if (stat->pages)
437493762fcSSteven Rostedt 		return 0;
438493762fcSSteven Rostedt 
439cafb168aSSteven Rostedt 	stat->pages = (void *)get_zeroed_page(GFP_KERNEL);
440cafb168aSSteven Rostedt 	if (!stat->pages)
441493762fcSSteven Rostedt 		return -ENOMEM;
442493762fcSSteven Rostedt 
443318e0a73SSteven Rostedt #ifdef CONFIG_DYNAMIC_FTRACE
444318e0a73SSteven Rostedt 	functions = ftrace_update_tot_cnt;
445318e0a73SSteven Rostedt #else
446318e0a73SSteven Rostedt 	/*
447318e0a73SSteven Rostedt 	 * We do not know the number of functions that exist because
448318e0a73SSteven Rostedt 	 * dynamic tracing is what counts them. With past experience
449318e0a73SSteven Rostedt 	 * we have around 20K functions. That should be more than enough.
450318e0a73SSteven Rostedt 	 * It is highly unlikely we will execute every function in
451318e0a73SSteven Rostedt 	 * the kernel.
452318e0a73SSteven Rostedt 	 */
453318e0a73SSteven Rostedt 	functions = 20000;
454318e0a73SSteven Rostedt #endif
455318e0a73SSteven Rostedt 
456cafb168aSSteven Rostedt 	pg = stat->start = stat->pages;
457493762fcSSteven Rostedt 
458318e0a73SSteven Rostedt 	pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE);
459318e0a73SSteven Rostedt 
460318e0a73SSteven Rostedt 	for (i = 0; i < pages; i++) {
461493762fcSSteven Rostedt 		pg->next = (void *)get_zeroed_page(GFP_KERNEL);
462493762fcSSteven Rostedt 		if (!pg->next)
463318e0a73SSteven Rostedt 			goto out_free;
464493762fcSSteven Rostedt 		pg = pg->next;
465493762fcSSteven Rostedt 	}
466493762fcSSteven Rostedt 
467493762fcSSteven Rostedt 	return 0;
468318e0a73SSteven Rostedt 
469318e0a73SSteven Rostedt  out_free:
470318e0a73SSteven Rostedt 	pg = stat->start;
471318e0a73SSteven Rostedt 	while (pg) {
472318e0a73SSteven Rostedt 		unsigned long tmp = (unsigned long)pg;
473318e0a73SSteven Rostedt 
474318e0a73SSteven Rostedt 		pg = pg->next;
475318e0a73SSteven Rostedt 		free_page(tmp);
476318e0a73SSteven Rostedt 	}
477318e0a73SSteven Rostedt 
478318e0a73SSteven Rostedt 	free_page((unsigned long)stat->pages);
479318e0a73SSteven Rostedt 	stat->pages = NULL;
480318e0a73SSteven Rostedt 	stat->start = NULL;
481318e0a73SSteven Rostedt 
482318e0a73SSteven Rostedt 	return -ENOMEM;
483493762fcSSteven Rostedt }
484493762fcSSteven Rostedt 
485cafb168aSSteven Rostedt static int ftrace_profile_init_cpu(int cpu)
486493762fcSSteven Rostedt {
487cafb168aSSteven Rostedt 	struct ftrace_profile_stat *stat;
488493762fcSSteven Rostedt 	int size;
489493762fcSSteven Rostedt 
490cafb168aSSteven Rostedt 	stat = &per_cpu(ftrace_profile_stats, cpu);
491cafb168aSSteven Rostedt 
492cafb168aSSteven Rostedt 	if (stat->hash) {
493493762fcSSteven Rostedt 		/* If the profile is already created, simply reset it */
494cafb168aSSteven Rostedt 		ftrace_profile_reset(stat);
495493762fcSSteven Rostedt 		return 0;
496493762fcSSteven Rostedt 	}
497493762fcSSteven Rostedt 
498493762fcSSteven Rostedt 	/*
499493762fcSSteven Rostedt 	 * We are profiling all functions, but usually only a few thousand
500493762fcSSteven Rostedt 	 * functions are hit. We'll make a hash of 1024 items.
501493762fcSSteven Rostedt 	 */
502493762fcSSteven Rostedt 	size = FTRACE_PROFILE_HASH_SIZE;
503493762fcSSteven Rostedt 
504cafb168aSSteven Rostedt 	stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL);
505493762fcSSteven Rostedt 
506cafb168aSSteven Rostedt 	if (!stat->hash)
507493762fcSSteven Rostedt 		return -ENOMEM;
508493762fcSSteven Rostedt 
509cafb168aSSteven Rostedt 	if (!ftrace_profile_bits) {
510493762fcSSteven Rostedt 		size--;
511493762fcSSteven Rostedt 
512493762fcSSteven Rostedt 		for (; size; size >>= 1)
513493762fcSSteven Rostedt 			ftrace_profile_bits++;
514cafb168aSSteven Rostedt 	}
515493762fcSSteven Rostedt 
516318e0a73SSteven Rostedt 	/* Preallocate the function profiling pages */
517cafb168aSSteven Rostedt 	if (ftrace_profile_pages_init(stat) < 0) {
518cafb168aSSteven Rostedt 		kfree(stat->hash);
519cafb168aSSteven Rostedt 		stat->hash = NULL;
520493762fcSSteven Rostedt 		return -ENOMEM;
521493762fcSSteven Rostedt 	}
522493762fcSSteven Rostedt 
523493762fcSSteven Rostedt 	return 0;
524493762fcSSteven Rostedt }
525493762fcSSteven Rostedt 
526cafb168aSSteven Rostedt static int ftrace_profile_init(void)
527cafb168aSSteven Rostedt {
528cafb168aSSteven Rostedt 	int cpu;
529cafb168aSSteven Rostedt 	int ret = 0;
530cafb168aSSteven Rostedt 
531cafb168aSSteven Rostedt 	for_each_online_cpu(cpu) {
532cafb168aSSteven Rostedt 		ret = ftrace_profile_init_cpu(cpu);
533cafb168aSSteven Rostedt 		if (ret)
534cafb168aSSteven Rostedt 			break;
535cafb168aSSteven Rostedt 	}
536cafb168aSSteven Rostedt 
537cafb168aSSteven Rostedt 	return ret;
538cafb168aSSteven Rostedt }
539cafb168aSSteven Rostedt 
540493762fcSSteven Rostedt /* interrupts must be disabled */
541cafb168aSSteven Rostedt static struct ftrace_profile *
542cafb168aSSteven Rostedt ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
543493762fcSSteven Rostedt {
544493762fcSSteven Rostedt 	struct ftrace_profile *rec;
545493762fcSSteven Rostedt 	struct hlist_head *hhd;
546493762fcSSteven Rostedt 	struct hlist_node *n;
547493762fcSSteven Rostedt 	unsigned long key;
548493762fcSSteven Rostedt 
549493762fcSSteven Rostedt 	key = hash_long(ip, ftrace_profile_bits);
550cafb168aSSteven Rostedt 	hhd = &stat->hash[key];
551493762fcSSteven Rostedt 
552493762fcSSteven Rostedt 	if (hlist_empty(hhd))
553493762fcSSteven Rostedt 		return NULL;
554493762fcSSteven Rostedt 
555493762fcSSteven Rostedt 	hlist_for_each_entry_rcu(rec, n, hhd, node) {
556493762fcSSteven Rostedt 		if (rec->ip == ip)
557493762fcSSteven Rostedt 			return rec;
558493762fcSSteven Rostedt 	}
559493762fcSSteven Rostedt 
560493762fcSSteven Rostedt 	return NULL;
561493762fcSSteven Rostedt }
562493762fcSSteven Rostedt 
563cafb168aSSteven Rostedt static void ftrace_add_profile(struct ftrace_profile_stat *stat,
564cafb168aSSteven Rostedt 			       struct ftrace_profile *rec)
565493762fcSSteven Rostedt {
566493762fcSSteven Rostedt 	unsigned long key;
567493762fcSSteven Rostedt 
568493762fcSSteven Rostedt 	key = hash_long(rec->ip, ftrace_profile_bits);
569cafb168aSSteven Rostedt 	hlist_add_head_rcu(&rec->node, &stat->hash[key]);
570493762fcSSteven Rostedt }
571493762fcSSteven Rostedt 
572318e0a73SSteven Rostedt /*
573318e0a73SSteven Rostedt  * The memory is already allocated, this simply finds a new record to use.
574318e0a73SSteven Rostedt  */
575493762fcSSteven Rostedt static struct ftrace_profile *
576318e0a73SSteven Rostedt ftrace_profile_alloc(struct ftrace_profile_stat *stat, unsigned long ip)
577493762fcSSteven Rostedt {
578493762fcSSteven Rostedt 	struct ftrace_profile *rec = NULL;
579493762fcSSteven Rostedt 
580318e0a73SSteven Rostedt 	/* prevent recursion (from NMIs) */
581cafb168aSSteven Rostedt 	if (atomic_inc_return(&stat->disabled) != 1)
582493762fcSSteven Rostedt 		goto out;
583493762fcSSteven Rostedt 
584493762fcSSteven Rostedt 	/*
585318e0a73SSteven Rostedt 	 * Try to find the function again since an NMI
586318e0a73SSteven Rostedt 	 * could have added it
587493762fcSSteven Rostedt 	 */
588cafb168aSSteven Rostedt 	rec = ftrace_find_profiled_func(stat, ip);
589493762fcSSteven Rostedt 	if (rec)
590cafb168aSSteven Rostedt 		goto out;
591493762fcSSteven Rostedt 
592cafb168aSSteven Rostedt 	if (stat->pages->index == PROFILES_PER_PAGE) {
593cafb168aSSteven Rostedt 		if (!stat->pages->next)
594cafb168aSSteven Rostedt 			goto out;
595cafb168aSSteven Rostedt 		stat->pages = stat->pages->next;
596493762fcSSteven Rostedt 	}
597493762fcSSteven Rostedt 
598cafb168aSSteven Rostedt 	rec = &stat->pages->records[stat->pages->index++];
599493762fcSSteven Rostedt 	rec->ip = ip;
600cafb168aSSteven Rostedt 	ftrace_add_profile(stat, rec);
601493762fcSSteven Rostedt 
602493762fcSSteven Rostedt  out:
603cafb168aSSteven Rostedt 	atomic_dec(&stat->disabled);
604493762fcSSteven Rostedt 
605493762fcSSteven Rostedt 	return rec;
606493762fcSSteven Rostedt }
607493762fcSSteven Rostedt 
608493762fcSSteven Rostedt static void
609493762fcSSteven Rostedt function_profile_call(unsigned long ip, unsigned long parent_ip)
610493762fcSSteven Rostedt {
611cafb168aSSteven Rostedt 	struct ftrace_profile_stat *stat;
612493762fcSSteven Rostedt 	struct ftrace_profile *rec;
613493762fcSSteven Rostedt 	unsigned long flags;
614493762fcSSteven Rostedt 
615493762fcSSteven Rostedt 	if (!ftrace_profile_enabled)
616493762fcSSteven Rostedt 		return;
617493762fcSSteven Rostedt 
618493762fcSSteven Rostedt 	local_irq_save(flags);
619cafb168aSSteven Rostedt 
620cafb168aSSteven Rostedt 	stat = &__get_cpu_var(ftrace_profile_stats);
6210f6ce3deSSteven Rostedt 	if (!stat->hash || !ftrace_profile_enabled)
622cafb168aSSteven Rostedt 		goto out;
623cafb168aSSteven Rostedt 
624cafb168aSSteven Rostedt 	rec = ftrace_find_profiled_func(stat, ip);
625493762fcSSteven Rostedt 	if (!rec) {
626318e0a73SSteven Rostedt 		rec = ftrace_profile_alloc(stat, ip);
627493762fcSSteven Rostedt 		if (!rec)
628493762fcSSteven Rostedt 			goto out;
629493762fcSSteven Rostedt 	}
630493762fcSSteven Rostedt 
631493762fcSSteven Rostedt 	rec->counter++;
632493762fcSSteven Rostedt  out:
633493762fcSSteven Rostedt 	local_irq_restore(flags);
634493762fcSSteven Rostedt }
635493762fcSSteven Rostedt 
6360706f1c4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
6370706f1c4SSteven Rostedt static int profile_graph_entry(struct ftrace_graph_ent *trace)
6380706f1c4SSteven Rostedt {
6390706f1c4SSteven Rostedt 	function_profile_call(trace->func, 0);
6400706f1c4SSteven Rostedt 	return 1;
6410706f1c4SSteven Rostedt }
6420706f1c4SSteven Rostedt 
6430706f1c4SSteven Rostedt static void profile_graph_return(struct ftrace_graph_ret *trace)
6440706f1c4SSteven Rostedt {
645cafb168aSSteven Rostedt 	struct ftrace_profile_stat *stat;
646a2a16d6aSSteven Rostedt 	unsigned long long calltime;
6470706f1c4SSteven Rostedt 	struct ftrace_profile *rec;
648cafb168aSSteven Rostedt 	unsigned long flags;
6490706f1c4SSteven Rostedt 
6500706f1c4SSteven Rostedt 	local_irq_save(flags);
651cafb168aSSteven Rostedt 	stat = &__get_cpu_var(ftrace_profile_stats);
6520f6ce3deSSteven Rostedt 	if (!stat->hash || !ftrace_profile_enabled)
653cafb168aSSteven Rostedt 		goto out;
654cafb168aSSteven Rostedt 
65537e44bc5SSteven Rostedt 	/* If the calltime was zero'd ignore it */
65637e44bc5SSteven Rostedt 	if (!trace->calltime)
65737e44bc5SSteven Rostedt 		goto out;
65837e44bc5SSteven Rostedt 
659a2a16d6aSSteven Rostedt 	calltime = trace->rettime - trace->calltime;
660a2a16d6aSSteven Rostedt 
661a2a16d6aSSteven Rostedt 	if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
662a2a16d6aSSteven Rostedt 		int index;
663a2a16d6aSSteven Rostedt 
664a2a16d6aSSteven Rostedt 		index = trace->depth;
665a2a16d6aSSteven Rostedt 
666a2a16d6aSSteven Rostedt 		/* Append this call time to the parent time to subtract */
667a2a16d6aSSteven Rostedt 		if (index)
668a2a16d6aSSteven Rostedt 			current->ret_stack[index - 1].subtime += calltime;
669a2a16d6aSSteven Rostedt 
670a2a16d6aSSteven Rostedt 		if (current->ret_stack[index].subtime < calltime)
671a2a16d6aSSteven Rostedt 			calltime -= current->ret_stack[index].subtime;
672a2a16d6aSSteven Rostedt 		else
673a2a16d6aSSteven Rostedt 			calltime = 0;
674a2a16d6aSSteven Rostedt 	}
675a2a16d6aSSteven Rostedt 
676cafb168aSSteven Rostedt 	rec = ftrace_find_profiled_func(stat, trace->func);
677e330b3bcSChase Douglas 	if (rec) {
678a2a16d6aSSteven Rostedt 		rec->time += calltime;
679e330b3bcSChase Douglas 		rec->time_squared += calltime * calltime;
680e330b3bcSChase Douglas 	}
681a2a16d6aSSteven Rostedt 
682cafb168aSSteven Rostedt  out:
6830706f1c4SSteven Rostedt 	local_irq_restore(flags);
6840706f1c4SSteven Rostedt }
6850706f1c4SSteven Rostedt 
6860706f1c4SSteven Rostedt static int register_ftrace_profiler(void)
6870706f1c4SSteven Rostedt {
6880706f1c4SSteven Rostedt 	return register_ftrace_graph(&profile_graph_return,
6890706f1c4SSteven Rostedt 				     &profile_graph_entry);
6900706f1c4SSteven Rostedt }
6910706f1c4SSteven Rostedt 
6920706f1c4SSteven Rostedt static void unregister_ftrace_profiler(void)
6930706f1c4SSteven Rostedt {
6940706f1c4SSteven Rostedt 	unregister_ftrace_graph();
6950706f1c4SSteven Rostedt }
6960706f1c4SSteven Rostedt #else
697493762fcSSteven Rostedt static struct ftrace_ops ftrace_profile_ops __read_mostly =
698493762fcSSteven Rostedt {
699493762fcSSteven Rostedt 	.func		= function_profile_call,
700493762fcSSteven Rostedt };
701493762fcSSteven Rostedt 
7020706f1c4SSteven Rostedt static int register_ftrace_profiler(void)
7030706f1c4SSteven Rostedt {
7040706f1c4SSteven Rostedt 	return register_ftrace_function(&ftrace_profile_ops);
7050706f1c4SSteven Rostedt }
7060706f1c4SSteven Rostedt 
7070706f1c4SSteven Rostedt static void unregister_ftrace_profiler(void)
7080706f1c4SSteven Rostedt {
7090706f1c4SSteven Rostedt 	unregister_ftrace_function(&ftrace_profile_ops);
7100706f1c4SSteven Rostedt }
7110706f1c4SSteven Rostedt #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
7120706f1c4SSteven Rostedt 
713493762fcSSteven Rostedt static ssize_t
714493762fcSSteven Rostedt ftrace_profile_write(struct file *filp, const char __user *ubuf,
715493762fcSSteven Rostedt 		     size_t cnt, loff_t *ppos)
716493762fcSSteven Rostedt {
717493762fcSSteven Rostedt 	unsigned long val;
718fb9fb015SSteven Rostedt 	char buf[64];		/* big enough to hold a number */
719493762fcSSteven Rostedt 	int ret;
720493762fcSSteven Rostedt 
721493762fcSSteven Rostedt 	if (cnt >= sizeof(buf))
722493762fcSSteven Rostedt 		return -EINVAL;
723493762fcSSteven Rostedt 
724493762fcSSteven Rostedt 	if (copy_from_user(&buf, ubuf, cnt))
725493762fcSSteven Rostedt 		return -EFAULT;
726493762fcSSteven Rostedt 
727493762fcSSteven Rostedt 	buf[cnt] = 0;
728493762fcSSteven Rostedt 
729493762fcSSteven Rostedt 	ret = strict_strtoul(buf, 10, &val);
730493762fcSSteven Rostedt 	if (ret < 0)
731493762fcSSteven Rostedt 		return ret;
732493762fcSSteven Rostedt 
733493762fcSSteven Rostedt 	val = !!val;
734493762fcSSteven Rostedt 
735493762fcSSteven Rostedt 	mutex_lock(&ftrace_profile_lock);
736493762fcSSteven Rostedt 	if (ftrace_profile_enabled ^ val) {
737493762fcSSteven Rostedt 		if (val) {
738493762fcSSteven Rostedt 			ret = ftrace_profile_init();
739493762fcSSteven Rostedt 			if (ret < 0) {
740493762fcSSteven Rostedt 				cnt = ret;
741493762fcSSteven Rostedt 				goto out;
742493762fcSSteven Rostedt 			}
743493762fcSSteven Rostedt 
7440706f1c4SSteven Rostedt 			ret = register_ftrace_profiler();
7450706f1c4SSteven Rostedt 			if (ret < 0) {
7460706f1c4SSteven Rostedt 				cnt = ret;
7470706f1c4SSteven Rostedt 				goto out;
7480706f1c4SSteven Rostedt 			}
749493762fcSSteven Rostedt 			ftrace_profile_enabled = 1;
750493762fcSSteven Rostedt 		} else {
751493762fcSSteven Rostedt 			ftrace_profile_enabled = 0;
7520f6ce3deSSteven Rostedt 			/*
7530f6ce3deSSteven Rostedt 			 * unregister_ftrace_profiler calls stop_machine
7540f6ce3deSSteven Rostedt 			 * so this acts like an synchronize_sched.
7550f6ce3deSSteven Rostedt 			 */
7560706f1c4SSteven Rostedt 			unregister_ftrace_profiler();
757493762fcSSteven Rostedt 		}
758493762fcSSteven Rostedt 	}
759493762fcSSteven Rostedt  out:
760493762fcSSteven Rostedt 	mutex_unlock(&ftrace_profile_lock);
761493762fcSSteven Rostedt 
762cf8517cfSJiri Olsa 	*ppos += cnt;
763493762fcSSteven Rostedt 
764493762fcSSteven Rostedt 	return cnt;
765493762fcSSteven Rostedt }
766493762fcSSteven Rostedt 
767493762fcSSteven Rostedt static ssize_t
768493762fcSSteven Rostedt ftrace_profile_read(struct file *filp, char __user *ubuf,
769493762fcSSteven Rostedt 		     size_t cnt, loff_t *ppos)
770493762fcSSteven Rostedt {
771fb9fb015SSteven Rostedt 	char buf[64];		/* big enough to hold a number */
772493762fcSSteven Rostedt 	int r;
773493762fcSSteven Rostedt 
774493762fcSSteven Rostedt 	r = sprintf(buf, "%u\n", ftrace_profile_enabled);
775493762fcSSteven Rostedt 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
776493762fcSSteven Rostedt }
777493762fcSSteven Rostedt 
778493762fcSSteven Rostedt static const struct file_operations ftrace_profile_fops = {
779493762fcSSteven Rostedt 	.open		= tracing_open_generic,
780493762fcSSteven Rostedt 	.read		= ftrace_profile_read,
781493762fcSSteven Rostedt 	.write		= ftrace_profile_write,
7826038f373SArnd Bergmann 	.llseek		= default_llseek,
783493762fcSSteven Rostedt };
784493762fcSSteven Rostedt 
785cafb168aSSteven Rostedt /* used to initialize the real stat files */
786cafb168aSSteven Rostedt static struct tracer_stat function_stats __initdata = {
787cafb168aSSteven Rostedt 	.name		= "functions",
788cafb168aSSteven Rostedt 	.stat_start	= function_stat_start,
789cafb168aSSteven Rostedt 	.stat_next	= function_stat_next,
790cafb168aSSteven Rostedt 	.stat_cmp	= function_stat_cmp,
791cafb168aSSteven Rostedt 	.stat_headers	= function_stat_headers,
792cafb168aSSteven Rostedt 	.stat_show	= function_stat_show
793cafb168aSSteven Rostedt };
794cafb168aSSteven Rostedt 
7956ab5d668SSteven Rostedt static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
796493762fcSSteven Rostedt {
797cafb168aSSteven Rostedt 	struct ftrace_profile_stat *stat;
798493762fcSSteven Rostedt 	struct dentry *entry;
799cafb168aSSteven Rostedt 	char *name;
800493762fcSSteven Rostedt 	int ret;
801cafb168aSSteven Rostedt 	int cpu;
802493762fcSSteven Rostedt 
803cafb168aSSteven Rostedt 	for_each_possible_cpu(cpu) {
804cafb168aSSteven Rostedt 		stat = &per_cpu(ftrace_profile_stats, cpu);
805cafb168aSSteven Rostedt 
806cafb168aSSteven Rostedt 		/* allocate enough for function name + cpu number */
807cafb168aSSteven Rostedt 		name = kmalloc(32, GFP_KERNEL);
808cafb168aSSteven Rostedt 		if (!name) {
809cafb168aSSteven Rostedt 			/*
810cafb168aSSteven Rostedt 			 * The files created are permanent, if something happens
811cafb168aSSteven Rostedt 			 * we still do not free memory.
812cafb168aSSteven Rostedt 			 */
813cafb168aSSteven Rostedt 			WARN(1,
814cafb168aSSteven Rostedt 			     "Could not allocate stat file for cpu %d\n",
815cafb168aSSteven Rostedt 			     cpu);
816493762fcSSteven Rostedt 			return;
817493762fcSSteven Rostedt 		}
818cafb168aSSteven Rostedt 		stat->stat = function_stats;
819cafb168aSSteven Rostedt 		snprintf(name, 32, "function%d", cpu);
820cafb168aSSteven Rostedt 		stat->stat.name = name;
821cafb168aSSteven Rostedt 		ret = register_stat_tracer(&stat->stat);
822cafb168aSSteven Rostedt 		if (ret) {
823cafb168aSSteven Rostedt 			WARN(1,
824cafb168aSSteven Rostedt 			     "Could not register function stat for cpu %d\n",
825cafb168aSSteven Rostedt 			     cpu);
826cafb168aSSteven Rostedt 			kfree(name);
827cafb168aSSteven Rostedt 			return;
828cafb168aSSteven Rostedt 		}
829cafb168aSSteven Rostedt 	}
830493762fcSSteven Rostedt 
831493762fcSSteven Rostedt 	entry = debugfs_create_file("function_profile_enabled", 0644,
832493762fcSSteven Rostedt 				    d_tracer, NULL, &ftrace_profile_fops);
833493762fcSSteven Rostedt 	if (!entry)
834493762fcSSteven Rostedt 		pr_warning("Could not create debugfs "
835493762fcSSteven Rostedt 			   "'function_profile_enabled' entry\n");
836493762fcSSteven Rostedt }
837493762fcSSteven Rostedt 
838493762fcSSteven Rostedt #else /* CONFIG_FUNCTION_PROFILER */
8396ab5d668SSteven Rostedt static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
840493762fcSSteven Rostedt {
841493762fcSSteven Rostedt }
842493762fcSSteven Rostedt #endif /* CONFIG_FUNCTION_PROFILER */
843493762fcSSteven Rostedt 
84473d3fd96SIngo Molnar static struct pid * const ftrace_swapper_pid = &init_struct_pid;
84573d3fd96SIngo Molnar 
8463d083395SSteven Rostedt #ifdef CONFIG_DYNAMIC_FTRACE
84773d3fd96SIngo Molnar 
84899ecdc43SSteven Rostedt #ifndef CONFIG_FTRACE_MCOUNT_RECORD
849cb7be3b2SSteven Rostedt # error Dynamic ftrace depends on MCOUNT_RECORD
85099ecdc43SSteven Rostedt #endif
85199ecdc43SSteven Rostedt 
8528fc0c701SSteven Rostedt static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
8538fc0c701SSteven Rostedt 
854b6887d79SSteven Rostedt struct ftrace_func_probe {
8558fc0c701SSteven Rostedt 	struct hlist_node	node;
856b6887d79SSteven Rostedt 	struct ftrace_probe_ops	*ops;
8578fc0c701SSteven Rostedt 	unsigned long		flags;
8588fc0c701SSteven Rostedt 	unsigned long		ip;
8598fc0c701SSteven Rostedt 	void			*data;
8608fc0c701SSteven Rostedt 	struct rcu_head		rcu;
8618fc0c701SSteven Rostedt };
8628fc0c701SSteven Rostedt 
863d61f82d0SSteven Rostedt enum {
864d61f82d0SSteven Rostedt 	FTRACE_ENABLE_CALLS		= (1 << 0),
865d61f82d0SSteven Rostedt 	FTRACE_DISABLE_CALLS		= (1 << 1),
866d61f82d0SSteven Rostedt 	FTRACE_UPDATE_TRACE_FUNC	= (1 << 2),
86779e406d7SSteven Rostedt 	FTRACE_START_FUNC_RET		= (1 << 3),
86879e406d7SSteven Rostedt 	FTRACE_STOP_FUNC_RET		= (1 << 4),
869d61f82d0SSteven Rostedt };
870b448c4e3SSteven Rostedt struct ftrace_func_entry {
871b448c4e3SSteven Rostedt 	struct hlist_node hlist;
872b448c4e3SSteven Rostedt 	unsigned long ip;
873b448c4e3SSteven Rostedt };
874b448c4e3SSteven Rostedt 
875b448c4e3SSteven Rostedt struct ftrace_hash {
876b448c4e3SSteven Rostedt 	unsigned long		size_bits;
877b448c4e3SSteven Rostedt 	struct hlist_head	*buckets;
878b448c4e3SSteven Rostedt 	unsigned long		count;
879b448c4e3SSteven Rostedt };
880b448c4e3SSteven Rostedt 
88133dc9b12SSteven Rostedt /*
88233dc9b12SSteven Rostedt  * We make these constant because no one should touch them,
88333dc9b12SSteven Rostedt  * but they are used as the default "empty hash", to avoid allocating
88433dc9b12SSteven Rostedt  * it all the time. These are in a read only section such that if
88533dc9b12SSteven Rostedt  * anyone does try to modify it, it will cause an exception.
88633dc9b12SSteven Rostedt  */
88733dc9b12SSteven Rostedt static const struct hlist_head empty_buckets[1];
88833dc9b12SSteven Rostedt static const struct ftrace_hash empty_hash = {
88933dc9b12SSteven Rostedt 	.buckets = (struct hlist_head *)empty_buckets,
890b448c4e3SSteven Rostedt };
89133dc9b12SSteven Rostedt #define EMPTY_HASH	((struct ftrace_hash *)&empty_hash)
8925072c59fSSteven Rostedt 
893ed926f9bSSteven Rostedt enum {
894ed926f9bSSteven Rostedt 	FTRACE_OPS_FL_ENABLED		= 1,
895ed926f9bSSteven Rostedt };
896ed926f9bSSteven Rostedt 
897f45948e8SSteven Rostedt struct ftrace_ops global_ops = {
898f45948e8SSteven Rostedt 	.func			= ftrace_stub,
89933dc9b12SSteven Rostedt 	.notrace_hash		= EMPTY_HASH,
90033dc9b12SSteven Rostedt 	.filter_hash		= EMPTY_HASH,
901f45948e8SSteven Rostedt };
902f45948e8SSteven Rostedt 
903e94142a6SLai Jiangshan static struct dyn_ftrace *ftrace_new_addrs;
9043d083395SSteven Rostedt 
90541c52c0dSSteven Rostedt static DEFINE_MUTEX(ftrace_regex_lock);
9063d083395SSteven Rostedt 
9073c1720f0SSteven Rostedt struct ftrace_page {
9083c1720f0SSteven Rostedt 	struct ftrace_page	*next;
909431aa3fbSSteven Rostedt 	int			index;
9103c1720f0SSteven Rostedt 	struct dyn_ftrace	records[];
911aa5e5ceaSDavid Miller };
9123c1720f0SSteven Rostedt 
9133c1720f0SSteven Rostedt #define ENTRIES_PER_PAGE \
9143c1720f0SSteven Rostedt   ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
9153c1720f0SSteven Rostedt 
9163c1720f0SSteven Rostedt /* estimate from running different kernels */
9173c1720f0SSteven Rostedt #define NR_TO_INIT		10000
9183c1720f0SSteven Rostedt 
9193c1720f0SSteven Rostedt static struct ftrace_page	*ftrace_pages_start;
9203c1720f0SSteven Rostedt static struct ftrace_page	*ftrace_pages;
9213c1720f0SSteven Rostedt 
92237ad5084SSteven Rostedt static struct dyn_ftrace *ftrace_free_records;
92337ad5084SSteven Rostedt 
924b448c4e3SSteven Rostedt static struct ftrace_func_entry *
925b448c4e3SSteven Rostedt ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip)
926b448c4e3SSteven Rostedt {
927b448c4e3SSteven Rostedt 	unsigned long key;
928b448c4e3SSteven Rostedt 	struct ftrace_func_entry *entry;
929b448c4e3SSteven Rostedt 	struct hlist_head *hhd;
930b448c4e3SSteven Rostedt 	struct hlist_node *n;
931b448c4e3SSteven Rostedt 
932b448c4e3SSteven Rostedt 	if (!hash->count)
933b448c4e3SSteven Rostedt 		return NULL;
934b448c4e3SSteven Rostedt 
935b448c4e3SSteven Rostedt 	if (hash->size_bits > 0)
936b448c4e3SSteven Rostedt 		key = hash_long(ip, hash->size_bits);
937b448c4e3SSteven Rostedt 	else
938b448c4e3SSteven Rostedt 		key = 0;
939b448c4e3SSteven Rostedt 
940b448c4e3SSteven Rostedt 	hhd = &hash->buckets[key];
941b448c4e3SSteven Rostedt 
942b448c4e3SSteven Rostedt 	hlist_for_each_entry_rcu(entry, n, hhd, hlist) {
943b448c4e3SSteven Rostedt 		if (entry->ip == ip)
944b448c4e3SSteven Rostedt 			return entry;
945b448c4e3SSteven Rostedt 	}
946b448c4e3SSteven Rostedt 	return NULL;
947b448c4e3SSteven Rostedt }
948b448c4e3SSteven Rostedt 
94933dc9b12SSteven Rostedt static void __add_hash_entry(struct ftrace_hash *hash,
95033dc9b12SSteven Rostedt 			     struct ftrace_func_entry *entry)
95133dc9b12SSteven Rostedt {
95233dc9b12SSteven Rostedt 	struct hlist_head *hhd;
95333dc9b12SSteven Rostedt 	unsigned long key;
95433dc9b12SSteven Rostedt 
95533dc9b12SSteven Rostedt 	if (hash->size_bits)
95633dc9b12SSteven Rostedt 		key = hash_long(entry->ip, hash->size_bits);
95733dc9b12SSteven Rostedt 	else
95833dc9b12SSteven Rostedt 		key = 0;
95933dc9b12SSteven Rostedt 
96033dc9b12SSteven Rostedt 	hhd = &hash->buckets[key];
96133dc9b12SSteven Rostedt 	hlist_add_head(&entry->hlist, hhd);
96233dc9b12SSteven Rostedt 	hash->count++;
96333dc9b12SSteven Rostedt }
96433dc9b12SSteven Rostedt 
965b448c4e3SSteven Rostedt static int add_hash_entry(struct ftrace_hash *hash, unsigned long ip)
966b448c4e3SSteven Rostedt {
967b448c4e3SSteven Rostedt 	struct ftrace_func_entry *entry;
968b448c4e3SSteven Rostedt 
969b448c4e3SSteven Rostedt 	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
970b448c4e3SSteven Rostedt 	if (!entry)
971b448c4e3SSteven Rostedt 		return -ENOMEM;
972b448c4e3SSteven Rostedt 
973b448c4e3SSteven Rostedt 	entry->ip = ip;
97433dc9b12SSteven Rostedt 	__add_hash_entry(hash, entry);
975b448c4e3SSteven Rostedt 
976b448c4e3SSteven Rostedt 	return 0;
977b448c4e3SSteven Rostedt }
978b448c4e3SSteven Rostedt 
979b448c4e3SSteven Rostedt static void
98033dc9b12SSteven Rostedt free_hash_entry(struct ftrace_hash *hash,
98133dc9b12SSteven Rostedt 		  struct ftrace_func_entry *entry)
98233dc9b12SSteven Rostedt {
98333dc9b12SSteven Rostedt 	hlist_del(&entry->hlist);
98433dc9b12SSteven Rostedt 	kfree(entry);
98533dc9b12SSteven Rostedt 	hash->count--;
98633dc9b12SSteven Rostedt }
98733dc9b12SSteven Rostedt 
98833dc9b12SSteven Rostedt static void
989b448c4e3SSteven Rostedt remove_hash_entry(struct ftrace_hash *hash,
990b448c4e3SSteven Rostedt 		  struct ftrace_func_entry *entry)
991b448c4e3SSteven Rostedt {
992b448c4e3SSteven Rostedt 	hlist_del(&entry->hlist);
993b448c4e3SSteven Rostedt 	hash->count--;
994b448c4e3SSteven Rostedt }
995b448c4e3SSteven Rostedt 
996b448c4e3SSteven Rostedt static void ftrace_hash_clear(struct ftrace_hash *hash)
997b448c4e3SSteven Rostedt {
998b448c4e3SSteven Rostedt 	struct hlist_head *hhd;
999b448c4e3SSteven Rostedt 	struct hlist_node *tp, *tn;
1000b448c4e3SSteven Rostedt 	struct ftrace_func_entry *entry;
1001b448c4e3SSteven Rostedt 	int size = 1 << hash->size_bits;
1002b448c4e3SSteven Rostedt 	int i;
1003b448c4e3SSteven Rostedt 
100433dc9b12SSteven Rostedt 	if (!hash->count)
100533dc9b12SSteven Rostedt 		return;
100633dc9b12SSteven Rostedt 
1007b448c4e3SSteven Rostedt 	for (i = 0; i < size; i++) {
1008b448c4e3SSteven Rostedt 		hhd = &hash->buckets[i];
1009b448c4e3SSteven Rostedt 		hlist_for_each_entry_safe(entry, tp, tn, hhd, hlist)
101033dc9b12SSteven Rostedt 			free_hash_entry(hash, entry);
1011b448c4e3SSteven Rostedt 	}
1012b448c4e3SSteven Rostedt 	FTRACE_WARN_ON(hash->count);
1013b448c4e3SSteven Rostedt }
1014b448c4e3SSteven Rostedt 
101533dc9b12SSteven Rostedt static void free_ftrace_hash(struct ftrace_hash *hash)
101633dc9b12SSteven Rostedt {
101733dc9b12SSteven Rostedt 	if (!hash || hash == EMPTY_HASH)
101833dc9b12SSteven Rostedt 		return;
101933dc9b12SSteven Rostedt 	ftrace_hash_clear(hash);
102033dc9b12SSteven Rostedt 	kfree(hash->buckets);
102133dc9b12SSteven Rostedt 	kfree(hash);
102233dc9b12SSteven Rostedt }
102333dc9b12SSteven Rostedt 
102433dc9b12SSteven Rostedt static struct ftrace_hash *alloc_ftrace_hash(int size_bits)
102533dc9b12SSteven Rostedt {
102633dc9b12SSteven Rostedt 	struct ftrace_hash *hash;
102733dc9b12SSteven Rostedt 	int size;
102833dc9b12SSteven Rostedt 
102933dc9b12SSteven Rostedt 	hash = kzalloc(sizeof(*hash), GFP_KERNEL);
103033dc9b12SSteven Rostedt 	if (!hash)
103133dc9b12SSteven Rostedt 		return NULL;
103233dc9b12SSteven Rostedt 
103333dc9b12SSteven Rostedt 	size = 1 << size_bits;
103433dc9b12SSteven Rostedt 	hash->buckets = kzalloc(sizeof(*hash->buckets) * size, GFP_KERNEL);
103533dc9b12SSteven Rostedt 
103633dc9b12SSteven Rostedt 	if (!hash->buckets) {
103733dc9b12SSteven Rostedt 		kfree(hash);
103833dc9b12SSteven Rostedt 		return NULL;
103933dc9b12SSteven Rostedt 	}
104033dc9b12SSteven Rostedt 
104133dc9b12SSteven Rostedt 	hash->size_bits = size_bits;
104233dc9b12SSteven Rostedt 
104333dc9b12SSteven Rostedt 	return hash;
104433dc9b12SSteven Rostedt }
104533dc9b12SSteven Rostedt 
104633dc9b12SSteven Rostedt static struct ftrace_hash *
104733dc9b12SSteven Rostedt alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash)
104833dc9b12SSteven Rostedt {
104933dc9b12SSteven Rostedt 	struct ftrace_func_entry *entry;
105033dc9b12SSteven Rostedt 	struct ftrace_hash *new_hash;
105133dc9b12SSteven Rostedt 	struct hlist_node *tp;
105233dc9b12SSteven Rostedt 	int size;
105333dc9b12SSteven Rostedt 	int ret;
105433dc9b12SSteven Rostedt 	int i;
105533dc9b12SSteven Rostedt 
105633dc9b12SSteven Rostedt 	new_hash = alloc_ftrace_hash(size_bits);
105733dc9b12SSteven Rostedt 	if (!new_hash)
105833dc9b12SSteven Rostedt 		return NULL;
105933dc9b12SSteven Rostedt 
106033dc9b12SSteven Rostedt 	/* Empty hash? */
106133dc9b12SSteven Rostedt 	if (!hash || !hash->count)
106233dc9b12SSteven Rostedt 		return new_hash;
106333dc9b12SSteven Rostedt 
106433dc9b12SSteven Rostedt 	size = 1 << hash->size_bits;
106533dc9b12SSteven Rostedt 	for (i = 0; i < size; i++) {
106633dc9b12SSteven Rostedt 		hlist_for_each_entry(entry, tp, &hash->buckets[i], hlist) {
106733dc9b12SSteven Rostedt 			ret = add_hash_entry(new_hash, entry->ip);
106833dc9b12SSteven Rostedt 			if (ret < 0)
106933dc9b12SSteven Rostedt 				goto free_hash;
107033dc9b12SSteven Rostedt 		}
107133dc9b12SSteven Rostedt 	}
107233dc9b12SSteven Rostedt 
107333dc9b12SSteven Rostedt 	FTRACE_WARN_ON(new_hash->count != hash->count);
107433dc9b12SSteven Rostedt 
107533dc9b12SSteven Rostedt 	return new_hash;
107633dc9b12SSteven Rostedt 
107733dc9b12SSteven Rostedt  free_hash:
107833dc9b12SSteven Rostedt 	free_ftrace_hash(new_hash);
107933dc9b12SSteven Rostedt 	return NULL;
108033dc9b12SSteven Rostedt }
108133dc9b12SSteven Rostedt 
108233dc9b12SSteven Rostedt static int
108333dc9b12SSteven Rostedt ftrace_hash_move(struct ftrace_hash **dst, struct ftrace_hash *src)
108433dc9b12SSteven Rostedt {
108533dc9b12SSteven Rostedt 	struct ftrace_func_entry *entry;
108633dc9b12SSteven Rostedt 	struct hlist_node *tp, *tn;
108733dc9b12SSteven Rostedt 	struct hlist_head *hhd;
108833dc9b12SSteven Rostedt 	struct ftrace_hash *hash = *dst;
108933dc9b12SSteven Rostedt 	unsigned long key;
109033dc9b12SSteven Rostedt 	int size = src->count;
109133dc9b12SSteven Rostedt 	int bits = 0;
109233dc9b12SSteven Rostedt 	int i;
109333dc9b12SSteven Rostedt 
109433dc9b12SSteven Rostedt 	/*
109533dc9b12SSteven Rostedt 	 * If the new source is empty, just free dst and assign it
109633dc9b12SSteven Rostedt 	 * the empty_hash.
109733dc9b12SSteven Rostedt 	 */
109833dc9b12SSteven Rostedt 	if (!src->count) {
109933dc9b12SSteven Rostedt 		free_ftrace_hash(*dst);
110033dc9b12SSteven Rostedt 		*dst = EMPTY_HASH;
110133dc9b12SSteven Rostedt 		return 0;
110233dc9b12SSteven Rostedt 	}
110333dc9b12SSteven Rostedt 
110433dc9b12SSteven Rostedt 	ftrace_hash_clear(hash);
110533dc9b12SSteven Rostedt 
110633dc9b12SSteven Rostedt 	/*
110733dc9b12SSteven Rostedt 	 * Make the hash size about 1/2 the # found
110833dc9b12SSteven Rostedt 	 */
110933dc9b12SSteven Rostedt 	for (size /= 2; size; size >>= 1)
111033dc9b12SSteven Rostedt 		bits++;
111133dc9b12SSteven Rostedt 
111233dc9b12SSteven Rostedt 	/* Don't allocate too much */
111333dc9b12SSteven Rostedt 	if (bits > FTRACE_HASH_MAX_BITS)
111433dc9b12SSteven Rostedt 		bits = FTRACE_HASH_MAX_BITS;
111533dc9b12SSteven Rostedt 
111633dc9b12SSteven Rostedt 	/* We can't modify the empty_hash */
111733dc9b12SSteven Rostedt 	if (hash == EMPTY_HASH) {
111833dc9b12SSteven Rostedt 		/* Create a new hash */
111933dc9b12SSteven Rostedt 		*dst = alloc_ftrace_hash(bits);
112033dc9b12SSteven Rostedt 		if (!*dst) {
112133dc9b12SSteven Rostedt 			*dst = EMPTY_HASH;
112233dc9b12SSteven Rostedt 			return -ENOMEM;
112333dc9b12SSteven Rostedt 		}
112433dc9b12SSteven Rostedt 		hash = *dst;
112533dc9b12SSteven Rostedt 	} else {
112633dc9b12SSteven Rostedt 		size = 1 << bits;
112733dc9b12SSteven Rostedt 
112833dc9b12SSteven Rostedt 		/* Use the old hash, but create new buckets */
112933dc9b12SSteven Rostedt 		hhd = kzalloc(sizeof(*hhd) * size, GFP_KERNEL);
113033dc9b12SSteven Rostedt 		if (!hhd)
113133dc9b12SSteven Rostedt 			return -ENOMEM;
113233dc9b12SSteven Rostedt 
113333dc9b12SSteven Rostedt 		kfree(hash->buckets);
113433dc9b12SSteven Rostedt 		hash->buckets = hhd;
113533dc9b12SSteven Rostedt 		hash->size_bits = bits;
113633dc9b12SSteven Rostedt 	}
113733dc9b12SSteven Rostedt 
113833dc9b12SSteven Rostedt 	size = 1 << src->size_bits;
113933dc9b12SSteven Rostedt 	for (i = 0; i < size; i++) {
114033dc9b12SSteven Rostedt 		hhd = &src->buckets[i];
114133dc9b12SSteven Rostedt 		hlist_for_each_entry_safe(entry, tp, tn, hhd, hlist) {
114233dc9b12SSteven Rostedt 			if (bits > 0)
114333dc9b12SSteven Rostedt 				key = hash_long(entry->ip, bits);
114433dc9b12SSteven Rostedt 			else
114533dc9b12SSteven Rostedt 				key = 0;
114633dc9b12SSteven Rostedt 			remove_hash_entry(src, entry);
114733dc9b12SSteven Rostedt 			__add_hash_entry(hash, entry);
114833dc9b12SSteven Rostedt 		}
114933dc9b12SSteven Rostedt 	}
115033dc9b12SSteven Rostedt 
115133dc9b12SSteven Rostedt 	return 0;
115233dc9b12SSteven Rostedt }
115333dc9b12SSteven Rostedt 
1154265c831cSSteven Rostedt /*
1155265c831cSSteven Rostedt  * This is a double for. Do not use 'break' to break out of the loop,
1156265c831cSSteven Rostedt  * you must use a goto.
1157265c831cSSteven Rostedt  */
1158265c831cSSteven Rostedt #define do_for_each_ftrace_rec(pg, rec)					\
1159265c831cSSteven Rostedt 	for (pg = ftrace_pages_start; pg; pg = pg->next) {		\
1160265c831cSSteven Rostedt 		int _____i;						\
1161265c831cSSteven Rostedt 		for (_____i = 0; _____i < pg->index; _____i++) {	\
1162265c831cSSteven Rostedt 			rec = &pg->records[_____i];
1163265c831cSSteven Rostedt 
1164265c831cSSteven Rostedt #define while_for_each_ftrace_rec()		\
1165265c831cSSteven Rostedt 		}				\
1166265c831cSSteven Rostedt 	}
1167ecea656dSAbhishek Sagar 
1168ed926f9bSSteven Rostedt static void __ftrace_hash_rec_update(struct ftrace_ops *ops,
1169ed926f9bSSteven Rostedt 				     int filter_hash,
1170ed926f9bSSteven Rostedt 				     bool inc)
1171ed926f9bSSteven Rostedt {
1172ed926f9bSSteven Rostedt 	struct ftrace_hash *hash;
1173ed926f9bSSteven Rostedt 	struct ftrace_hash *other_hash;
1174ed926f9bSSteven Rostedt 	struct ftrace_page *pg;
1175ed926f9bSSteven Rostedt 	struct dyn_ftrace *rec;
1176ed926f9bSSteven Rostedt 	int count = 0;
1177ed926f9bSSteven Rostedt 	int all = 0;
1178ed926f9bSSteven Rostedt 
1179ed926f9bSSteven Rostedt 	/* Only update if the ops has been registered */
1180ed926f9bSSteven Rostedt 	if (!(ops->flags & FTRACE_OPS_FL_ENABLED))
1181ed926f9bSSteven Rostedt 		return;
1182ed926f9bSSteven Rostedt 
1183ed926f9bSSteven Rostedt 	/*
1184ed926f9bSSteven Rostedt 	 * In the filter_hash case:
1185ed926f9bSSteven Rostedt 	 *   If the count is zero, we update all records.
1186ed926f9bSSteven Rostedt 	 *   Otherwise we just update the items in the hash.
1187ed926f9bSSteven Rostedt 	 *
1188ed926f9bSSteven Rostedt 	 * In the notrace_hash case:
1189ed926f9bSSteven Rostedt 	 *   We enable the update in the hash.
1190ed926f9bSSteven Rostedt 	 *   As disabling notrace means enabling the tracing,
1191ed926f9bSSteven Rostedt 	 *   and enabling notrace means disabling, the inc variable
1192ed926f9bSSteven Rostedt 	 *   gets inversed.
1193ed926f9bSSteven Rostedt 	 */
1194ed926f9bSSteven Rostedt 	if (filter_hash) {
1195ed926f9bSSteven Rostedt 		hash = ops->filter_hash;
1196ed926f9bSSteven Rostedt 		other_hash = ops->notrace_hash;
1197ed926f9bSSteven Rostedt 		if (!hash->count)
1198ed926f9bSSteven Rostedt 			all = 1;
1199ed926f9bSSteven Rostedt 	} else {
1200ed926f9bSSteven Rostedt 		inc = !inc;
1201ed926f9bSSteven Rostedt 		hash = ops->notrace_hash;
1202ed926f9bSSteven Rostedt 		other_hash = ops->filter_hash;
1203ed926f9bSSteven Rostedt 		/*
1204ed926f9bSSteven Rostedt 		 * If the notrace hash has no items,
1205ed926f9bSSteven Rostedt 		 * then there's nothing to do.
1206ed926f9bSSteven Rostedt 		 */
1207ed926f9bSSteven Rostedt 		if (!hash->count)
1208ed926f9bSSteven Rostedt 			return;
1209ed926f9bSSteven Rostedt 	}
1210ed926f9bSSteven Rostedt 
1211ed926f9bSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
1212ed926f9bSSteven Rostedt 		int in_other_hash = 0;
1213ed926f9bSSteven Rostedt 		int in_hash = 0;
1214ed926f9bSSteven Rostedt 		int match = 0;
1215ed926f9bSSteven Rostedt 
1216ed926f9bSSteven Rostedt 		if (all) {
1217ed926f9bSSteven Rostedt 			/*
1218ed926f9bSSteven Rostedt 			 * Only the filter_hash affects all records.
1219ed926f9bSSteven Rostedt 			 * Update if the record is not in the notrace hash.
1220ed926f9bSSteven Rostedt 			 */
1221ed926f9bSSteven Rostedt 			if (!ftrace_lookup_ip(other_hash, rec->ip))
1222ed926f9bSSteven Rostedt 				match = 1;
1223ed926f9bSSteven Rostedt 		} else {
1224ed926f9bSSteven Rostedt 			in_hash = !!ftrace_lookup_ip(hash, rec->ip);
1225ed926f9bSSteven Rostedt 			in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip);
1226ed926f9bSSteven Rostedt 
1227ed926f9bSSteven Rostedt 			/*
1228ed926f9bSSteven Rostedt 			 *
1229ed926f9bSSteven Rostedt 			 */
1230ed926f9bSSteven Rostedt 			if (filter_hash && in_hash && !in_other_hash)
1231ed926f9bSSteven Rostedt 				match = 1;
1232ed926f9bSSteven Rostedt 			else if (!filter_hash && in_hash &&
1233ed926f9bSSteven Rostedt 				 (in_other_hash || !other_hash->count))
1234ed926f9bSSteven Rostedt 				match = 1;
1235ed926f9bSSteven Rostedt 		}
1236ed926f9bSSteven Rostedt 		if (!match)
1237ed926f9bSSteven Rostedt 			continue;
1238ed926f9bSSteven Rostedt 
1239ed926f9bSSteven Rostedt 		if (inc) {
1240ed926f9bSSteven Rostedt 			rec->flags++;
1241ed926f9bSSteven Rostedt 			if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == FTRACE_REF_MAX))
1242ed926f9bSSteven Rostedt 				return;
1243ed926f9bSSteven Rostedt 		} else {
1244ed926f9bSSteven Rostedt 			if (FTRACE_WARN_ON((rec->flags & ~FTRACE_FL_MASK) == 0))
1245ed926f9bSSteven Rostedt 				return;
1246ed926f9bSSteven Rostedt 			rec->flags--;
1247ed926f9bSSteven Rostedt 		}
1248ed926f9bSSteven Rostedt 		count++;
1249ed926f9bSSteven Rostedt 		/* Shortcut, if we handled all records, we are done. */
1250ed926f9bSSteven Rostedt 		if (!all && count == hash->count)
1251ed926f9bSSteven Rostedt 			return;
1252ed926f9bSSteven Rostedt 	} while_for_each_ftrace_rec();
1253ed926f9bSSteven Rostedt }
1254ed926f9bSSteven Rostedt 
1255ed926f9bSSteven Rostedt static void ftrace_hash_rec_disable(struct ftrace_ops *ops,
1256ed926f9bSSteven Rostedt 				    int filter_hash)
1257ed926f9bSSteven Rostedt {
1258ed926f9bSSteven Rostedt 	__ftrace_hash_rec_update(ops, filter_hash, 0);
1259ed926f9bSSteven Rostedt }
1260ed926f9bSSteven Rostedt 
1261ed926f9bSSteven Rostedt static void ftrace_hash_rec_enable(struct ftrace_ops *ops,
1262ed926f9bSSteven Rostedt 				   int filter_hash)
1263ed926f9bSSteven Rostedt {
1264ed926f9bSSteven Rostedt 	__ftrace_hash_rec_update(ops, filter_hash, 1);
1265ed926f9bSSteven Rostedt }
1266ed926f9bSSteven Rostedt 
1267e309b41dSIngo Molnar static void ftrace_free_rec(struct dyn_ftrace *rec)
126837ad5084SSteven Rostedt {
1269ee000b7fSLai Jiangshan 	rec->freelist = ftrace_free_records;
127037ad5084SSteven Rostedt 	ftrace_free_records = rec;
127137ad5084SSteven Rostedt 	rec->flags |= FTRACE_FL_FREE;
127237ad5084SSteven Rostedt }
127337ad5084SSteven Rostedt 
1274e309b41dSIngo Molnar static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
12753c1720f0SSteven Rostedt {
127637ad5084SSteven Rostedt 	struct dyn_ftrace *rec;
127737ad5084SSteven Rostedt 
127837ad5084SSteven Rostedt 	/* First check for freed records */
127937ad5084SSteven Rostedt 	if (ftrace_free_records) {
128037ad5084SSteven Rostedt 		rec = ftrace_free_records;
128137ad5084SSteven Rostedt 
128237ad5084SSteven Rostedt 		if (unlikely(!(rec->flags & FTRACE_FL_FREE))) {
12836912896eSSteven Rostedt 			FTRACE_WARN_ON_ONCE(1);
128437ad5084SSteven Rostedt 			ftrace_free_records = NULL;
128537ad5084SSteven Rostedt 			return NULL;
128637ad5084SSteven Rostedt 		}
128737ad5084SSteven Rostedt 
1288ee000b7fSLai Jiangshan 		ftrace_free_records = rec->freelist;
128937ad5084SSteven Rostedt 		memset(rec, 0, sizeof(*rec));
129037ad5084SSteven Rostedt 		return rec;
129137ad5084SSteven Rostedt 	}
129237ad5084SSteven Rostedt 
12933c1720f0SSteven Rostedt 	if (ftrace_pages->index == ENTRIES_PER_PAGE) {
129408f5ac90SSteven Rostedt 		if (!ftrace_pages->next) {
129508f5ac90SSteven Rostedt 			/* allocate another page */
129608f5ac90SSteven Rostedt 			ftrace_pages->next =
129708f5ac90SSteven Rostedt 				(void *)get_zeroed_page(GFP_KERNEL);
12983c1720f0SSteven Rostedt 			if (!ftrace_pages->next)
12993c1720f0SSteven Rostedt 				return NULL;
130008f5ac90SSteven Rostedt 		}
13013c1720f0SSteven Rostedt 		ftrace_pages = ftrace_pages->next;
13023c1720f0SSteven Rostedt 	}
13033c1720f0SSteven Rostedt 
13043c1720f0SSteven Rostedt 	return &ftrace_pages->records[ftrace_pages->index++];
13053c1720f0SSteven Rostedt }
13063c1720f0SSteven Rostedt 
130708f5ac90SSteven Rostedt static struct dyn_ftrace *
1308d61f82d0SSteven Rostedt ftrace_record_ip(unsigned long ip)
13093d083395SSteven Rostedt {
131008f5ac90SSteven Rostedt 	struct dyn_ftrace *rec;
13113d083395SSteven Rostedt 
1312f3c7ac40SSteven Rostedt 	if (ftrace_disabled)
131308f5ac90SSteven Rostedt 		return NULL;
1314d61f82d0SSteven Rostedt 
131508f5ac90SSteven Rostedt 	rec = ftrace_alloc_dyn_node(ip);
131608f5ac90SSteven Rostedt 	if (!rec)
131708f5ac90SSteven Rostedt 		return NULL;
13183d083395SSteven Rostedt 
131908f5ac90SSteven Rostedt 	rec->ip = ip;
1320ee000b7fSLai Jiangshan 	rec->newlist = ftrace_new_addrs;
1321e94142a6SLai Jiangshan 	ftrace_new_addrs = rec;
13223d083395SSteven Rostedt 
132308f5ac90SSteven Rostedt 	return rec;
13243d083395SSteven Rostedt }
13253d083395SSteven Rostedt 
132605736a42SSteven Rostedt static void print_ip_ins(const char *fmt, unsigned char *p)
132705736a42SSteven Rostedt {
132805736a42SSteven Rostedt 	int i;
132905736a42SSteven Rostedt 
133005736a42SSteven Rostedt 	printk(KERN_CONT "%s", fmt);
133105736a42SSteven Rostedt 
133205736a42SSteven Rostedt 	for (i = 0; i < MCOUNT_INSN_SIZE; i++)
133305736a42SSteven Rostedt 		printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
133405736a42SSteven Rostedt }
133505736a42SSteven Rostedt 
133631e88909SSteven Rostedt static void ftrace_bug(int failed, unsigned long ip)
13373c1720f0SSteven Rostedt {
1338b17e8a37SSteven Rostedt 	switch (failed) {
1339593eb8a2SSteven Rostedt 	case -EFAULT:
13406912896eSSteven Rostedt 		FTRACE_WARN_ON_ONCE(1);
134105736a42SSteven Rostedt 		pr_info("ftrace faulted on modifying ");
134205736a42SSteven Rostedt 		print_ip_sym(ip);
134305736a42SSteven Rostedt 		break;
1344593eb8a2SSteven Rostedt 	case -EINVAL:
13456912896eSSteven Rostedt 		FTRACE_WARN_ON_ONCE(1);
134605736a42SSteven Rostedt 		pr_info("ftrace failed to modify ");
134705736a42SSteven Rostedt 		print_ip_sym(ip);
134805736a42SSteven Rostedt 		print_ip_ins(" actual: ", (unsigned char *)ip);
134905736a42SSteven Rostedt 		printk(KERN_CONT "\n");
135005736a42SSteven Rostedt 		break;
1351593eb8a2SSteven Rostedt 	case -EPERM:
13526912896eSSteven Rostedt 		FTRACE_WARN_ON_ONCE(1);
1353593eb8a2SSteven Rostedt 		pr_info("ftrace faulted on writing ");
1354593eb8a2SSteven Rostedt 		print_ip_sym(ip);
1355593eb8a2SSteven Rostedt 		break;
1356593eb8a2SSteven Rostedt 	default:
13576912896eSSteven Rostedt 		FTRACE_WARN_ON_ONCE(1);
1358593eb8a2SSteven Rostedt 		pr_info("ftrace faulted on unknown error ");
1359593eb8a2SSteven Rostedt 		print_ip_sym(ip);
136005736a42SSteven Rostedt 	}
1361b17e8a37SSteven Rostedt }
136205736a42SSteven Rostedt 
13633d083395SSteven Rostedt 
13642cfa1978SMasami Hiramatsu /* Return 1 if the address range is reserved for ftrace */
13652cfa1978SMasami Hiramatsu int ftrace_text_reserved(void *start, void *end)
13662cfa1978SMasami Hiramatsu {
13672cfa1978SMasami Hiramatsu 	struct dyn_ftrace *rec;
13682cfa1978SMasami Hiramatsu 	struct ftrace_page *pg;
13692cfa1978SMasami Hiramatsu 
13702cfa1978SMasami Hiramatsu 	do_for_each_ftrace_rec(pg, rec) {
13712cfa1978SMasami Hiramatsu 		if (rec->ip <= (unsigned long)end &&
13722cfa1978SMasami Hiramatsu 		    rec->ip + MCOUNT_INSN_SIZE > (unsigned long)start)
13732cfa1978SMasami Hiramatsu 			return 1;
13742cfa1978SMasami Hiramatsu 	} while_for_each_ftrace_rec();
13752cfa1978SMasami Hiramatsu 	return 0;
13762cfa1978SMasami Hiramatsu }
13772cfa1978SMasami Hiramatsu 
13782cfa1978SMasami Hiramatsu 
13793d083395SSteven Rostedt static int
138031e88909SSteven Rostedt __ftrace_replace_code(struct dyn_ftrace *rec, int enable)
13813d083395SSteven Rostedt {
1382e7d3737eSFrederic Weisbecker 	unsigned long ftrace_addr;
138364fbcd16SXiao Guangrong 	unsigned long flag = 0UL;
1384e7d3737eSFrederic Weisbecker 
1385f0001207SShaohua Li 	ftrace_addr = (unsigned long)FTRACE_ADDR;
13863d083395SSteven Rostedt 
13873d083395SSteven Rostedt 	/*
1388ed926f9bSSteven Rostedt 	 * If we are enabling tracing:
13893d083395SSteven Rostedt 	 *
1390ed926f9bSSteven Rostedt 	 *   If the record has a ref count, then we need to enable it
1391ed926f9bSSteven Rostedt 	 *   because someone is using it.
13923d083395SSteven Rostedt 	 *
1393ed926f9bSSteven Rostedt 	 *   Otherwise we make sure its disabled.
1394ed926f9bSSteven Rostedt 	 *
1395ed926f9bSSteven Rostedt 	 * If we are disabling tracing, then disable all records that
1396ed926f9bSSteven Rostedt 	 * are enabled.
13973d083395SSteven Rostedt 	 */
1398ed926f9bSSteven Rostedt 	if (enable && (rec->flags & ~FTRACE_FL_MASK))
139964fbcd16SXiao Guangrong 		flag = FTRACE_FL_ENABLED;
14003d083395SSteven Rostedt 
140164fbcd16SXiao Guangrong 	/* If the state of this record hasn't changed, then do nothing */
140264fbcd16SXiao Guangrong 	if ((rec->flags & FTRACE_FL_ENABLED) == flag)
140364fbcd16SXiao Guangrong 		return 0;
140464fbcd16SXiao Guangrong 
140564fbcd16SXiao Guangrong 	if (flag) {
140664fbcd16SXiao Guangrong 		rec->flags |= FTRACE_FL_ENABLED;
1407e7d3737eSFrederic Weisbecker 		return ftrace_make_call(rec, ftrace_addr);
140864fbcd16SXiao Guangrong 	}
140964fbcd16SXiao Guangrong 
141064fbcd16SXiao Guangrong 	rec->flags &= ~FTRACE_FL_ENABLED;
1411e7d3737eSFrederic Weisbecker 	return ftrace_make_nop(NULL, rec, ftrace_addr);
14123d083395SSteven Rostedt }
14133d083395SSteven Rostedt 
14143d083395SSteven Rostedt static void ftrace_replace_code(int enable)
14153d083395SSteven Rostedt {
14163d083395SSteven Rostedt 	struct dyn_ftrace *rec;
14173d083395SSteven Rostedt 	struct ftrace_page *pg;
14186a24a244SSteven Rostedt 	int failed;
14193d083395SSteven Rostedt 
142045a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
142145a4a237SSteven Rostedt 		return;
142245a4a237SSteven Rostedt 
1423265c831cSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
1424d2c8c3eaSSteven Rostedt 		/* Skip over free records */
1425d2c8c3eaSSteven Rostedt 		if (rec->flags & FTRACE_FL_FREE)
14263d083395SSteven Rostedt 			continue;
14273d083395SSteven Rostedt 
142831e88909SSteven Rostedt 		failed = __ftrace_replace_code(rec, enable);
1429fa9d13cfSZhaolei 		if (failed) {
143031e88909SSteven Rostedt 			ftrace_bug(failed, rec->ip);
14314377245aSSteven Rostedt 			/* Stop processing */
14324377245aSSteven Rostedt 			return;
14334377245aSSteven Rostedt 		}
1434265c831cSSteven Rostedt 	} while_for_each_ftrace_rec();
14353d083395SSteven Rostedt }
14363c1720f0SSteven Rostedt 
14373b47bfc1SSteven Rostedt static int
143831e88909SSteven Rostedt ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
14393c1720f0SSteven Rostedt {
144037ad5084SSteven Rostedt 	unsigned long ip;
1441492a7ea5SAbhishek Sagar 	int ret;
144237ad5084SSteven Rostedt 
1443492a7ea5SAbhishek Sagar 	ip = rec->ip;
14443c1720f0SSteven Rostedt 
144545a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
144645a4a237SSteven Rostedt 		return 0;
144745a4a237SSteven Rostedt 
144825aac9dcSShaohua Li 	ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
14493d083395SSteven Rostedt 	if (ret) {
145031e88909SSteven Rostedt 		ftrace_bug(ret, ip);
14513d083395SSteven Rostedt 		return 0;
1452d61f82d0SSteven Rostedt 	}
1453d61f82d0SSteven Rostedt 	return 1;
14543d083395SSteven Rostedt }
14553d083395SSteven Rostedt 
1456000ab691SSteven Rostedt /*
1457000ab691SSteven Rostedt  * archs can override this function if they must do something
1458000ab691SSteven Rostedt  * before the modifying code is performed.
1459000ab691SSteven Rostedt  */
1460000ab691SSteven Rostedt int __weak ftrace_arch_code_modify_prepare(void)
1461000ab691SSteven Rostedt {
1462000ab691SSteven Rostedt 	return 0;
1463000ab691SSteven Rostedt }
1464000ab691SSteven Rostedt 
1465000ab691SSteven Rostedt /*
1466000ab691SSteven Rostedt  * archs can override this function if they must do something
1467000ab691SSteven Rostedt  * after the modifying code is performed.
1468000ab691SSteven Rostedt  */
1469000ab691SSteven Rostedt int __weak ftrace_arch_code_modify_post_process(void)
1470000ab691SSteven Rostedt {
1471000ab691SSteven Rostedt 	return 0;
1472000ab691SSteven Rostedt }
1473000ab691SSteven Rostedt 
14743d083395SSteven Rostedt static int __ftrace_modify_code(void *data)
14753d083395SSteven Rostedt {
14763d083395SSteven Rostedt 	int *command = data;
14773d083395SSteven Rostedt 
1478a3583244SSteven Rostedt 	if (*command & FTRACE_ENABLE_CALLS)
14793d083395SSteven Rostedt 		ftrace_replace_code(1);
1480a3583244SSteven Rostedt 	else if (*command & FTRACE_DISABLE_CALLS)
14813d083395SSteven Rostedt 		ftrace_replace_code(0);
14823d083395SSteven Rostedt 
14833d083395SSteven Rostedt 	if (*command & FTRACE_UPDATE_TRACE_FUNC)
14843d083395SSteven Rostedt 		ftrace_update_ftrace_func(ftrace_trace_function);
14853d083395SSteven Rostedt 
14865a45cfe1SSteven Rostedt 	if (*command & FTRACE_START_FUNC_RET)
14875a45cfe1SSteven Rostedt 		ftrace_enable_ftrace_graph_caller();
14885a45cfe1SSteven Rostedt 	else if (*command & FTRACE_STOP_FUNC_RET)
14895a45cfe1SSteven Rostedt 		ftrace_disable_ftrace_graph_caller();
14905a45cfe1SSteven Rostedt 
14913d083395SSteven Rostedt 	return 0;
14923d083395SSteven Rostedt }
14933d083395SSteven Rostedt 
1494e309b41dSIngo Molnar static void ftrace_run_update_code(int command)
14953d083395SSteven Rostedt {
1496000ab691SSteven Rostedt 	int ret;
1497000ab691SSteven Rostedt 
1498000ab691SSteven Rostedt 	ret = ftrace_arch_code_modify_prepare();
1499000ab691SSteven Rostedt 	FTRACE_WARN_ON(ret);
1500000ab691SSteven Rostedt 	if (ret)
1501000ab691SSteven Rostedt 		return;
1502000ab691SSteven Rostedt 
1503784e2d76SRusty Russell 	stop_machine(__ftrace_modify_code, &command, NULL);
1504000ab691SSteven Rostedt 
1505000ab691SSteven Rostedt 	ret = ftrace_arch_code_modify_post_process();
1506000ab691SSteven Rostedt 	FTRACE_WARN_ON(ret);
15073d083395SSteven Rostedt }
15083d083395SSteven Rostedt 
15093d083395SSteven Rostedt static ftrace_func_t saved_ftrace_func;
151060a7ecf4SSteven Rostedt static int ftrace_start_up;
1511df4fc315SSteven Rostedt 
1512df4fc315SSteven Rostedt static void ftrace_startup_enable(int command)
1513df4fc315SSteven Rostedt {
1514df4fc315SSteven Rostedt 	if (saved_ftrace_func != ftrace_trace_function) {
1515df4fc315SSteven Rostedt 		saved_ftrace_func = ftrace_trace_function;
1516df4fc315SSteven Rostedt 		command |= FTRACE_UPDATE_TRACE_FUNC;
1517df4fc315SSteven Rostedt 	}
1518df4fc315SSteven Rostedt 
1519df4fc315SSteven Rostedt 	if (!command || !ftrace_enabled)
1520df4fc315SSteven Rostedt 		return;
1521df4fc315SSteven Rostedt 
1522df4fc315SSteven Rostedt 	ftrace_run_update_code(command);
1523df4fc315SSteven Rostedt }
15243d083395SSteven Rostedt 
1525*bd69c30bSSteven Rostedt static void ftrace_startup(struct ftrace_ops *ops, int command)
15263d083395SSteven Rostedt {
15274eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
15284eebcc81SSteven Rostedt 		return;
15294eebcc81SSteven Rostedt 
153060a7ecf4SSteven Rostedt 	ftrace_start_up++;
1531d61f82d0SSteven Rostedt 	command |= FTRACE_ENABLE_CALLS;
15323d083395SSteven Rostedt 
1533ed926f9bSSteven Rostedt 	ops->flags |= FTRACE_OPS_FL_ENABLED;
1534ed926f9bSSteven Rostedt 	if (ftrace_start_up == 1)
1535ed926f9bSSteven Rostedt 		ftrace_hash_rec_enable(ops, 1);
1536ed926f9bSSteven Rostedt 
1537df4fc315SSteven Rostedt 	ftrace_startup_enable(command);
15383d083395SSteven Rostedt }
15393d083395SSteven Rostedt 
1540*bd69c30bSSteven Rostedt static void ftrace_shutdown(struct ftrace_ops *ops, int command)
15413d083395SSteven Rostedt {
15424eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
15434eebcc81SSteven Rostedt 		return;
15444eebcc81SSteven Rostedt 
154560a7ecf4SSteven Rostedt 	ftrace_start_up--;
15469ea1a153SFrederic Weisbecker 	/*
15479ea1a153SFrederic Weisbecker 	 * Just warn in case of unbalance, no need to kill ftrace, it's not
15489ea1a153SFrederic Weisbecker 	 * critical but the ftrace_call callers may be never nopped again after
15499ea1a153SFrederic Weisbecker 	 * further ftrace uses.
15509ea1a153SFrederic Weisbecker 	 */
15519ea1a153SFrederic Weisbecker 	WARN_ON_ONCE(ftrace_start_up < 0);
15529ea1a153SFrederic Weisbecker 
155360a7ecf4SSteven Rostedt 	if (!ftrace_start_up)
1554ed926f9bSSteven Rostedt 		ftrace_hash_rec_disable(ops, 1);
1555ed926f9bSSteven Rostedt 
1556ed926f9bSSteven Rostedt 	if (!ftrace_start_up) {
1557d61f82d0SSteven Rostedt 		command |= FTRACE_DISABLE_CALLS;
1558ed926f9bSSteven Rostedt 		ops->flags &= ~FTRACE_OPS_FL_ENABLED;
1559ed926f9bSSteven Rostedt 	}
1560d61f82d0SSteven Rostedt 
1561d61f82d0SSteven Rostedt 	if (saved_ftrace_func != ftrace_trace_function) {
1562d61f82d0SSteven Rostedt 		saved_ftrace_func = ftrace_trace_function;
1563d61f82d0SSteven Rostedt 		command |= FTRACE_UPDATE_TRACE_FUNC;
1564d61f82d0SSteven Rostedt 	}
1565d61f82d0SSteven Rostedt 
1566d61f82d0SSteven Rostedt 	if (!command || !ftrace_enabled)
1567e6ea44e9SSteven Rostedt 		return;
15683d083395SSteven Rostedt 
1569d61f82d0SSteven Rostedt 	ftrace_run_update_code(command);
15703d083395SSteven Rostedt }
15713d083395SSteven Rostedt 
1572e309b41dSIngo Molnar static void ftrace_startup_sysctl(void)
1573b0fc494fSSteven Rostedt {
15744eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
15754eebcc81SSteven Rostedt 		return;
15764eebcc81SSteven Rostedt 
1577d61f82d0SSteven Rostedt 	/* Force update next time */
1578d61f82d0SSteven Rostedt 	saved_ftrace_func = NULL;
157960a7ecf4SSteven Rostedt 	/* ftrace_start_up is true if we want ftrace running */
158060a7ecf4SSteven Rostedt 	if (ftrace_start_up)
158179e406d7SSteven Rostedt 		ftrace_run_update_code(FTRACE_ENABLE_CALLS);
1582b0fc494fSSteven Rostedt }
1583b0fc494fSSteven Rostedt 
1584e309b41dSIngo Molnar static void ftrace_shutdown_sysctl(void)
1585b0fc494fSSteven Rostedt {
15864eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
15874eebcc81SSteven Rostedt 		return;
15884eebcc81SSteven Rostedt 
158960a7ecf4SSteven Rostedt 	/* ftrace_start_up is true if ftrace is running */
159060a7ecf4SSteven Rostedt 	if (ftrace_start_up)
159179e406d7SSteven Rostedt 		ftrace_run_update_code(FTRACE_DISABLE_CALLS);
1592b0fc494fSSteven Rostedt }
1593b0fc494fSSteven Rostedt 
15943d083395SSteven Rostedt static cycle_t		ftrace_update_time;
15953d083395SSteven Rostedt static unsigned long	ftrace_update_cnt;
15963d083395SSteven Rostedt unsigned long		ftrace_update_tot_cnt;
15973d083395SSteven Rostedt 
159831e88909SSteven Rostedt static int ftrace_update_code(struct module *mod)
15993d083395SSteven Rostedt {
1600e94142a6SLai Jiangshan 	struct dyn_ftrace *p;
1601f22f9a89SAbhishek Sagar 	cycle_t start, stop;
16023d083395SSteven Rostedt 
1603750ed1a4SIngo Molnar 	start = ftrace_now(raw_smp_processor_id());
16043d083395SSteven Rostedt 	ftrace_update_cnt = 0;
16053d083395SSteven Rostedt 
1606e94142a6SLai Jiangshan 	while (ftrace_new_addrs) {
1607f22f9a89SAbhishek Sagar 
160808f5ac90SSteven Rostedt 		/* If something went wrong, bail without enabling anything */
160908f5ac90SSteven Rostedt 		if (unlikely(ftrace_disabled))
161008f5ac90SSteven Rostedt 			return -1;
16113d083395SSteven Rostedt 
1612e94142a6SLai Jiangshan 		p = ftrace_new_addrs;
1613ee000b7fSLai Jiangshan 		ftrace_new_addrs = p->newlist;
1614e94142a6SLai Jiangshan 		p->flags = 0L;
1615f22f9a89SAbhishek Sagar 
16165cb084bbSJiri Olsa 		/*
161725985edcSLucas De Marchi 		 * Do the initial record conversion from mcount jump
16185cb084bbSJiri Olsa 		 * to the NOP instructions.
16195cb084bbSJiri Olsa 		 */
16205cb084bbSJiri Olsa 		if (!ftrace_code_disable(mod, p)) {
16215cb084bbSJiri Olsa 			ftrace_free_rec(p);
1622d2c8c3eaSSteven Rostedt 			/* Game over */
1623d2c8c3eaSSteven Rostedt 			break;
16245cb084bbSJiri Olsa 		}
16255cb084bbSJiri Olsa 
16263d083395SSteven Rostedt 		ftrace_update_cnt++;
16275cb084bbSJiri Olsa 
16285cb084bbSJiri Olsa 		/*
16295cb084bbSJiri Olsa 		 * If the tracing is enabled, go ahead and enable the record.
16305cb084bbSJiri Olsa 		 *
16315cb084bbSJiri Olsa 		 * The reason not to enable the record immediatelly is the
16325cb084bbSJiri Olsa 		 * inherent check of ftrace_make_nop/ftrace_make_call for
16335cb084bbSJiri Olsa 		 * correct previous instructions.  Making first the NOP
16345cb084bbSJiri Olsa 		 * conversion puts the module to the correct state, thus
16355cb084bbSJiri Olsa 		 * passing the ftrace_make_call check.
16365cb084bbSJiri Olsa 		 */
16375cb084bbSJiri Olsa 		if (ftrace_start_up) {
16385cb084bbSJiri Olsa 			int failed = __ftrace_replace_code(p, 1);
16395cb084bbSJiri Olsa 			if (failed) {
16405cb084bbSJiri Olsa 				ftrace_bug(failed, p->ip);
16410eb96701SAbhishek Sagar 				ftrace_free_rec(p);
16423d083395SSteven Rostedt 			}
16435cb084bbSJiri Olsa 		}
16445cb084bbSJiri Olsa 	}
16453d083395SSteven Rostedt 
1646750ed1a4SIngo Molnar 	stop = ftrace_now(raw_smp_processor_id());
16473d083395SSteven Rostedt 	ftrace_update_time = stop - start;
16483d083395SSteven Rostedt 	ftrace_update_tot_cnt += ftrace_update_cnt;
16493d083395SSteven Rostedt 
165016444a8aSArnaldo Carvalho de Melo 	return 0;
165116444a8aSArnaldo Carvalho de Melo }
165216444a8aSArnaldo Carvalho de Melo 
165368bf21aaSSteven Rostedt static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
16543c1720f0SSteven Rostedt {
16553c1720f0SSteven Rostedt 	struct ftrace_page *pg;
16563c1720f0SSteven Rostedt 	int cnt;
16573c1720f0SSteven Rostedt 	int i;
16583c1720f0SSteven Rostedt 
16593c1720f0SSteven Rostedt 	/* allocate a few pages */
16603c1720f0SSteven Rostedt 	ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
16613c1720f0SSteven Rostedt 	if (!ftrace_pages_start)
16623c1720f0SSteven Rostedt 		return -1;
16633c1720f0SSteven Rostedt 
16643c1720f0SSteven Rostedt 	/*
16653c1720f0SSteven Rostedt 	 * Allocate a few more pages.
16663c1720f0SSteven Rostedt 	 *
16673c1720f0SSteven Rostedt 	 * TODO: have some parser search vmlinux before
16683c1720f0SSteven Rostedt 	 *   final linking to find all calls to ftrace.
16693c1720f0SSteven Rostedt 	 *   Then we can:
16703c1720f0SSteven Rostedt 	 *    a) know how many pages to allocate.
16713c1720f0SSteven Rostedt 	 *     and/or
16723c1720f0SSteven Rostedt 	 *    b) set up the table then.
16733c1720f0SSteven Rostedt 	 *
16743c1720f0SSteven Rostedt 	 *  The dynamic code is still necessary for
16753c1720f0SSteven Rostedt 	 *  modules.
16763c1720f0SSteven Rostedt 	 */
16773c1720f0SSteven Rostedt 
16783c1720f0SSteven Rostedt 	pg = ftrace_pages = ftrace_pages_start;
16793c1720f0SSteven Rostedt 
168068bf21aaSSteven Rostedt 	cnt = num_to_init / ENTRIES_PER_PAGE;
168108f5ac90SSteven Rostedt 	pr_info("ftrace: allocating %ld entries in %d pages\n",
16825821e1b7Swalimis 		num_to_init, cnt + 1);
16833c1720f0SSteven Rostedt 
16843c1720f0SSteven Rostedt 	for (i = 0; i < cnt; i++) {
16853c1720f0SSteven Rostedt 		pg->next = (void *)get_zeroed_page(GFP_KERNEL);
16863c1720f0SSteven Rostedt 
16873c1720f0SSteven Rostedt 		/* If we fail, we'll try later anyway */
16883c1720f0SSteven Rostedt 		if (!pg->next)
16893c1720f0SSteven Rostedt 			break;
16903c1720f0SSteven Rostedt 
16913c1720f0SSteven Rostedt 		pg = pg->next;
16923c1720f0SSteven Rostedt 	}
16933c1720f0SSteven Rostedt 
16943c1720f0SSteven Rostedt 	return 0;
16953c1720f0SSteven Rostedt }
16963c1720f0SSteven Rostedt 
16975072c59fSSteven Rostedt enum {
16985072c59fSSteven Rostedt 	FTRACE_ITER_FILTER	= (1 << 0),
1699689fd8b6S[email protected] 	FTRACE_ITER_NOTRACE	= (1 << 1),
17003499e461SSteven Rostedt 	FTRACE_ITER_PRINTALL	= (1 << 2),
17013499e461SSteven Rostedt 	FTRACE_ITER_HASH	= (1 << 3),
1702647bcd03SSteven Rostedt 	FTRACE_ITER_ENABLED	= (1 << 4),
17035072c59fSSteven Rostedt };
17045072c59fSSteven Rostedt 
17055072c59fSSteven Rostedt #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
17065072c59fSSteven Rostedt 
17075072c59fSSteven Rostedt struct ftrace_iterator {
170898c4fd04SSteven Rostedt 	loff_t				pos;
17092bccfffdSSteven Rostedt 	loff_t				func_pos;
17105072c59fSSteven Rostedt 	struct ftrace_page		*pg;
17114aeb6967SSteven Rostedt 	struct dyn_ftrace		*func;
17124aeb6967SSteven Rostedt 	struct ftrace_func_probe	*probe;
17134aeb6967SSteven Rostedt 	struct trace_parser		parser;
17141cf41dd7SSteven Rostedt 	struct ftrace_hash		*hash;
171533dc9b12SSteven Rostedt 	struct ftrace_ops		*ops;
17168fc0c701SSteven Rostedt 	int				hidx;
1717431aa3fbSSteven Rostedt 	int				idx;
17185072c59fSSteven Rostedt 	unsigned			flags;
17195072c59fSSteven Rostedt };
17205072c59fSSteven Rostedt 
1721e309b41dSIngo Molnar static void *
17224aeb6967SSteven Rostedt t_hash_next(struct seq_file *m, loff_t *pos)
17238fc0c701SSteven Rostedt {
17248fc0c701SSteven Rostedt 	struct ftrace_iterator *iter = m->private;
17254aeb6967SSteven Rostedt 	struct hlist_node *hnd = NULL;
17268fc0c701SSteven Rostedt 	struct hlist_head *hhd;
17278fc0c701SSteven Rostedt 
17288fc0c701SSteven Rostedt 	(*pos)++;
172998c4fd04SSteven Rostedt 	iter->pos = *pos;
17308fc0c701SSteven Rostedt 
17314aeb6967SSteven Rostedt 	if (iter->probe)
17324aeb6967SSteven Rostedt 		hnd = &iter->probe->node;
17338fc0c701SSteven Rostedt  retry:
17348fc0c701SSteven Rostedt 	if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
17358fc0c701SSteven Rostedt 		return NULL;
17368fc0c701SSteven Rostedt 
17378fc0c701SSteven Rostedt 	hhd = &ftrace_func_hash[iter->hidx];
17388fc0c701SSteven Rostedt 
17398fc0c701SSteven Rostedt 	if (hlist_empty(hhd)) {
17408fc0c701SSteven Rostedt 		iter->hidx++;
17418fc0c701SSteven Rostedt 		hnd = NULL;
17428fc0c701SSteven Rostedt 		goto retry;
17438fc0c701SSteven Rostedt 	}
17448fc0c701SSteven Rostedt 
17458fc0c701SSteven Rostedt 	if (!hnd)
17468fc0c701SSteven Rostedt 		hnd = hhd->first;
17478fc0c701SSteven Rostedt 	else {
17488fc0c701SSteven Rostedt 		hnd = hnd->next;
17498fc0c701SSteven Rostedt 		if (!hnd) {
17508fc0c701SSteven Rostedt 			iter->hidx++;
17518fc0c701SSteven Rostedt 			goto retry;
17528fc0c701SSteven Rostedt 		}
17538fc0c701SSteven Rostedt 	}
17548fc0c701SSteven Rostedt 
17554aeb6967SSteven Rostedt 	if (WARN_ON_ONCE(!hnd))
17564aeb6967SSteven Rostedt 		return NULL;
17574aeb6967SSteven Rostedt 
17584aeb6967SSteven Rostedt 	iter->probe = hlist_entry(hnd, struct ftrace_func_probe, node);
17594aeb6967SSteven Rostedt 
17604aeb6967SSteven Rostedt 	return iter;
17618fc0c701SSteven Rostedt }
17628fc0c701SSteven Rostedt 
17638fc0c701SSteven Rostedt static void *t_hash_start(struct seq_file *m, loff_t *pos)
17648fc0c701SSteven Rostedt {
17658fc0c701SSteven Rostedt 	struct ftrace_iterator *iter = m->private;
17668fc0c701SSteven Rostedt 	void *p = NULL;
1767d82d6244SLi Zefan 	loff_t l;
1768d82d6244SLi Zefan 
17692bccfffdSSteven Rostedt 	if (iter->func_pos > *pos)
17702bccfffdSSteven Rostedt 		return NULL;
17718fc0c701SSteven Rostedt 
1772d82d6244SLi Zefan 	iter->hidx = 0;
17732bccfffdSSteven Rostedt 	for (l = 0; l <= (*pos - iter->func_pos); ) {
17744aeb6967SSteven Rostedt 		p = t_hash_next(m, &l);
1775d82d6244SLi Zefan 		if (!p)
1776d82d6244SLi Zefan 			break;
1777d82d6244SLi Zefan 	}
17784aeb6967SSteven Rostedt 	if (!p)
17794aeb6967SSteven Rostedt 		return NULL;
17804aeb6967SSteven Rostedt 
178198c4fd04SSteven Rostedt 	/* Only set this if we have an item */
178298c4fd04SSteven Rostedt 	iter->flags |= FTRACE_ITER_HASH;
178398c4fd04SSteven Rostedt 
17844aeb6967SSteven Rostedt 	return iter;
17858fc0c701SSteven Rostedt }
17868fc0c701SSteven Rostedt 
17874aeb6967SSteven Rostedt static int
17884aeb6967SSteven Rostedt t_hash_show(struct seq_file *m, struct ftrace_iterator *iter)
17898fc0c701SSteven Rostedt {
1790b6887d79SSteven Rostedt 	struct ftrace_func_probe *rec;
17918fc0c701SSteven Rostedt 
17924aeb6967SSteven Rostedt 	rec = iter->probe;
17934aeb6967SSteven Rostedt 	if (WARN_ON_ONCE(!rec))
17944aeb6967SSteven Rostedt 		return -EIO;
17958fc0c701SSteven Rostedt 
1796809dcf29SSteven Rostedt 	if (rec->ops->print)
1797809dcf29SSteven Rostedt 		return rec->ops->print(m, rec->ip, rec->ops, rec->data);
1798809dcf29SSteven Rostedt 
1799b375a11aSSteven Rostedt 	seq_printf(m, "%ps:%ps", (void *)rec->ip, (void *)rec->ops->func);
18008fc0c701SSteven Rostedt 
18018fc0c701SSteven Rostedt 	if (rec->data)
18028fc0c701SSteven Rostedt 		seq_printf(m, ":%p", rec->data);
18038fc0c701SSteven Rostedt 	seq_putc(m, '\n');
18048fc0c701SSteven Rostedt 
18058fc0c701SSteven Rostedt 	return 0;
18068fc0c701SSteven Rostedt }
18078fc0c701SSteven Rostedt 
18088fc0c701SSteven Rostedt static void *
18095072c59fSSteven Rostedt t_next(struct seq_file *m, void *v, loff_t *pos)
18105072c59fSSteven Rostedt {
18115072c59fSSteven Rostedt 	struct ftrace_iterator *iter = m->private;
1812f45948e8SSteven Rostedt 	struct ftrace_ops *ops = &global_ops;
18135072c59fSSteven Rostedt 	struct dyn_ftrace *rec = NULL;
18145072c59fSSteven Rostedt 
181545a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
181645a4a237SSteven Rostedt 		return NULL;
181745a4a237SSteven Rostedt 
18188fc0c701SSteven Rostedt 	if (iter->flags & FTRACE_ITER_HASH)
18194aeb6967SSteven Rostedt 		return t_hash_next(m, pos);
18208fc0c701SSteven Rostedt 
18215072c59fSSteven Rostedt 	(*pos)++;
18221106b699SJiri Olsa 	iter->pos = iter->func_pos = *pos;
18235072c59fSSteven Rostedt 
18240c75a3edSSteven Rostedt 	if (iter->flags & FTRACE_ITER_PRINTALL)
182557c072c7SSteven Rostedt 		return t_hash_start(m, pos);
18260c75a3edSSteven Rostedt 
18275072c59fSSteven Rostedt  retry:
18285072c59fSSteven Rostedt 	if (iter->idx >= iter->pg->index) {
18295072c59fSSteven Rostedt 		if (iter->pg->next) {
18305072c59fSSteven Rostedt 			iter->pg = iter->pg->next;
18315072c59fSSteven Rostedt 			iter->idx = 0;
18325072c59fSSteven Rostedt 			goto retry;
18335072c59fSSteven Rostedt 		}
18345072c59fSSteven Rostedt 	} else {
18355072c59fSSteven Rostedt 		rec = &iter->pg->records[iter->idx++];
1836a9fdda33SSteven Rostedt 		if ((rec->flags & FTRACE_FL_FREE) ||
1837a9fdda33SSteven Rostedt 
18380183fb1cSSteven Rostedt 		    ((iter->flags & FTRACE_ITER_FILTER) &&
1839f45948e8SSteven Rostedt 		     !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) ||
18400183fb1cSSteven Rostedt 
184141c52c0dSSteven Rostedt 		    ((iter->flags & FTRACE_ITER_NOTRACE) &&
1842647bcd03SSteven Rostedt 		     !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) ||
1843647bcd03SSteven Rostedt 
1844647bcd03SSteven Rostedt 		    ((iter->flags & FTRACE_ITER_ENABLED) &&
1845647bcd03SSteven Rostedt 		     !(rec->flags & ~FTRACE_FL_MASK))) {
1846647bcd03SSteven Rostedt 
18475072c59fSSteven Rostedt 			rec = NULL;
18485072c59fSSteven Rostedt 			goto retry;
18495072c59fSSteven Rostedt 		}
18505072c59fSSteven Rostedt 	}
18515072c59fSSteven Rostedt 
18524aeb6967SSteven Rostedt 	if (!rec)
185357c072c7SSteven Rostedt 		return t_hash_start(m, pos);
18544aeb6967SSteven Rostedt 
18554aeb6967SSteven Rostedt 	iter->func = rec;
18564aeb6967SSteven Rostedt 
18574aeb6967SSteven Rostedt 	return iter;
18585072c59fSSteven Rostedt }
18595072c59fSSteven Rostedt 
186098c4fd04SSteven Rostedt static void reset_iter_read(struct ftrace_iterator *iter)
186198c4fd04SSteven Rostedt {
186298c4fd04SSteven Rostedt 	iter->pos = 0;
186398c4fd04SSteven Rostedt 	iter->func_pos = 0;
186498c4fd04SSteven Rostedt 	iter->flags &= ~(FTRACE_ITER_PRINTALL & FTRACE_ITER_HASH);
18655072c59fSSteven Rostedt }
18665072c59fSSteven Rostedt 
18675072c59fSSteven Rostedt static void *t_start(struct seq_file *m, loff_t *pos)
18685072c59fSSteven Rostedt {
18695072c59fSSteven Rostedt 	struct ftrace_iterator *iter = m->private;
1870f45948e8SSteven Rostedt 	struct ftrace_ops *ops = &global_ops;
18715072c59fSSteven Rostedt 	void *p = NULL;
1872694ce0a5SLi Zefan 	loff_t l;
18735072c59fSSteven Rostedt 
18748fc0c701SSteven Rostedt 	mutex_lock(&ftrace_lock);
187545a4a237SSteven Rostedt 
187645a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
187745a4a237SSteven Rostedt 		return NULL;
187845a4a237SSteven Rostedt 
18790c75a3edSSteven Rostedt 	/*
188098c4fd04SSteven Rostedt 	 * If an lseek was done, then reset and start from beginning.
188198c4fd04SSteven Rostedt 	 */
188298c4fd04SSteven Rostedt 	if (*pos < iter->pos)
188398c4fd04SSteven Rostedt 		reset_iter_read(iter);
188498c4fd04SSteven Rostedt 
188598c4fd04SSteven Rostedt 	/*
18860c75a3edSSteven Rostedt 	 * For set_ftrace_filter reading, if we have the filter
18870c75a3edSSteven Rostedt 	 * off, we can short cut and just print out that all
18880c75a3edSSteven Rostedt 	 * functions are enabled.
18890c75a3edSSteven Rostedt 	 */
1890f45948e8SSteven Rostedt 	if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) {
18910c75a3edSSteven Rostedt 		if (*pos > 0)
18928fc0c701SSteven Rostedt 			return t_hash_start(m, pos);
18930c75a3edSSteven Rostedt 		iter->flags |= FTRACE_ITER_PRINTALL;
1894df091625SChris Wright 		/* reset in case of seek/pread */
1895df091625SChris Wright 		iter->flags &= ~FTRACE_ITER_HASH;
18960c75a3edSSteven Rostedt 		return iter;
18970c75a3edSSteven Rostedt 	}
18980c75a3edSSteven Rostedt 
18998fc0c701SSteven Rostedt 	if (iter->flags & FTRACE_ITER_HASH)
19008fc0c701SSteven Rostedt 		return t_hash_start(m, pos);
19018fc0c701SSteven Rostedt 
190298c4fd04SSteven Rostedt 	/*
190398c4fd04SSteven Rostedt 	 * Unfortunately, we need to restart at ftrace_pages_start
190498c4fd04SSteven Rostedt 	 * every time we let go of the ftrace_mutex. This is because
190598c4fd04SSteven Rostedt 	 * those pointers can change without the lock.
190698c4fd04SSteven Rostedt 	 */
1907694ce0a5SLi Zefan 	iter->pg = ftrace_pages_start;
1908694ce0a5SLi Zefan 	iter->idx = 0;
1909694ce0a5SLi Zefan 	for (l = 0; l <= *pos; ) {
1910694ce0a5SLi Zefan 		p = t_next(m, p, &l);
1911694ce0a5SLi Zefan 		if (!p)
1912694ce0a5SLi Zefan 			break;
191350cdaf08SLiming Wang 	}
19145821e1b7Swalimis 
19154aeb6967SSteven Rostedt 	if (!p) {
19164aeb6967SSteven Rostedt 		if (iter->flags & FTRACE_ITER_FILTER)
19178fc0c701SSteven Rostedt 			return t_hash_start(m, pos);
19188fc0c701SSteven Rostedt 
19194aeb6967SSteven Rostedt 		return NULL;
19204aeb6967SSteven Rostedt 	}
19214aeb6967SSteven Rostedt 
19224aeb6967SSteven Rostedt 	return iter;
19235072c59fSSteven Rostedt }
19245072c59fSSteven Rostedt 
19255072c59fSSteven Rostedt static void t_stop(struct seq_file *m, void *p)
19265072c59fSSteven Rostedt {
19278fc0c701SSteven Rostedt 	mutex_unlock(&ftrace_lock);
19285072c59fSSteven Rostedt }
19295072c59fSSteven Rostedt 
19305072c59fSSteven Rostedt static int t_show(struct seq_file *m, void *v)
19315072c59fSSteven Rostedt {
19320c75a3edSSteven Rostedt 	struct ftrace_iterator *iter = m->private;
19334aeb6967SSteven Rostedt 	struct dyn_ftrace *rec;
19345072c59fSSteven Rostedt 
19358fc0c701SSteven Rostedt 	if (iter->flags & FTRACE_ITER_HASH)
19364aeb6967SSteven Rostedt 		return t_hash_show(m, iter);
19378fc0c701SSteven Rostedt 
19380c75a3edSSteven Rostedt 	if (iter->flags & FTRACE_ITER_PRINTALL) {
19390c75a3edSSteven Rostedt 		seq_printf(m, "#### all functions enabled ####\n");
19400c75a3edSSteven Rostedt 		return 0;
19410c75a3edSSteven Rostedt 	}
19420c75a3edSSteven Rostedt 
19434aeb6967SSteven Rostedt 	rec = iter->func;
19444aeb6967SSteven Rostedt 
19455072c59fSSteven Rostedt 	if (!rec)
19465072c59fSSteven Rostedt 		return 0;
19475072c59fSSteven Rostedt 
1948647bcd03SSteven Rostedt 	seq_printf(m, "%ps", (void *)rec->ip);
1949647bcd03SSteven Rostedt 	if (iter->flags & FTRACE_ITER_ENABLED)
1950647bcd03SSteven Rostedt 		seq_printf(m, " (%ld)",
1951647bcd03SSteven Rostedt 			   rec->flags & ~FTRACE_FL_MASK);
1952647bcd03SSteven Rostedt 	seq_printf(m, "\n");
19535072c59fSSteven Rostedt 
19545072c59fSSteven Rostedt 	return 0;
19555072c59fSSteven Rostedt }
19565072c59fSSteven Rostedt 
195788e9d34cSJames Morris static const struct seq_operations show_ftrace_seq_ops = {
19585072c59fSSteven Rostedt 	.start = t_start,
19595072c59fSSteven Rostedt 	.next = t_next,
19605072c59fSSteven Rostedt 	.stop = t_stop,
19615072c59fSSteven Rostedt 	.show = t_show,
19625072c59fSSteven Rostedt };
19635072c59fSSteven Rostedt 
1964e309b41dSIngo Molnar static int
19655072c59fSSteven Rostedt ftrace_avail_open(struct inode *inode, struct file *file)
19665072c59fSSteven Rostedt {
19675072c59fSSteven Rostedt 	struct ftrace_iterator *iter;
19685072c59fSSteven Rostedt 	int ret;
19695072c59fSSteven Rostedt 
19704eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
19714eebcc81SSteven Rostedt 		return -ENODEV;
19724eebcc81SSteven Rostedt 
19735072c59fSSteven Rostedt 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
19745072c59fSSteven Rostedt 	if (!iter)
19755072c59fSSteven Rostedt 		return -ENOMEM;
19765072c59fSSteven Rostedt 
19775072c59fSSteven Rostedt 	iter->pg = ftrace_pages_start;
19785072c59fSSteven Rostedt 
19795072c59fSSteven Rostedt 	ret = seq_open(file, &show_ftrace_seq_ops);
19805072c59fSSteven Rostedt 	if (!ret) {
19815072c59fSSteven Rostedt 		struct seq_file *m = file->private_data;
19824bf39a94SIngo Molnar 
19835072c59fSSteven Rostedt 		m->private = iter;
19844bf39a94SIngo Molnar 	} else {
19855072c59fSSteven Rostedt 		kfree(iter);
19864bf39a94SIngo Molnar 	}
19875072c59fSSteven Rostedt 
19885072c59fSSteven Rostedt 	return ret;
19895072c59fSSteven Rostedt }
19905072c59fSSteven Rostedt 
1991647bcd03SSteven Rostedt static int
1992647bcd03SSteven Rostedt ftrace_enabled_open(struct inode *inode, struct file *file)
1993647bcd03SSteven Rostedt {
1994647bcd03SSteven Rostedt 	struct ftrace_iterator *iter;
1995647bcd03SSteven Rostedt 	int ret;
1996647bcd03SSteven Rostedt 
1997647bcd03SSteven Rostedt 	if (unlikely(ftrace_disabled))
1998647bcd03SSteven Rostedt 		return -ENODEV;
1999647bcd03SSteven Rostedt 
2000647bcd03SSteven Rostedt 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
2001647bcd03SSteven Rostedt 	if (!iter)
2002647bcd03SSteven Rostedt 		return -ENOMEM;
2003647bcd03SSteven Rostedt 
2004647bcd03SSteven Rostedt 	iter->pg = ftrace_pages_start;
2005647bcd03SSteven Rostedt 	iter->flags = FTRACE_ITER_ENABLED;
2006647bcd03SSteven Rostedt 
2007647bcd03SSteven Rostedt 	ret = seq_open(file, &show_ftrace_seq_ops);
2008647bcd03SSteven Rostedt 	if (!ret) {
2009647bcd03SSteven Rostedt 		struct seq_file *m = file->private_data;
2010647bcd03SSteven Rostedt 
2011647bcd03SSteven Rostedt 		m->private = iter;
2012647bcd03SSteven Rostedt 	} else {
2013647bcd03SSteven Rostedt 		kfree(iter);
2014647bcd03SSteven Rostedt 	}
2015647bcd03SSteven Rostedt 
2016647bcd03SSteven Rostedt 	return ret;
2017647bcd03SSteven Rostedt }
2018647bcd03SSteven Rostedt 
20191cf41dd7SSteven Rostedt static void ftrace_filter_reset(struct ftrace_hash *hash)
20205072c59fSSteven Rostedt {
202152baf119SSteven Rostedt 	mutex_lock(&ftrace_lock);
20221cf41dd7SSteven Rostedt 	ftrace_hash_clear(hash);
202352baf119SSteven Rostedt 	mutex_unlock(&ftrace_lock);
20245072c59fSSteven Rostedt }
20255072c59fSSteven Rostedt 
2026e309b41dSIngo Molnar static int
2027f45948e8SSteven Rostedt ftrace_regex_open(struct ftrace_ops *ops, int flag,
20281cf41dd7SSteven Rostedt 		  struct inode *inode, struct file *file)
20295072c59fSSteven Rostedt {
20305072c59fSSteven Rostedt 	struct ftrace_iterator *iter;
2031f45948e8SSteven Rostedt 	struct ftrace_hash *hash;
20325072c59fSSteven Rostedt 	int ret = 0;
20335072c59fSSteven Rostedt 
20344eebcc81SSteven Rostedt 	if (unlikely(ftrace_disabled))
20354eebcc81SSteven Rostedt 		return -ENODEV;
20364eebcc81SSteven Rostedt 
20375072c59fSSteven Rostedt 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
20385072c59fSSteven Rostedt 	if (!iter)
20395072c59fSSteven Rostedt 		return -ENOMEM;
20405072c59fSSteven Rostedt 
2041689fd8b6S[email protected] 	if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) {
2042689fd8b6S[email protected] 		kfree(iter);
2043689fd8b6S[email protected] 		return -ENOMEM;
2044689fd8b6S[email protected] 	}
2045689fd8b6S[email protected] 
2046f45948e8SSteven Rostedt 	if (flag & FTRACE_ITER_NOTRACE)
2047f45948e8SSteven Rostedt 		hash = ops->notrace_hash;
2048f45948e8SSteven Rostedt 	else
2049f45948e8SSteven Rostedt 		hash = ops->filter_hash;
2050f45948e8SSteven Rostedt 
205133dc9b12SSteven Rostedt 	iter->ops = ops;
205233dc9b12SSteven Rostedt 	iter->flags = flag;
205333dc9b12SSteven Rostedt 
205433dc9b12SSteven Rostedt 	if (file->f_mode & FMODE_WRITE) {
205533dc9b12SSteven Rostedt 		mutex_lock(&ftrace_lock);
205633dc9b12SSteven Rostedt 		iter->hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, hash);
205733dc9b12SSteven Rostedt 		mutex_unlock(&ftrace_lock);
205833dc9b12SSteven Rostedt 
205933dc9b12SSteven Rostedt 		if (!iter->hash) {
206033dc9b12SSteven Rostedt 			trace_parser_put(&iter->parser);
206133dc9b12SSteven Rostedt 			kfree(iter);
206233dc9b12SSteven Rostedt 			return -ENOMEM;
206333dc9b12SSteven Rostedt 		}
206433dc9b12SSteven Rostedt 	}
20651cf41dd7SSteven Rostedt 
206641c52c0dSSteven Rostedt 	mutex_lock(&ftrace_regex_lock);
206733dc9b12SSteven Rostedt 
20685072c59fSSteven Rostedt 	if ((file->f_mode & FMODE_WRITE) &&
20698650ae32SSteven Rostedt 	    (file->f_flags & O_TRUNC))
207033dc9b12SSteven Rostedt 		ftrace_filter_reset(iter->hash);
20715072c59fSSteven Rostedt 
20725072c59fSSteven Rostedt 	if (file->f_mode & FMODE_READ) {
20735072c59fSSteven Rostedt 		iter->pg = ftrace_pages_start;
20745072c59fSSteven Rostedt 
20755072c59fSSteven Rostedt 		ret = seq_open(file, &show_ftrace_seq_ops);
20765072c59fSSteven Rostedt 		if (!ret) {
20775072c59fSSteven Rostedt 			struct seq_file *m = file->private_data;
20785072c59fSSteven Rostedt 			m->private = iter;
207979fe249cSLi Zefan 		} else {
208033dc9b12SSteven Rostedt 			/* Failed */
208133dc9b12SSteven Rostedt 			free_ftrace_hash(iter->hash);
208279fe249cSLi Zefan 			trace_parser_put(&iter->parser);
20835072c59fSSteven Rostedt 			kfree(iter);
208479fe249cSLi Zefan 		}
20855072c59fSSteven Rostedt 	} else
20865072c59fSSteven Rostedt 		file->private_data = iter;
208741c52c0dSSteven Rostedt 	mutex_unlock(&ftrace_regex_lock);
20885072c59fSSteven Rostedt 
20895072c59fSSteven Rostedt 	return ret;
20905072c59fSSteven Rostedt }
20915072c59fSSteven Rostedt 
209241c52c0dSSteven Rostedt static int
209341c52c0dSSteven Rostedt ftrace_filter_open(struct inode *inode, struct file *file)
209441c52c0dSSteven Rostedt {
2095f45948e8SSteven Rostedt 	return ftrace_regex_open(&global_ops, FTRACE_ITER_FILTER,
20961cf41dd7SSteven Rostedt 				 inode, file);
209741c52c0dSSteven Rostedt }
209841c52c0dSSteven Rostedt 
209941c52c0dSSteven Rostedt static int
210041c52c0dSSteven Rostedt ftrace_notrace_open(struct inode *inode, struct file *file)
210141c52c0dSSteven Rostedt {
2102f45948e8SSteven Rostedt 	return ftrace_regex_open(&global_ops, FTRACE_ITER_NOTRACE,
21031cf41dd7SSteven Rostedt 				 inode, file);
210441c52c0dSSteven Rostedt }
210541c52c0dSSteven Rostedt 
2106e309b41dSIngo Molnar static loff_t
210741c52c0dSSteven Rostedt ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
21085072c59fSSteven Rostedt {
21095072c59fSSteven Rostedt 	loff_t ret;
21105072c59fSSteven Rostedt 
21115072c59fSSteven Rostedt 	if (file->f_mode & FMODE_READ)
21125072c59fSSteven Rostedt 		ret = seq_lseek(file, offset, origin);
21135072c59fSSteven Rostedt 	else
21145072c59fSSteven Rostedt 		file->f_pos = ret = 1;
21155072c59fSSteven Rostedt 
21165072c59fSSteven Rostedt 	return ret;
21175072c59fSSteven Rostedt }
21185072c59fSSteven Rostedt 
211964e7c440SSteven Rostedt static int ftrace_match(char *str, char *regex, int len, int type)
21209f4801e3SSteven Rostedt {
21219f4801e3SSteven Rostedt 	int matched = 0;
2122751e9983SLi Zefan 	int slen;
21239f4801e3SSteven Rostedt 
21249f4801e3SSteven Rostedt 	switch (type) {
21259f4801e3SSteven Rostedt 	case MATCH_FULL:
21269f4801e3SSteven Rostedt 		if (strcmp(str, regex) == 0)
21279f4801e3SSteven Rostedt 			matched = 1;
21289f4801e3SSteven Rostedt 		break;
21299f4801e3SSteven Rostedt 	case MATCH_FRONT_ONLY:
21309f4801e3SSteven Rostedt 		if (strncmp(str, regex, len) == 0)
21319f4801e3SSteven Rostedt 			matched = 1;
21329f4801e3SSteven Rostedt 		break;
21339f4801e3SSteven Rostedt 	case MATCH_MIDDLE_ONLY:
21349f4801e3SSteven Rostedt 		if (strstr(str, regex))
21359f4801e3SSteven Rostedt 			matched = 1;
21369f4801e3SSteven Rostedt 		break;
21379f4801e3SSteven Rostedt 	case MATCH_END_ONLY:
2138751e9983SLi Zefan 		slen = strlen(str);
2139751e9983SLi Zefan 		if (slen >= len && memcmp(str + slen - len, regex, len) == 0)
21409f4801e3SSteven Rostedt 			matched = 1;
21419f4801e3SSteven Rostedt 		break;
21429f4801e3SSteven Rostedt 	}
21439f4801e3SSteven Rostedt 
21449f4801e3SSteven Rostedt 	return matched;
21459f4801e3SSteven Rostedt }
21469f4801e3SSteven Rostedt 
2147b448c4e3SSteven Rostedt static int
21481cf41dd7SSteven Rostedt enter_record(struct ftrace_hash *hash, struct dyn_ftrace *rec, int not)
214964e7c440SSteven Rostedt {
2150b448c4e3SSteven Rostedt 	struct ftrace_func_entry *entry;
2151b448c4e3SSteven Rostedt 	int ret = 0;
2152b448c4e3SSteven Rostedt 
21531cf41dd7SSteven Rostedt 	entry = ftrace_lookup_ip(hash, rec->ip);
2154b448c4e3SSteven Rostedt 	if (not) {
2155b448c4e3SSteven Rostedt 		/* Do nothing if it doesn't exist */
2156b448c4e3SSteven Rostedt 		if (!entry)
2157b448c4e3SSteven Rostedt 			return 0;
2158b448c4e3SSteven Rostedt 
215933dc9b12SSteven Rostedt 		free_hash_entry(hash, entry);
2160b448c4e3SSteven Rostedt 	} else {
2161b448c4e3SSteven Rostedt 		/* Do nothing if it exists */
2162b448c4e3SSteven Rostedt 		if (entry)
2163b448c4e3SSteven Rostedt 			return 0;
2164b448c4e3SSteven Rostedt 
2165b448c4e3SSteven Rostedt 		ret = add_hash_entry(hash, rec->ip);
2166b448c4e3SSteven Rostedt 	}
2167b448c4e3SSteven Rostedt 	return ret;
2168996e87beSSteven Rostedt }
2169996e87beSSteven Rostedt 
217064e7c440SSteven Rostedt static int
2171b9df92d2SSteven Rostedt ftrace_match_record(struct dyn_ftrace *rec, char *mod,
2172b9df92d2SSteven Rostedt 		    char *regex, int len, int type)
217364e7c440SSteven Rostedt {
217464e7c440SSteven Rostedt 	char str[KSYM_SYMBOL_LEN];
2175b9df92d2SSteven Rostedt 	char *modname;
217664e7c440SSteven Rostedt 
2177b9df92d2SSteven Rostedt 	kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
2178b9df92d2SSteven Rostedt 
2179b9df92d2SSteven Rostedt 	if (mod) {
2180b9df92d2SSteven Rostedt 		/* module lookup requires matching the module */
2181b9df92d2SSteven Rostedt 		if (!modname || strcmp(modname, mod))
2182b9df92d2SSteven Rostedt 			return 0;
2183b9df92d2SSteven Rostedt 
2184b9df92d2SSteven Rostedt 		/* blank search means to match all funcs in the mod */
2185b9df92d2SSteven Rostedt 		if (!len)
2186b9df92d2SSteven Rostedt 			return 1;
2187b9df92d2SSteven Rostedt 	}
2188b9df92d2SSteven Rostedt 
218964e7c440SSteven Rostedt 	return ftrace_match(str, regex, len, type);
219064e7c440SSteven Rostedt }
219164e7c440SSteven Rostedt 
21921cf41dd7SSteven Rostedt static int
21931cf41dd7SSteven Rostedt match_records(struct ftrace_hash *hash, char *buff,
21941cf41dd7SSteven Rostedt 	      int len, char *mod, int not)
21959f4801e3SSteven Rostedt {
2196b9df92d2SSteven Rostedt 	unsigned search_len = 0;
21979f4801e3SSteven Rostedt 	struct ftrace_page *pg;
21989f4801e3SSteven Rostedt 	struct dyn_ftrace *rec;
2199b9df92d2SSteven Rostedt 	int type = MATCH_FULL;
2200b9df92d2SSteven Rostedt 	char *search = buff;
2201311d16daSLi Zefan 	int found = 0;
2202b448c4e3SSteven Rostedt 	int ret;
22039f4801e3SSteven Rostedt 
2204b9df92d2SSteven Rostedt 	if (len) {
22053f6fe06dSFrederic Weisbecker 		type = filter_parse_regex(buff, len, &search, &not);
22069f4801e3SSteven Rostedt 		search_len = strlen(search);
2207b9df92d2SSteven Rostedt 	}
2208b9df92d2SSteven Rostedt 
220952baf119SSteven Rostedt 	mutex_lock(&ftrace_lock);
2210b9df92d2SSteven Rostedt 
2211b9df92d2SSteven Rostedt 	if (unlikely(ftrace_disabled))
2212b9df92d2SSteven Rostedt 		goto out_unlock;
2213b9df92d2SSteven Rostedt 
2214265c831cSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
22155072c59fSSteven Rostedt 
2216b9df92d2SSteven Rostedt 		if (ftrace_match_record(rec, mod, search, search_len, type)) {
22171cf41dd7SSteven Rostedt 			ret = enter_record(hash, rec, not);
2218b448c4e3SSteven Rostedt 			if (ret < 0) {
2219b448c4e3SSteven Rostedt 				found = ret;
2220b448c4e3SSteven Rostedt 				goto out_unlock;
2221b448c4e3SSteven Rostedt 			}
2222311d16daSLi Zefan 			found = 1;
22235072c59fSSteven Rostedt 		}
2224265c831cSSteven Rostedt 	} while_for_each_ftrace_rec();
2225b9df92d2SSteven Rostedt  out_unlock:
222652baf119SSteven Rostedt 	mutex_unlock(&ftrace_lock);
2227311d16daSLi Zefan 
2228311d16daSLi Zefan 	return found;
22295072c59fSSteven Rostedt }
22305072c59fSSteven Rostedt 
223164e7c440SSteven Rostedt static int
22321cf41dd7SSteven Rostedt ftrace_match_records(struct ftrace_hash *hash, char *buff, int len)
223364e7c440SSteven Rostedt {
22341cf41dd7SSteven Rostedt 	return match_records(hash, buff, len, NULL, 0);
223564e7c440SSteven Rostedt }
223664e7c440SSteven Rostedt 
22371cf41dd7SSteven Rostedt static int
22381cf41dd7SSteven Rostedt ftrace_match_module_records(struct ftrace_hash *hash, char *buff, char *mod)
223964e7c440SSteven Rostedt {
224064e7c440SSteven Rostedt 	int not = 0;
22416a24a244SSteven Rostedt 
224264e7c440SSteven Rostedt 	/* blank or '*' mean the same */
224364e7c440SSteven Rostedt 	if (strcmp(buff, "*") == 0)
224464e7c440SSteven Rostedt 		buff[0] = 0;
224564e7c440SSteven Rostedt 
224664e7c440SSteven Rostedt 	/* handle the case of 'dont filter this module' */
224764e7c440SSteven Rostedt 	if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
224864e7c440SSteven Rostedt 		buff[0] = 0;
224964e7c440SSteven Rostedt 		not = 1;
225064e7c440SSteven Rostedt 	}
225164e7c440SSteven Rostedt 
22521cf41dd7SSteven Rostedt 	return match_records(hash, buff, strlen(buff), mod, not);
225364e7c440SSteven Rostedt }
225464e7c440SSteven Rostedt 
2255f6180773SSteven Rostedt /*
2256f6180773SSteven Rostedt  * We register the module command as a template to show others how
2257f6180773SSteven Rostedt  * to register the a command as well.
2258f6180773SSteven Rostedt  */
2259f6180773SSteven Rostedt 
2260f6180773SSteven Rostedt static int
2261f6180773SSteven Rostedt ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
2262f6180773SSteven Rostedt {
2263f45948e8SSteven Rostedt 	struct ftrace_ops *ops = &global_ops;
22641cf41dd7SSteven Rostedt 	struct ftrace_hash *hash;
2265f6180773SSteven Rostedt 	char *mod;
2266b448c4e3SSteven Rostedt 	int ret = -EINVAL;
2267f6180773SSteven Rostedt 
2268f6180773SSteven Rostedt 	/*
2269f6180773SSteven Rostedt 	 * cmd == 'mod' because we only registered this func
2270f6180773SSteven Rostedt 	 * for the 'mod' ftrace_func_command.
2271f6180773SSteven Rostedt 	 * But if you register one func with multiple commands,
2272f6180773SSteven Rostedt 	 * you can tell which command was used by the cmd
2273f6180773SSteven Rostedt 	 * parameter.
2274f6180773SSteven Rostedt 	 */
2275f6180773SSteven Rostedt 
2276f6180773SSteven Rostedt 	/* we must have a module name */
2277f6180773SSteven Rostedt 	if (!param)
2278b448c4e3SSteven Rostedt 		return ret;
2279f6180773SSteven Rostedt 
2280f6180773SSteven Rostedt 	mod = strsep(&param, ":");
2281f6180773SSteven Rostedt 	if (!strlen(mod))
2282b448c4e3SSteven Rostedt 		return ret;
2283f6180773SSteven Rostedt 
22841cf41dd7SSteven Rostedt 	if (enable)
2285f45948e8SSteven Rostedt 		hash = ops->filter_hash;
22861cf41dd7SSteven Rostedt 	else
2287f45948e8SSteven Rostedt 		hash = ops->notrace_hash;
22881cf41dd7SSteven Rostedt 
22891cf41dd7SSteven Rostedt 	ret = ftrace_match_module_records(hash, func, mod);
2290b448c4e3SSteven Rostedt 	if (!ret)
2291b448c4e3SSteven Rostedt 		ret = -EINVAL;
2292b448c4e3SSteven Rostedt 	if (ret < 0)
2293b448c4e3SSteven Rostedt 		return ret;
2294b448c4e3SSteven Rostedt 
2295f6180773SSteven Rostedt 	return 0;
2296f6180773SSteven Rostedt }
2297f6180773SSteven Rostedt 
2298f6180773SSteven Rostedt static struct ftrace_func_command ftrace_mod_cmd = {
2299f6180773SSteven Rostedt 	.name			= "mod",
2300f6180773SSteven Rostedt 	.func			= ftrace_mod_callback,
2301f6180773SSteven Rostedt };
2302f6180773SSteven Rostedt 
2303f6180773SSteven Rostedt static int __init ftrace_mod_cmd_init(void)
2304f6180773SSteven Rostedt {
2305f6180773SSteven Rostedt 	return register_ftrace_command(&ftrace_mod_cmd);
2306f6180773SSteven Rostedt }
2307f6180773SSteven Rostedt device_initcall(ftrace_mod_cmd_init);
2308f6180773SSteven Rostedt 
230959df055fSSteven Rostedt static void
2310b6887d79SSteven Rostedt function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
231159df055fSSteven Rostedt {
2312b6887d79SSteven Rostedt 	struct ftrace_func_probe *entry;
231359df055fSSteven Rostedt 	struct hlist_head *hhd;
231459df055fSSteven Rostedt 	struct hlist_node *n;
231559df055fSSteven Rostedt 	unsigned long key;
231659df055fSSteven Rostedt 
231759df055fSSteven Rostedt 	key = hash_long(ip, FTRACE_HASH_BITS);
231859df055fSSteven Rostedt 
231959df055fSSteven Rostedt 	hhd = &ftrace_func_hash[key];
232059df055fSSteven Rostedt 
232159df055fSSteven Rostedt 	if (hlist_empty(hhd))
232259df055fSSteven Rostedt 		return;
232359df055fSSteven Rostedt 
232459df055fSSteven Rostedt 	/*
232559df055fSSteven Rostedt 	 * Disable preemption for these calls to prevent a RCU grace
232659df055fSSteven Rostedt 	 * period. This syncs the hash iteration and freeing of items
232759df055fSSteven Rostedt 	 * on the hash. rcu_read_lock is too dangerous here.
232859df055fSSteven Rostedt 	 */
23295168ae50SSteven Rostedt 	preempt_disable_notrace();
233059df055fSSteven Rostedt 	hlist_for_each_entry_rcu(entry, n, hhd, node) {
233159df055fSSteven Rostedt 		if (entry->ip == ip)
233259df055fSSteven Rostedt 			entry->ops->func(ip, parent_ip, &entry->data);
233359df055fSSteven Rostedt 	}
23345168ae50SSteven Rostedt 	preempt_enable_notrace();
233559df055fSSteven Rostedt }
233659df055fSSteven Rostedt 
2337b6887d79SSteven Rostedt static struct ftrace_ops trace_probe_ops __read_mostly =
233859df055fSSteven Rostedt {
2339b6887d79SSteven Rostedt 	.func		= function_trace_probe_call,
234059df055fSSteven Rostedt };
234159df055fSSteven Rostedt 
2342b6887d79SSteven Rostedt static int ftrace_probe_registered;
234359df055fSSteven Rostedt 
2344b6887d79SSteven Rostedt static void __enable_ftrace_function_probe(void)
234559df055fSSteven Rostedt {
234659df055fSSteven Rostedt 	int i;
234759df055fSSteven Rostedt 
2348b6887d79SSteven Rostedt 	if (ftrace_probe_registered)
234959df055fSSteven Rostedt 		return;
235059df055fSSteven Rostedt 
235159df055fSSteven Rostedt 	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
235259df055fSSteven Rostedt 		struct hlist_head *hhd = &ftrace_func_hash[i];
235359df055fSSteven Rostedt 		if (hhd->first)
235459df055fSSteven Rostedt 			break;
235559df055fSSteven Rostedt 	}
235659df055fSSteven Rostedt 	/* Nothing registered? */
235759df055fSSteven Rostedt 	if (i == FTRACE_FUNC_HASHSIZE)
235859df055fSSteven Rostedt 		return;
235959df055fSSteven Rostedt 
2360b6887d79SSteven Rostedt 	__register_ftrace_function(&trace_probe_ops);
2361*bd69c30bSSteven Rostedt 	ftrace_startup(&global_ops, 0);
2362b6887d79SSteven Rostedt 	ftrace_probe_registered = 1;
236359df055fSSteven Rostedt }
236459df055fSSteven Rostedt 
2365b6887d79SSteven Rostedt static void __disable_ftrace_function_probe(void)
236659df055fSSteven Rostedt {
236759df055fSSteven Rostedt 	int i;
236859df055fSSteven Rostedt 
2369b6887d79SSteven Rostedt 	if (!ftrace_probe_registered)
237059df055fSSteven Rostedt 		return;
237159df055fSSteven Rostedt 
237259df055fSSteven Rostedt 	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
237359df055fSSteven Rostedt 		struct hlist_head *hhd = &ftrace_func_hash[i];
237459df055fSSteven Rostedt 		if (hhd->first)
237559df055fSSteven Rostedt 			return;
237659df055fSSteven Rostedt 	}
237759df055fSSteven Rostedt 
237859df055fSSteven Rostedt 	/* no more funcs left */
2379b6887d79SSteven Rostedt 	__unregister_ftrace_function(&trace_probe_ops);
2380*bd69c30bSSteven Rostedt 	ftrace_shutdown(&global_ops, 0);
2381b6887d79SSteven Rostedt 	ftrace_probe_registered = 0;
238259df055fSSteven Rostedt }
238359df055fSSteven Rostedt 
238459df055fSSteven Rostedt 
238559df055fSSteven Rostedt static void ftrace_free_entry_rcu(struct rcu_head *rhp)
238659df055fSSteven Rostedt {
2387b6887d79SSteven Rostedt 	struct ftrace_func_probe *entry =
2388b6887d79SSteven Rostedt 		container_of(rhp, struct ftrace_func_probe, rcu);
238959df055fSSteven Rostedt 
239059df055fSSteven Rostedt 	if (entry->ops->free)
239159df055fSSteven Rostedt 		entry->ops->free(&entry->data);
239259df055fSSteven Rostedt 	kfree(entry);
239359df055fSSteven Rostedt }
239459df055fSSteven Rostedt 
239559df055fSSteven Rostedt 
239659df055fSSteven Rostedt int
2397b6887d79SSteven Rostedt register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
239859df055fSSteven Rostedt 			      void *data)
239959df055fSSteven Rostedt {
2400b6887d79SSteven Rostedt 	struct ftrace_func_probe *entry;
240159df055fSSteven Rostedt 	struct ftrace_page *pg;
240259df055fSSteven Rostedt 	struct dyn_ftrace *rec;
240359df055fSSteven Rostedt 	int type, len, not;
24046a24a244SSteven Rostedt 	unsigned long key;
240559df055fSSteven Rostedt 	int count = 0;
240659df055fSSteven Rostedt 	char *search;
240759df055fSSteven Rostedt 
24083f6fe06dSFrederic Weisbecker 	type = filter_parse_regex(glob, strlen(glob), &search, &not);
240959df055fSSteven Rostedt 	len = strlen(search);
241059df055fSSteven Rostedt 
2411b6887d79SSteven Rostedt 	/* we do not support '!' for function probes */
241259df055fSSteven Rostedt 	if (WARN_ON(not))
241359df055fSSteven Rostedt 		return -EINVAL;
241459df055fSSteven Rostedt 
241559df055fSSteven Rostedt 	mutex_lock(&ftrace_lock);
241659df055fSSteven Rostedt 
241745a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
241845a4a237SSteven Rostedt 		goto out_unlock;
241945a4a237SSteven Rostedt 
242059df055fSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
242159df055fSSteven Rostedt 
2422b9df92d2SSteven Rostedt 		if (!ftrace_match_record(rec, NULL, search, len, type))
242359df055fSSteven Rostedt 			continue;
242459df055fSSteven Rostedt 
242559df055fSSteven Rostedt 		entry = kmalloc(sizeof(*entry), GFP_KERNEL);
242659df055fSSteven Rostedt 		if (!entry) {
2427b6887d79SSteven Rostedt 			/* If we did not process any, then return error */
242859df055fSSteven Rostedt 			if (!count)
242959df055fSSteven Rostedt 				count = -ENOMEM;
243059df055fSSteven Rostedt 			goto out_unlock;
243159df055fSSteven Rostedt 		}
243259df055fSSteven Rostedt 
243359df055fSSteven Rostedt 		count++;
243459df055fSSteven Rostedt 
243559df055fSSteven Rostedt 		entry->data = data;
243659df055fSSteven Rostedt 
243759df055fSSteven Rostedt 		/*
243859df055fSSteven Rostedt 		 * The caller might want to do something special
243959df055fSSteven Rostedt 		 * for each function we find. We call the callback
244059df055fSSteven Rostedt 		 * to give the caller an opportunity to do so.
244159df055fSSteven Rostedt 		 */
244259df055fSSteven Rostedt 		if (ops->callback) {
244359df055fSSteven Rostedt 			if (ops->callback(rec->ip, &entry->data) < 0) {
244459df055fSSteven Rostedt 				/* caller does not like this func */
244559df055fSSteven Rostedt 				kfree(entry);
244659df055fSSteven Rostedt 				continue;
244759df055fSSteven Rostedt 			}
244859df055fSSteven Rostedt 		}
244959df055fSSteven Rostedt 
245059df055fSSteven Rostedt 		entry->ops = ops;
245159df055fSSteven Rostedt 		entry->ip = rec->ip;
245259df055fSSteven Rostedt 
245359df055fSSteven Rostedt 		key = hash_long(entry->ip, FTRACE_HASH_BITS);
245459df055fSSteven Rostedt 		hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
245559df055fSSteven Rostedt 
245659df055fSSteven Rostedt 	} while_for_each_ftrace_rec();
2457b6887d79SSteven Rostedt 	__enable_ftrace_function_probe();
245859df055fSSteven Rostedt 
245959df055fSSteven Rostedt  out_unlock:
246059df055fSSteven Rostedt 	mutex_unlock(&ftrace_lock);
246159df055fSSteven Rostedt 
246259df055fSSteven Rostedt 	return count;
246359df055fSSteven Rostedt }
246459df055fSSteven Rostedt 
246559df055fSSteven Rostedt enum {
2466b6887d79SSteven Rostedt 	PROBE_TEST_FUNC		= 1,
2467b6887d79SSteven Rostedt 	PROBE_TEST_DATA		= 2
246859df055fSSteven Rostedt };
246959df055fSSteven Rostedt 
247059df055fSSteven Rostedt static void
2471b6887d79SSteven Rostedt __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
247259df055fSSteven Rostedt 				  void *data, int flags)
247359df055fSSteven Rostedt {
2474b6887d79SSteven Rostedt 	struct ftrace_func_probe *entry;
247559df055fSSteven Rostedt 	struct hlist_node *n, *tmp;
247659df055fSSteven Rostedt 	char str[KSYM_SYMBOL_LEN];
247759df055fSSteven Rostedt 	int type = MATCH_FULL;
247859df055fSSteven Rostedt 	int i, len = 0;
247959df055fSSteven Rostedt 	char *search;
248059df055fSSteven Rostedt 
2481b36461daSAtsushi Tsuji 	if (glob && (strcmp(glob, "*") == 0 || !strlen(glob)))
248259df055fSSteven Rostedt 		glob = NULL;
2483b36461daSAtsushi Tsuji 	else if (glob) {
248459df055fSSteven Rostedt 		int not;
248559df055fSSteven Rostedt 
24863f6fe06dSFrederic Weisbecker 		type = filter_parse_regex(glob, strlen(glob), &search, &not);
248759df055fSSteven Rostedt 		len = strlen(search);
248859df055fSSteven Rostedt 
2489b6887d79SSteven Rostedt 		/* we do not support '!' for function probes */
249059df055fSSteven Rostedt 		if (WARN_ON(not))
249159df055fSSteven Rostedt 			return;
249259df055fSSteven Rostedt 	}
249359df055fSSteven Rostedt 
249459df055fSSteven Rostedt 	mutex_lock(&ftrace_lock);
249559df055fSSteven Rostedt 	for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
249659df055fSSteven Rostedt 		struct hlist_head *hhd = &ftrace_func_hash[i];
249759df055fSSteven Rostedt 
249859df055fSSteven Rostedt 		hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
249959df055fSSteven Rostedt 
250059df055fSSteven Rostedt 			/* break up if statements for readability */
2501b6887d79SSteven Rostedt 			if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
250259df055fSSteven Rostedt 				continue;
250359df055fSSteven Rostedt 
2504b6887d79SSteven Rostedt 			if ((flags & PROBE_TEST_DATA) && entry->data != data)
250559df055fSSteven Rostedt 				continue;
250659df055fSSteven Rostedt 
250759df055fSSteven Rostedt 			/* do this last, since it is the most expensive */
250859df055fSSteven Rostedt 			if (glob) {
250959df055fSSteven Rostedt 				kallsyms_lookup(entry->ip, NULL, NULL,
251059df055fSSteven Rostedt 						NULL, str);
251159df055fSSteven Rostedt 				if (!ftrace_match(str, glob, len, type))
251259df055fSSteven Rostedt 					continue;
251359df055fSSteven Rostedt 			}
251459df055fSSteven Rostedt 
251559df055fSSteven Rostedt 			hlist_del(&entry->node);
251659df055fSSteven Rostedt 			call_rcu(&entry->rcu, ftrace_free_entry_rcu);
251759df055fSSteven Rostedt 		}
251859df055fSSteven Rostedt 	}
2519b6887d79SSteven Rostedt 	__disable_ftrace_function_probe();
252059df055fSSteven Rostedt 	mutex_unlock(&ftrace_lock);
252159df055fSSteven Rostedt }
252259df055fSSteven Rostedt 
252359df055fSSteven Rostedt void
2524b6887d79SSteven Rostedt unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
252559df055fSSteven Rostedt 				void *data)
252659df055fSSteven Rostedt {
2527b6887d79SSteven Rostedt 	__unregister_ftrace_function_probe(glob, ops, data,
2528b6887d79SSteven Rostedt 					  PROBE_TEST_FUNC | PROBE_TEST_DATA);
252959df055fSSteven Rostedt }
253059df055fSSteven Rostedt 
253159df055fSSteven Rostedt void
2532b6887d79SSteven Rostedt unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
253359df055fSSteven Rostedt {
2534b6887d79SSteven Rostedt 	__unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
253559df055fSSteven Rostedt }
253659df055fSSteven Rostedt 
2537b6887d79SSteven Rostedt void unregister_ftrace_function_probe_all(char *glob)
253859df055fSSteven Rostedt {
2539b6887d79SSteven Rostedt 	__unregister_ftrace_function_probe(glob, NULL, NULL, 0);
254059df055fSSteven Rostedt }
254159df055fSSteven Rostedt 
2542f6180773SSteven Rostedt static LIST_HEAD(ftrace_commands);
2543f6180773SSteven Rostedt static DEFINE_MUTEX(ftrace_cmd_mutex);
2544f6180773SSteven Rostedt 
2545f6180773SSteven Rostedt int register_ftrace_command(struct ftrace_func_command *cmd)
2546f6180773SSteven Rostedt {
2547f6180773SSteven Rostedt 	struct ftrace_func_command *p;
2548f6180773SSteven Rostedt 	int ret = 0;
2549f6180773SSteven Rostedt 
2550f6180773SSteven Rostedt 	mutex_lock(&ftrace_cmd_mutex);
2551f6180773SSteven Rostedt 	list_for_each_entry(p, &ftrace_commands, list) {
2552f6180773SSteven Rostedt 		if (strcmp(cmd->name, p->name) == 0) {
2553f6180773SSteven Rostedt 			ret = -EBUSY;
2554f6180773SSteven Rostedt 			goto out_unlock;
2555f6180773SSteven Rostedt 		}
2556f6180773SSteven Rostedt 	}
2557f6180773SSteven Rostedt 	list_add(&cmd->list, &ftrace_commands);
2558f6180773SSteven Rostedt  out_unlock:
2559f6180773SSteven Rostedt 	mutex_unlock(&ftrace_cmd_mutex);
2560f6180773SSteven Rostedt 
2561f6180773SSteven Rostedt 	return ret;
2562f6180773SSteven Rostedt }
2563f6180773SSteven Rostedt 
2564f6180773SSteven Rostedt int unregister_ftrace_command(struct ftrace_func_command *cmd)
2565f6180773SSteven Rostedt {
2566f6180773SSteven Rostedt 	struct ftrace_func_command *p, *n;
2567f6180773SSteven Rostedt 	int ret = -ENODEV;
2568f6180773SSteven Rostedt 
2569f6180773SSteven Rostedt 	mutex_lock(&ftrace_cmd_mutex);
2570f6180773SSteven Rostedt 	list_for_each_entry_safe(p, n, &ftrace_commands, list) {
2571f6180773SSteven Rostedt 		if (strcmp(cmd->name, p->name) == 0) {
2572f6180773SSteven Rostedt 			ret = 0;
2573f6180773SSteven Rostedt 			list_del_init(&p->list);
2574f6180773SSteven Rostedt 			goto out_unlock;
2575f6180773SSteven Rostedt 		}
2576f6180773SSteven Rostedt 	}
2577f6180773SSteven Rostedt  out_unlock:
2578f6180773SSteven Rostedt 	mutex_unlock(&ftrace_cmd_mutex);
2579f6180773SSteven Rostedt 
2580f6180773SSteven Rostedt 	return ret;
2581f6180773SSteven Rostedt }
2582f6180773SSteven Rostedt 
258333dc9b12SSteven Rostedt static int ftrace_process_regex(struct ftrace_hash *hash,
258433dc9b12SSteven Rostedt 				char *buff, int len, int enable)
258564e7c440SSteven Rostedt {
2586f6180773SSteven Rostedt 	char *func, *command, *next = buff;
25876a24a244SSteven Rostedt 	struct ftrace_func_command *p;
2588b448c4e3SSteven Rostedt 	int ret;
258964e7c440SSteven Rostedt 
259064e7c440SSteven Rostedt 	func = strsep(&next, ":");
259164e7c440SSteven Rostedt 
259264e7c440SSteven Rostedt 	if (!next) {
25931cf41dd7SSteven Rostedt 		ret = ftrace_match_records(hash, func, len);
2594b448c4e3SSteven Rostedt 		if (!ret)
2595b448c4e3SSteven Rostedt 			ret = -EINVAL;
2596b448c4e3SSteven Rostedt 		if (ret < 0)
2597311d16daSLi Zefan 			return ret;
2598b448c4e3SSteven Rostedt 		return 0;
259964e7c440SSteven Rostedt 	}
260064e7c440SSteven Rostedt 
2601f6180773SSteven Rostedt 	/* command found */
260264e7c440SSteven Rostedt 
260364e7c440SSteven Rostedt 	command = strsep(&next, ":");
260464e7c440SSteven Rostedt 
2605f6180773SSteven Rostedt 	mutex_lock(&ftrace_cmd_mutex);
2606f6180773SSteven Rostedt 	list_for_each_entry(p, &ftrace_commands, list) {
2607f6180773SSteven Rostedt 		if (strcmp(p->name, command) == 0) {
2608f6180773SSteven Rostedt 			ret = p->func(func, command, next, enable);
2609f6180773SSteven Rostedt 			goto out_unlock;
261064e7c440SSteven Rostedt 		}
2611f6180773SSteven Rostedt 	}
2612f6180773SSteven Rostedt  out_unlock:
2613f6180773SSteven Rostedt 	mutex_unlock(&ftrace_cmd_mutex);
261464e7c440SSteven Rostedt 
2615f6180773SSteven Rostedt 	return ret;
261664e7c440SSteven Rostedt }
261764e7c440SSteven Rostedt 
2618e309b41dSIngo Molnar static ssize_t
261941c52c0dSSteven Rostedt ftrace_regex_write(struct file *file, const char __user *ubuf,
262041c52c0dSSteven Rostedt 		   size_t cnt, loff_t *ppos, int enable)
26215072c59fSSteven Rostedt {
26225072c59fSSteven Rostedt 	struct ftrace_iterator *iter;
2623689fd8b6S[email protected] 	struct trace_parser *parser;
2624689fd8b6S[email protected] 	ssize_t ret, read;
26255072c59fSSteven Rostedt 
26264ba7978eSLi Zefan 	if (!cnt)
26275072c59fSSteven Rostedt 		return 0;
26285072c59fSSteven Rostedt 
262941c52c0dSSteven Rostedt 	mutex_lock(&ftrace_regex_lock);
26305072c59fSSteven Rostedt 
263145a4a237SSteven Rostedt 	ret = -ENODEV;
263245a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
263345a4a237SSteven Rostedt 		goto out_unlock;
263445a4a237SSteven Rostedt 
26355072c59fSSteven Rostedt 	if (file->f_mode & FMODE_READ) {
26365072c59fSSteven Rostedt 		struct seq_file *m = file->private_data;
26375072c59fSSteven Rostedt 		iter = m->private;
26385072c59fSSteven Rostedt 	} else
26395072c59fSSteven Rostedt 		iter = file->private_data;
26405072c59fSSteven Rostedt 
2641689fd8b6S[email protected] 	parser = &iter->parser;
2642689fd8b6S[email protected] 	read = trace_get_user(parser, ubuf, cnt, ppos);
26435072c59fSSteven Rostedt 
26444ba7978eSLi Zefan 	if (read >= 0 && trace_parser_loaded(parser) &&
2645689fd8b6S[email protected] 	    !trace_parser_cont(parser)) {
264633dc9b12SSteven Rostedt 		ret = ftrace_process_regex(iter->hash, parser->buffer,
2647689fd8b6S[email protected] 					   parser->idx, enable);
2648313254a9SLi Zefan 		trace_parser_clear(parser);
26495072c59fSSteven Rostedt 		if (ret)
2650ed146b25SLi Zefan 			goto out_unlock;
26515072c59fSSteven Rostedt 	}
26525072c59fSSteven Rostedt 
26535072c59fSSteven Rostedt 	ret = read;
2654ed146b25SLi Zefan out_unlock:
265541c52c0dSSteven Rostedt 	mutex_unlock(&ftrace_regex_lock);
2656ed146b25SLi Zefan 
26575072c59fSSteven Rostedt 	return ret;
26585072c59fSSteven Rostedt }
26595072c59fSSteven Rostedt 
266041c52c0dSSteven Rostedt static ssize_t
266141c52c0dSSteven Rostedt ftrace_filter_write(struct file *file, const char __user *ubuf,
266241c52c0dSSteven Rostedt 		    size_t cnt, loff_t *ppos)
266341c52c0dSSteven Rostedt {
266441c52c0dSSteven Rostedt 	return ftrace_regex_write(file, ubuf, cnt, ppos, 1);
266541c52c0dSSteven Rostedt }
266641c52c0dSSteven Rostedt 
266741c52c0dSSteven Rostedt static ssize_t
266841c52c0dSSteven Rostedt ftrace_notrace_write(struct file *file, const char __user *ubuf,
266941c52c0dSSteven Rostedt 		     size_t cnt, loff_t *ppos)
267041c52c0dSSteven Rostedt {
267141c52c0dSSteven Rostedt 	return ftrace_regex_write(file, ubuf, cnt, ppos, 0);
267241c52c0dSSteven Rostedt }
267341c52c0dSSteven Rostedt 
267433dc9b12SSteven Rostedt static int
2675f45948e8SSteven Rostedt ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len,
2676f45948e8SSteven Rostedt 		 int reset, int enable)
267741c52c0dSSteven Rostedt {
267833dc9b12SSteven Rostedt 	struct ftrace_hash **orig_hash;
2679f45948e8SSteven Rostedt 	struct ftrace_hash *hash;
268033dc9b12SSteven Rostedt 	int ret;
2681f45948e8SSteven Rostedt 
268241c52c0dSSteven Rostedt 	if (unlikely(ftrace_disabled))
268333dc9b12SSteven Rostedt 		return -ENODEV;
268441c52c0dSSteven Rostedt 
2685f45948e8SSteven Rostedt 	if (enable)
268633dc9b12SSteven Rostedt 		orig_hash = &ops->filter_hash;
2687f45948e8SSteven Rostedt 	else
268833dc9b12SSteven Rostedt 		orig_hash = &ops->notrace_hash;
268933dc9b12SSteven Rostedt 
269033dc9b12SSteven Rostedt 	hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash);
269133dc9b12SSteven Rostedt 	if (!hash)
269233dc9b12SSteven Rostedt 		return -ENOMEM;
2693f45948e8SSteven Rostedt 
269441c52c0dSSteven Rostedt 	mutex_lock(&ftrace_regex_lock);
269541c52c0dSSteven Rostedt 	if (reset)
26961cf41dd7SSteven Rostedt 		ftrace_filter_reset(hash);
269741c52c0dSSteven Rostedt 	if (buf)
26981cf41dd7SSteven Rostedt 		ftrace_match_records(hash, buf, len);
269933dc9b12SSteven Rostedt 
270033dc9b12SSteven Rostedt 	mutex_lock(&ftrace_lock);
270133dc9b12SSteven Rostedt 	ret = ftrace_hash_move(orig_hash, hash);
270233dc9b12SSteven Rostedt 	mutex_unlock(&ftrace_lock);
270333dc9b12SSteven Rostedt 
270441c52c0dSSteven Rostedt 	mutex_unlock(&ftrace_regex_lock);
270533dc9b12SSteven Rostedt 
270633dc9b12SSteven Rostedt 	free_ftrace_hash(hash);
270733dc9b12SSteven Rostedt 	return ret;
270841c52c0dSSteven Rostedt }
270941c52c0dSSteven Rostedt 
271077a2b37dSSteven Rostedt /**
271177a2b37dSSteven Rostedt  * ftrace_set_filter - set a function to filter on in ftrace
271277a2b37dSSteven Rostedt  * @buf - the string that holds the function filter text.
271377a2b37dSSteven Rostedt  * @len - the length of the string.
271477a2b37dSSteven Rostedt  * @reset - non zero to reset all filters before applying this filter.
271577a2b37dSSteven Rostedt  *
271677a2b37dSSteven Rostedt  * Filters denote which functions should be enabled when tracing is enabled.
271777a2b37dSSteven Rostedt  * If @buf is NULL and reset is set, all functions will be enabled for tracing.
271877a2b37dSSteven Rostedt  */
2719e309b41dSIngo Molnar void ftrace_set_filter(unsigned char *buf, int len, int reset)
272077a2b37dSSteven Rostedt {
2721f45948e8SSteven Rostedt 	ftrace_set_regex(&global_ops, buf, len, reset, 1);
272241c52c0dSSteven Rostedt }
27234eebcc81SSteven Rostedt 
272441c52c0dSSteven Rostedt /**
272541c52c0dSSteven Rostedt  * ftrace_set_notrace - set a function to not trace in ftrace
272641c52c0dSSteven Rostedt  * @buf - the string that holds the function notrace text.
272741c52c0dSSteven Rostedt  * @len - the length of the string.
272841c52c0dSSteven Rostedt  * @reset - non zero to reset all filters before applying this filter.
272941c52c0dSSteven Rostedt  *
273041c52c0dSSteven Rostedt  * Notrace Filters denote which functions should not be enabled when tracing
273141c52c0dSSteven Rostedt  * is enabled. If @buf is NULL and reset is set, all functions will be enabled
273241c52c0dSSteven Rostedt  * for tracing.
273341c52c0dSSteven Rostedt  */
273441c52c0dSSteven Rostedt void ftrace_set_notrace(unsigned char *buf, int len, int reset)
273541c52c0dSSteven Rostedt {
2736f45948e8SSteven Rostedt 	ftrace_set_regex(&global_ops, buf, len, reset, 0);
273777a2b37dSSteven Rostedt }
273877a2b37dSSteven Rostedt 
27392af15d6aSSteven Rostedt /*
27402af15d6aSSteven Rostedt  * command line interface to allow users to set filters on boot up.
27412af15d6aSSteven Rostedt  */
27422af15d6aSSteven Rostedt #define FTRACE_FILTER_SIZE		COMMAND_LINE_SIZE
27432af15d6aSSteven Rostedt static char ftrace_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
27442af15d6aSSteven Rostedt static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata;
27452af15d6aSSteven Rostedt 
27462af15d6aSSteven Rostedt static int __init set_ftrace_notrace(char *str)
27472af15d6aSSteven Rostedt {
27482af15d6aSSteven Rostedt 	strncpy(ftrace_notrace_buf, str, FTRACE_FILTER_SIZE);
27492af15d6aSSteven Rostedt 	return 1;
27502af15d6aSSteven Rostedt }
27512af15d6aSSteven Rostedt __setup("ftrace_notrace=", set_ftrace_notrace);
27522af15d6aSSteven Rostedt 
27532af15d6aSSteven Rostedt static int __init set_ftrace_filter(char *str)
27542af15d6aSSteven Rostedt {
27552af15d6aSSteven Rostedt 	strncpy(ftrace_filter_buf, str, FTRACE_FILTER_SIZE);
27562af15d6aSSteven Rostedt 	return 1;
27572af15d6aSSteven Rostedt }
27582af15d6aSSteven Rostedt __setup("ftrace_filter=", set_ftrace_filter);
27592af15d6aSSteven Rostedt 
2760369bc18fSStefan Assmann #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2761f6060f46SLai Jiangshan static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
2762801c29fdSSteven Rostedt static int ftrace_set_func(unsigned long *array, int *idx, char *buffer);
2763801c29fdSSteven Rostedt 
2764369bc18fSStefan Assmann static int __init set_graph_function(char *str)
2765369bc18fSStefan Assmann {
276606f43d66SFrederic Weisbecker 	strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
2767369bc18fSStefan Assmann 	return 1;
2768369bc18fSStefan Assmann }
2769369bc18fSStefan Assmann __setup("ftrace_graph_filter=", set_graph_function);
2770369bc18fSStefan Assmann 
2771369bc18fSStefan Assmann static void __init set_ftrace_early_graph(char *buf)
2772369bc18fSStefan Assmann {
2773369bc18fSStefan Assmann 	int ret;
2774369bc18fSStefan Assmann 	char *func;
2775369bc18fSStefan Assmann 
2776369bc18fSStefan Assmann 	while (buf) {
2777369bc18fSStefan Assmann 		func = strsep(&buf, ",");
2778369bc18fSStefan Assmann 		/* we allow only one expression at a time */
2779369bc18fSStefan Assmann 		ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
2780369bc18fSStefan Assmann 				      func);
2781369bc18fSStefan Assmann 		if (ret)
2782369bc18fSStefan Assmann 			printk(KERN_DEBUG "ftrace: function %s not "
2783369bc18fSStefan Assmann 					  "traceable\n", func);
2784369bc18fSStefan Assmann 	}
2785369bc18fSStefan Assmann }
2786369bc18fSStefan Assmann #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2787369bc18fSStefan Assmann 
2788f45948e8SSteven Rostedt static void __init
2789f45948e8SSteven Rostedt set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable)
27902af15d6aSSteven Rostedt {
27912af15d6aSSteven Rostedt 	char *func;
27922af15d6aSSteven Rostedt 
27932af15d6aSSteven Rostedt 	while (buf) {
27942af15d6aSSteven Rostedt 		func = strsep(&buf, ",");
2795f45948e8SSteven Rostedt 		ftrace_set_regex(ops, func, strlen(func), 0, enable);
27962af15d6aSSteven Rostedt 	}
27972af15d6aSSteven Rostedt }
27982af15d6aSSteven Rostedt 
27992af15d6aSSteven Rostedt static void __init set_ftrace_early_filters(void)
28002af15d6aSSteven Rostedt {
28012af15d6aSSteven Rostedt 	if (ftrace_filter_buf[0])
2802f45948e8SSteven Rostedt 		set_ftrace_early_filter(&global_ops, ftrace_filter_buf, 1);
28032af15d6aSSteven Rostedt 	if (ftrace_notrace_buf[0])
2804f45948e8SSteven Rostedt 		set_ftrace_early_filter(&global_ops, ftrace_notrace_buf, 0);
2805369bc18fSStefan Assmann #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2806369bc18fSStefan Assmann 	if (ftrace_graph_buf[0])
2807369bc18fSStefan Assmann 		set_ftrace_early_graph(ftrace_graph_buf);
2808369bc18fSStefan Assmann #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
28092af15d6aSSteven Rostedt }
28102af15d6aSSteven Rostedt 
2811e309b41dSIngo Molnar static int
28121cf41dd7SSteven Rostedt ftrace_regex_release(struct inode *inode, struct file *file)
28135072c59fSSteven Rostedt {
28145072c59fSSteven Rostedt 	struct seq_file *m = (struct seq_file *)file->private_data;
28155072c59fSSteven Rostedt 	struct ftrace_iterator *iter;
281633dc9b12SSteven Rostedt 	struct ftrace_hash **orig_hash;
2817689fd8b6S[email protected] 	struct trace_parser *parser;
2818ed926f9bSSteven Rostedt 	int filter_hash;
281933dc9b12SSteven Rostedt 	int ret;
28205072c59fSSteven Rostedt 
282141c52c0dSSteven Rostedt 	mutex_lock(&ftrace_regex_lock);
28225072c59fSSteven Rostedt 	if (file->f_mode & FMODE_READ) {
28235072c59fSSteven Rostedt 		iter = m->private;
28245072c59fSSteven Rostedt 
28255072c59fSSteven Rostedt 		seq_release(inode, file);
28265072c59fSSteven Rostedt 	} else
28275072c59fSSteven Rostedt 		iter = file->private_data;
28285072c59fSSteven Rostedt 
2829689fd8b6S[email protected] 	parser = &iter->parser;
2830689fd8b6S[email protected] 	if (trace_parser_loaded(parser)) {
2831689fd8b6S[email protected] 		parser->buffer[parser->idx] = 0;
28321cf41dd7SSteven Rostedt 		ftrace_match_records(iter->hash, parser->buffer, parser->idx);
28335072c59fSSteven Rostedt 	}
28345072c59fSSteven Rostedt 
2835058e297dSSteven Rostedt 	trace_parser_put(parser);
2836058e297dSSteven Rostedt 
2837058e297dSSteven Rostedt 	if (file->f_mode & FMODE_WRITE) {
2838ed926f9bSSteven Rostedt 		filter_hash = !!(iter->flags & FTRACE_ITER_FILTER);
2839ed926f9bSSteven Rostedt 
2840ed926f9bSSteven Rostedt 		if (filter_hash)
284133dc9b12SSteven Rostedt 			orig_hash = &iter->ops->filter_hash;
2842ed926f9bSSteven Rostedt 		else
2843ed926f9bSSteven Rostedt 			orig_hash = &iter->ops->notrace_hash;
284433dc9b12SSteven Rostedt 
2845e6ea44e9SSteven Rostedt 		mutex_lock(&ftrace_lock);
2846ed926f9bSSteven Rostedt 		/*
2847ed926f9bSSteven Rostedt 		 * Remove the current set, update the hash and add
2848ed926f9bSSteven Rostedt 		 * them back.
2849ed926f9bSSteven Rostedt 		 */
2850ed926f9bSSteven Rostedt 		ftrace_hash_rec_disable(iter->ops, filter_hash);
285133dc9b12SSteven Rostedt 		ret = ftrace_hash_move(orig_hash, iter->hash);
2852ed926f9bSSteven Rostedt 		if (!ret) {
2853ed926f9bSSteven Rostedt 			ftrace_hash_rec_enable(iter->ops, filter_hash);
2854ed926f9bSSteven Rostedt 			if (iter->ops->flags & FTRACE_OPS_FL_ENABLED
2855ed926f9bSSteven Rostedt 			    && ftrace_enabled)
28565072c59fSSteven Rostedt 				ftrace_run_update_code(FTRACE_ENABLE_CALLS);
2857ed926f9bSSteven Rostedt 		}
2858e6ea44e9SSteven Rostedt 		mutex_unlock(&ftrace_lock);
2859058e297dSSteven Rostedt 	}
286033dc9b12SSteven Rostedt 	free_ftrace_hash(iter->hash);
286133dc9b12SSteven Rostedt 	kfree(iter);
2862689fd8b6S[email protected] 
286341c52c0dSSteven Rostedt 	mutex_unlock(&ftrace_regex_lock);
28645072c59fSSteven Rostedt 	return 0;
28655072c59fSSteven Rostedt }
28665072c59fSSteven Rostedt 
28675e2336a0SSteven Rostedt static const struct file_operations ftrace_avail_fops = {
28685072c59fSSteven Rostedt 	.open = ftrace_avail_open,
28695072c59fSSteven Rostedt 	.read = seq_read,
28705072c59fSSteven Rostedt 	.llseek = seq_lseek,
28713be04b47SLi Zefan 	.release = seq_release_private,
28725072c59fSSteven Rostedt };
28735072c59fSSteven Rostedt 
2874647bcd03SSteven Rostedt static const struct file_operations ftrace_enabled_fops = {
2875647bcd03SSteven Rostedt 	.open = ftrace_enabled_open,
2876647bcd03SSteven Rostedt 	.read = seq_read,
2877647bcd03SSteven Rostedt 	.llseek = seq_lseek,
2878647bcd03SSteven Rostedt 	.release = seq_release_private,
2879647bcd03SSteven Rostedt };
2880647bcd03SSteven Rostedt 
28815e2336a0SSteven Rostedt static const struct file_operations ftrace_filter_fops = {
28825072c59fSSteven Rostedt 	.open = ftrace_filter_open,
2883850a80cfSLai Jiangshan 	.read = seq_read,
28845072c59fSSteven Rostedt 	.write = ftrace_filter_write,
288598c4fd04SSteven Rostedt 	.llseek = ftrace_regex_lseek,
28861cf41dd7SSteven Rostedt 	.release = ftrace_regex_release,
28875072c59fSSteven Rostedt };
28885072c59fSSteven Rostedt 
28895e2336a0SSteven Rostedt static const struct file_operations ftrace_notrace_fops = {
289041c52c0dSSteven Rostedt 	.open = ftrace_notrace_open,
2891850a80cfSLai Jiangshan 	.read = seq_read,
289241c52c0dSSteven Rostedt 	.write = ftrace_notrace_write,
289341c52c0dSSteven Rostedt 	.llseek = ftrace_regex_lseek,
28941cf41dd7SSteven Rostedt 	.release = ftrace_regex_release,
289541c52c0dSSteven Rostedt };
289641c52c0dSSteven Rostedt 
2897ea4e2bc4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
2898ea4e2bc4SSteven Rostedt 
2899ea4e2bc4SSteven Rostedt static DEFINE_MUTEX(graph_lock);
2900ea4e2bc4SSteven Rostedt 
2901ea4e2bc4SSteven Rostedt int ftrace_graph_count;
2902c7c6b1feSLi Zefan int ftrace_graph_filter_enabled;
2903ea4e2bc4SSteven Rostedt unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
2904ea4e2bc4SSteven Rostedt 
2905ea4e2bc4SSteven Rostedt static void *
290685951842SLi Zefan __g_next(struct seq_file *m, loff_t *pos)
2907ea4e2bc4SSteven Rostedt {
290885951842SLi Zefan 	if (*pos >= ftrace_graph_count)
2909ea4e2bc4SSteven Rostedt 		return NULL;
2910a4ec5e0cSLi Zefan 	return &ftrace_graph_funcs[*pos];
291185951842SLi Zefan }
2912ea4e2bc4SSteven Rostedt 
291385951842SLi Zefan static void *
291485951842SLi Zefan g_next(struct seq_file *m, void *v, loff_t *pos)
291585951842SLi Zefan {
291685951842SLi Zefan 	(*pos)++;
291785951842SLi Zefan 	return __g_next(m, pos);
2918ea4e2bc4SSteven Rostedt }
2919ea4e2bc4SSteven Rostedt 
2920ea4e2bc4SSteven Rostedt static void *g_start(struct seq_file *m, loff_t *pos)
2921ea4e2bc4SSteven Rostedt {
2922ea4e2bc4SSteven Rostedt 	mutex_lock(&graph_lock);
2923ea4e2bc4SSteven Rostedt 
2924f9349a8fSFrederic Weisbecker 	/* Nothing, tell g_show to print all functions are enabled */
2925c7c6b1feSLi Zefan 	if (!ftrace_graph_filter_enabled && !*pos)
2926f9349a8fSFrederic Weisbecker 		return (void *)1;
2927f9349a8fSFrederic Weisbecker 
292885951842SLi Zefan 	return __g_next(m, pos);
2929ea4e2bc4SSteven Rostedt }
2930ea4e2bc4SSteven Rostedt 
2931ea4e2bc4SSteven Rostedt static void g_stop(struct seq_file *m, void *p)
2932ea4e2bc4SSteven Rostedt {
2933ea4e2bc4SSteven Rostedt 	mutex_unlock(&graph_lock);
2934ea4e2bc4SSteven Rostedt }
2935ea4e2bc4SSteven Rostedt 
2936ea4e2bc4SSteven Rostedt static int g_show(struct seq_file *m, void *v)
2937ea4e2bc4SSteven Rostedt {
2938ea4e2bc4SSteven Rostedt 	unsigned long *ptr = v;
2939ea4e2bc4SSteven Rostedt 
2940ea4e2bc4SSteven Rostedt 	if (!ptr)
2941ea4e2bc4SSteven Rostedt 		return 0;
2942ea4e2bc4SSteven Rostedt 
2943f9349a8fSFrederic Weisbecker 	if (ptr == (unsigned long *)1) {
2944f9349a8fSFrederic Weisbecker 		seq_printf(m, "#### all functions enabled ####\n");
2945f9349a8fSFrederic Weisbecker 		return 0;
2946f9349a8fSFrederic Weisbecker 	}
2947f9349a8fSFrederic Weisbecker 
2948b375a11aSSteven Rostedt 	seq_printf(m, "%ps\n", (void *)*ptr);
2949ea4e2bc4SSteven Rostedt 
2950ea4e2bc4SSteven Rostedt 	return 0;
2951ea4e2bc4SSteven Rostedt }
2952ea4e2bc4SSteven Rostedt 
295388e9d34cSJames Morris static const struct seq_operations ftrace_graph_seq_ops = {
2954ea4e2bc4SSteven Rostedt 	.start = g_start,
2955ea4e2bc4SSteven Rostedt 	.next = g_next,
2956ea4e2bc4SSteven Rostedt 	.stop = g_stop,
2957ea4e2bc4SSteven Rostedt 	.show = g_show,
2958ea4e2bc4SSteven Rostedt };
2959ea4e2bc4SSteven Rostedt 
2960ea4e2bc4SSteven Rostedt static int
2961ea4e2bc4SSteven Rostedt ftrace_graph_open(struct inode *inode, struct file *file)
2962ea4e2bc4SSteven Rostedt {
2963ea4e2bc4SSteven Rostedt 	int ret = 0;
2964ea4e2bc4SSteven Rostedt 
2965ea4e2bc4SSteven Rostedt 	if (unlikely(ftrace_disabled))
2966ea4e2bc4SSteven Rostedt 		return -ENODEV;
2967ea4e2bc4SSteven Rostedt 
2968ea4e2bc4SSteven Rostedt 	mutex_lock(&graph_lock);
2969ea4e2bc4SSteven Rostedt 	if ((file->f_mode & FMODE_WRITE) &&
29708650ae32SSteven Rostedt 	    (file->f_flags & O_TRUNC)) {
2971c7c6b1feSLi Zefan 		ftrace_graph_filter_enabled = 0;
2972ea4e2bc4SSteven Rostedt 		ftrace_graph_count = 0;
2973ea4e2bc4SSteven Rostedt 		memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
2974ea4e2bc4SSteven Rostedt 	}
2975ea4e2bc4SSteven Rostedt 	mutex_unlock(&graph_lock);
2976ea4e2bc4SSteven Rostedt 
2977a4ec5e0cSLi Zefan 	if (file->f_mode & FMODE_READ)
2978a4ec5e0cSLi Zefan 		ret = seq_open(file, &ftrace_graph_seq_ops);
2979a4ec5e0cSLi Zefan 
2980ea4e2bc4SSteven Rostedt 	return ret;
2981ea4e2bc4SSteven Rostedt }
2982ea4e2bc4SSteven Rostedt 
2983ea4e2bc4SSteven Rostedt static int
298487827111SLi Zefan ftrace_graph_release(struct inode *inode, struct file *file)
298587827111SLi Zefan {
298687827111SLi Zefan 	if (file->f_mode & FMODE_READ)
298787827111SLi Zefan 		seq_release(inode, file);
298887827111SLi Zefan 	return 0;
298987827111SLi Zefan }
299087827111SLi Zefan 
299187827111SLi Zefan static int
2992f9349a8fSFrederic Weisbecker ftrace_set_func(unsigned long *array, int *idx, char *buffer)
2993ea4e2bc4SSteven Rostedt {
2994ea4e2bc4SSteven Rostedt 	struct dyn_ftrace *rec;
2995ea4e2bc4SSteven Rostedt 	struct ftrace_page *pg;
2996f9349a8fSFrederic Weisbecker 	int search_len;
2997c7c6b1feSLi Zefan 	int fail = 1;
2998f9349a8fSFrederic Weisbecker 	int type, not;
2999f9349a8fSFrederic Weisbecker 	char *search;
3000f9349a8fSFrederic Weisbecker 	bool exists;
3001f9349a8fSFrederic Weisbecker 	int i;
3002ea4e2bc4SSteven Rostedt 
3003f9349a8fSFrederic Weisbecker 	/* decode regex */
30043f6fe06dSFrederic Weisbecker 	type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
3005c7c6b1feSLi Zefan 	if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS)
3006c7c6b1feSLi Zefan 		return -EBUSY;
3007f9349a8fSFrederic Weisbecker 
3008f9349a8fSFrederic Weisbecker 	search_len = strlen(search);
3009f9349a8fSFrederic Weisbecker 
301052baf119SSteven Rostedt 	mutex_lock(&ftrace_lock);
301145a4a237SSteven Rostedt 
301245a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled)) {
301345a4a237SSteven Rostedt 		mutex_unlock(&ftrace_lock);
301445a4a237SSteven Rostedt 		return -ENODEV;
301545a4a237SSteven Rostedt 	}
301645a4a237SSteven Rostedt 
3017265c831cSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
3018ea4e2bc4SSteven Rostedt 
301945a4a237SSteven Rostedt 		if (rec->flags & FTRACE_FL_FREE)
3020ea4e2bc4SSteven Rostedt 			continue;
3021ea4e2bc4SSteven Rostedt 
3022b9df92d2SSteven Rostedt 		if (ftrace_match_record(rec, NULL, search, search_len, type)) {
3023c7c6b1feSLi Zefan 			/* if it is in the array */
3024f9349a8fSFrederic Weisbecker 			exists = false;
3025c7c6b1feSLi Zefan 			for (i = 0; i < *idx; i++) {
3026f9349a8fSFrederic Weisbecker 				if (array[i] == rec->ip) {
3027f9349a8fSFrederic Weisbecker 					exists = true;
3028faec2ec5SLiming Wang 					break;
3029faec2ec5SLiming Wang 				}
3030c7c6b1feSLi Zefan 			}
3031c7c6b1feSLi Zefan 
3032c7c6b1feSLi Zefan 			if (!not) {
3033c7c6b1feSLi Zefan 				fail = 0;
3034c7c6b1feSLi Zefan 				if (!exists) {
3035f9349a8fSFrederic Weisbecker 					array[(*idx)++] = rec->ip;
3036c7c6b1feSLi Zefan 					if (*idx >= FTRACE_GRAPH_MAX_FUNCS)
3037c7c6b1feSLi Zefan 						goto out;
3038c7c6b1feSLi Zefan 				}
3039c7c6b1feSLi Zefan 			} else {
3040c7c6b1feSLi Zefan 				if (exists) {
3041c7c6b1feSLi Zefan 					array[i] = array[--(*idx)];
3042c7c6b1feSLi Zefan 					array[*idx] = 0;
3043c7c6b1feSLi Zefan 					fail = 0;
3044c7c6b1feSLi Zefan 				}
3045c7c6b1feSLi Zefan 			}
3046f9349a8fSFrederic Weisbecker 		}
3047265c831cSSteven Rostedt 	} while_for_each_ftrace_rec();
3048c7c6b1feSLi Zefan out:
304952baf119SSteven Rostedt 	mutex_unlock(&ftrace_lock);
3050ea4e2bc4SSteven Rostedt 
3051c7c6b1feSLi Zefan 	if (fail)
3052c7c6b1feSLi Zefan 		return -EINVAL;
3053c7c6b1feSLi Zefan 
3054c7c6b1feSLi Zefan 	ftrace_graph_filter_enabled = 1;
3055c7c6b1feSLi Zefan 	return 0;
3056ea4e2bc4SSteven Rostedt }
3057ea4e2bc4SSteven Rostedt 
3058ea4e2bc4SSteven Rostedt static ssize_t
3059ea4e2bc4SSteven Rostedt ftrace_graph_write(struct file *file, const char __user *ubuf,
3060ea4e2bc4SSteven Rostedt 		   size_t cnt, loff_t *ppos)
3061ea4e2bc4SSteven Rostedt {
3062689fd8b6S[email protected] 	struct trace_parser parser;
30634ba7978eSLi Zefan 	ssize_t read, ret;
3064ea4e2bc4SSteven Rostedt 
3065c7c6b1feSLi Zefan 	if (!cnt)
3066ea4e2bc4SSteven Rostedt 		return 0;
3067ea4e2bc4SSteven Rostedt 
3068ea4e2bc4SSteven Rostedt 	mutex_lock(&graph_lock);
3069ea4e2bc4SSteven Rostedt 
3070689fd8b6S[email protected] 	if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
3071689fd8b6S[email protected] 		ret = -ENOMEM;
30721eb90f13SLi Zefan 		goto out_unlock;
3073ea4e2bc4SSteven Rostedt 	}
3074ea4e2bc4SSteven Rostedt 
3075689fd8b6S[email protected] 	read = trace_get_user(&parser, ubuf, cnt, ppos);
3076689fd8b6S[email protected] 
30774ba7978eSLi Zefan 	if (read >= 0 && trace_parser_loaded((&parser))) {
3078689fd8b6S[email protected] 		parser.buffer[parser.idx] = 0;
3079ea4e2bc4SSteven Rostedt 
3080f9349a8fSFrederic Weisbecker 		/* we allow only one expression at a time */
3081a4ec5e0cSLi Zefan 		ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
3082689fd8b6S[email protected] 					parser.buffer);
3083ea4e2bc4SSteven Rostedt 		if (ret)
30841eb90f13SLi Zefan 			goto out_free;
3085689fd8b6S[email protected] 	}
3086ea4e2bc4SSteven Rostedt 
3087ea4e2bc4SSteven Rostedt 	ret = read;
30881eb90f13SLi Zefan 
30891eb90f13SLi Zefan out_free:
3090689fd8b6S[email protected] 	trace_parser_put(&parser);
30911eb90f13SLi Zefan out_unlock:
3092ea4e2bc4SSteven Rostedt 	mutex_unlock(&graph_lock);
3093ea4e2bc4SSteven Rostedt 
3094ea4e2bc4SSteven Rostedt 	return ret;
3095ea4e2bc4SSteven Rostedt }
3096ea4e2bc4SSteven Rostedt 
3097ea4e2bc4SSteven Rostedt static const struct file_operations ftrace_graph_fops = {
3098ea4e2bc4SSteven Rostedt 	.open		= ftrace_graph_open,
3099850a80cfSLai Jiangshan 	.read		= seq_read,
3100ea4e2bc4SSteven Rostedt 	.write		= ftrace_graph_write,
310187827111SLi Zefan 	.release	= ftrace_graph_release,
31026038f373SArnd Bergmann 	.llseek		= seq_lseek,
3103ea4e2bc4SSteven Rostedt };
3104ea4e2bc4SSteven Rostedt #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
3105ea4e2bc4SSteven Rostedt 
3106df4fc315SSteven Rostedt static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
31075072c59fSSteven Rostedt {
31085072c59fSSteven Rostedt 
31095452af66SFrederic Weisbecker 	trace_create_file("available_filter_functions", 0444,
31105072c59fSSteven Rostedt 			d_tracer, NULL, &ftrace_avail_fops);
31115072c59fSSteven Rostedt 
3112647bcd03SSteven Rostedt 	trace_create_file("enabled_functions", 0444,
3113647bcd03SSteven Rostedt 			d_tracer, NULL, &ftrace_enabled_fops);
3114647bcd03SSteven Rostedt 
31155452af66SFrederic Weisbecker 	trace_create_file("set_ftrace_filter", 0644, d_tracer,
31165072c59fSSteven Rostedt 			NULL, &ftrace_filter_fops);
311741c52c0dSSteven Rostedt 
31185452af66SFrederic Weisbecker 	trace_create_file("set_ftrace_notrace", 0644, d_tracer,
311941c52c0dSSteven Rostedt 				    NULL, &ftrace_notrace_fops);
3120ad90c0e3SSteven Rostedt 
3121ea4e2bc4SSteven Rostedt #ifdef CONFIG_FUNCTION_GRAPH_TRACER
31225452af66SFrederic Weisbecker 	trace_create_file("set_graph_function", 0444, d_tracer,
3123ea4e2bc4SSteven Rostedt 				    NULL,
3124ea4e2bc4SSteven Rostedt 				    &ftrace_graph_fops);
3125ea4e2bc4SSteven Rostedt #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
3126ea4e2bc4SSteven Rostedt 
31275072c59fSSteven Rostedt 	return 0;
31285072c59fSSteven Rostedt }
31295072c59fSSteven Rostedt 
31305cb084bbSJiri Olsa static int ftrace_process_locs(struct module *mod,
313131e88909SSteven Rostedt 			       unsigned long *start,
313268bf21aaSSteven Rostedt 			       unsigned long *end)
313368bf21aaSSteven Rostedt {
313468bf21aaSSteven Rostedt 	unsigned long *p;
313568bf21aaSSteven Rostedt 	unsigned long addr;
313668bf21aaSSteven Rostedt 
3137e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
313868bf21aaSSteven Rostedt 	p = start;
313968bf21aaSSteven Rostedt 	while (p < end) {
314068bf21aaSSteven Rostedt 		addr = ftrace_call_adjust(*p++);
314120e5227eSSteven Rostedt 		/*
314220e5227eSSteven Rostedt 		 * Some architecture linkers will pad between
314320e5227eSSteven Rostedt 		 * the different mcount_loc sections of different
314420e5227eSSteven Rostedt 		 * object files to satisfy alignments.
314520e5227eSSteven Rostedt 		 * Skip any NULL pointers.
314620e5227eSSteven Rostedt 		 */
314720e5227eSSteven Rostedt 		if (!addr)
314820e5227eSSteven Rostedt 			continue;
314968bf21aaSSteven Rostedt 		ftrace_record_ip(addr);
315068bf21aaSSteven Rostedt 	}
315168bf21aaSSteven Rostedt 
315231e88909SSteven Rostedt 	ftrace_update_code(mod);
3153e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
315468bf21aaSSteven Rostedt 
315568bf21aaSSteven Rostedt 	return 0;
315668bf21aaSSteven Rostedt }
315768bf21aaSSteven Rostedt 
315893eb677dSSteven Rostedt #ifdef CONFIG_MODULES
3159e7247a15S[email protected] void ftrace_release_mod(struct module *mod)
316093eb677dSSteven Rostedt {
316193eb677dSSteven Rostedt 	struct dyn_ftrace *rec;
316293eb677dSSteven Rostedt 	struct ftrace_page *pg;
316393eb677dSSteven Rostedt 
316493eb677dSSteven Rostedt 	mutex_lock(&ftrace_lock);
316545a4a237SSteven Rostedt 
316645a4a237SSteven Rostedt 	if (ftrace_disabled)
316745a4a237SSteven Rostedt 		goto out_unlock;
316845a4a237SSteven Rostedt 
316993eb677dSSteven Rostedt 	do_for_each_ftrace_rec(pg, rec) {
3170e7247a15S[email protected] 		if (within_module_core(rec->ip, mod)) {
317193eb677dSSteven Rostedt 			/*
317293eb677dSSteven Rostedt 			 * rec->ip is changed in ftrace_free_rec()
317393eb677dSSteven Rostedt 			 * It should not between s and e if record was freed.
317493eb677dSSteven Rostedt 			 */
317593eb677dSSteven Rostedt 			FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE);
317693eb677dSSteven Rostedt 			ftrace_free_rec(rec);
317793eb677dSSteven Rostedt 		}
317893eb677dSSteven Rostedt 	} while_for_each_ftrace_rec();
317945a4a237SSteven Rostedt  out_unlock:
318093eb677dSSteven Rostedt 	mutex_unlock(&ftrace_lock);
318193eb677dSSteven Rostedt }
318293eb677dSSteven Rostedt 
318393eb677dSSteven Rostedt static void ftrace_init_module(struct module *mod,
318431e88909SSteven Rostedt 			       unsigned long *start, unsigned long *end)
318590d595feSSteven Rostedt {
318600fd61aeSSteven Rostedt 	if (ftrace_disabled || start == end)
3187fed1939cSSteven Rostedt 		return;
31885cb084bbSJiri Olsa 	ftrace_process_locs(mod, start, end);
318990d595feSSteven Rostedt }
319090d595feSSteven Rostedt 
319193eb677dSSteven Rostedt static int ftrace_module_notify(struct notifier_block *self,
319293eb677dSSteven Rostedt 				unsigned long val, void *data)
319393eb677dSSteven Rostedt {
319493eb677dSSteven Rostedt 	struct module *mod = data;
319593eb677dSSteven Rostedt 
319693eb677dSSteven Rostedt 	switch (val) {
319793eb677dSSteven Rostedt 	case MODULE_STATE_COMING:
319893eb677dSSteven Rostedt 		ftrace_init_module(mod, mod->ftrace_callsites,
319993eb677dSSteven Rostedt 				   mod->ftrace_callsites +
320093eb677dSSteven Rostedt 				   mod->num_ftrace_callsites);
320193eb677dSSteven Rostedt 		break;
320293eb677dSSteven Rostedt 	case MODULE_STATE_GOING:
3203e7247a15S[email protected] 		ftrace_release_mod(mod);
320493eb677dSSteven Rostedt 		break;
320593eb677dSSteven Rostedt 	}
320693eb677dSSteven Rostedt 
320793eb677dSSteven Rostedt 	return 0;
320893eb677dSSteven Rostedt }
320993eb677dSSteven Rostedt #else
321093eb677dSSteven Rostedt static int ftrace_module_notify(struct notifier_block *self,
321193eb677dSSteven Rostedt 				unsigned long val, void *data)
321293eb677dSSteven Rostedt {
321393eb677dSSteven Rostedt 	return 0;
321493eb677dSSteven Rostedt }
321593eb677dSSteven Rostedt #endif /* CONFIG_MODULES */
321693eb677dSSteven Rostedt 
321793eb677dSSteven Rostedt struct notifier_block ftrace_module_nb = {
321893eb677dSSteven Rostedt 	.notifier_call = ftrace_module_notify,
321993eb677dSSteven Rostedt 	.priority = 0,
322093eb677dSSteven Rostedt };
322193eb677dSSteven Rostedt 
322268bf21aaSSteven Rostedt extern unsigned long __start_mcount_loc[];
322368bf21aaSSteven Rostedt extern unsigned long __stop_mcount_loc[];
322468bf21aaSSteven Rostedt 
322568bf21aaSSteven Rostedt void __init ftrace_init(void)
322668bf21aaSSteven Rostedt {
322768bf21aaSSteven Rostedt 	unsigned long count, addr, flags;
322868bf21aaSSteven Rostedt 	int ret;
322968bf21aaSSteven Rostedt 
323068bf21aaSSteven Rostedt 	/* Keep the ftrace pointer to the stub */
323168bf21aaSSteven Rostedt 	addr = (unsigned long)ftrace_stub;
323268bf21aaSSteven Rostedt 
323368bf21aaSSteven Rostedt 	local_irq_save(flags);
323468bf21aaSSteven Rostedt 	ftrace_dyn_arch_init(&addr);
323568bf21aaSSteven Rostedt 	local_irq_restore(flags);
323668bf21aaSSteven Rostedt 
323768bf21aaSSteven Rostedt 	/* ftrace_dyn_arch_init places the return code in addr */
323868bf21aaSSteven Rostedt 	if (addr)
323968bf21aaSSteven Rostedt 		goto failed;
324068bf21aaSSteven Rostedt 
324168bf21aaSSteven Rostedt 	count = __stop_mcount_loc - __start_mcount_loc;
324268bf21aaSSteven Rostedt 
324368bf21aaSSteven Rostedt 	ret = ftrace_dyn_table_alloc(count);
324468bf21aaSSteven Rostedt 	if (ret)
324568bf21aaSSteven Rostedt 		goto failed;
324668bf21aaSSteven Rostedt 
324768bf21aaSSteven Rostedt 	last_ftrace_enabled = ftrace_enabled = 1;
324868bf21aaSSteven Rostedt 
32495cb084bbSJiri Olsa 	ret = ftrace_process_locs(NULL,
325031e88909SSteven Rostedt 				  __start_mcount_loc,
325168bf21aaSSteven Rostedt 				  __stop_mcount_loc);
325268bf21aaSSteven Rostedt 
325393eb677dSSteven Rostedt 	ret = register_module_notifier(&ftrace_module_nb);
325424ed0c4bSMing Lei 	if (ret)
325593eb677dSSteven Rostedt 		pr_warning("Failed to register trace ftrace module notifier\n");
325693eb677dSSteven Rostedt 
32572af15d6aSSteven Rostedt 	set_ftrace_early_filters();
32582af15d6aSSteven Rostedt 
325968bf21aaSSteven Rostedt 	return;
326068bf21aaSSteven Rostedt  failed:
326168bf21aaSSteven Rostedt 	ftrace_disabled = 1;
326268bf21aaSSteven Rostedt }
326368bf21aaSSteven Rostedt 
32643d083395SSteven Rostedt #else
32650b6e4d56SFrederic Weisbecker 
3266*bd69c30bSSteven Rostedt struct ftrace_ops global_ops = {
3267*bd69c30bSSteven Rostedt 	.func			= ftrace_stub,
3268*bd69c30bSSteven Rostedt };
3269*bd69c30bSSteven Rostedt 
32700b6e4d56SFrederic Weisbecker static int __init ftrace_nodyn_init(void)
32710b6e4d56SFrederic Weisbecker {
32720b6e4d56SFrederic Weisbecker 	ftrace_enabled = 1;
32730b6e4d56SFrederic Weisbecker 	return 0;
32740b6e4d56SFrederic Weisbecker }
32750b6e4d56SFrederic Weisbecker device_initcall(ftrace_nodyn_init);
32760b6e4d56SFrederic Weisbecker 
3277df4fc315SSteven Rostedt static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
3278df4fc315SSteven Rostedt static inline void ftrace_startup_enable(int command) { }
32795a45cfe1SSteven Rostedt /* Keep as macros so we do not need to define the commands */
3280*bd69c30bSSteven Rostedt # define ftrace_startup(ops, command)	do { } while (0)
3281*bd69c30bSSteven Rostedt # define ftrace_shutdown(ops, command)	do { } while (0)
3282b0fc494fSSteven Rostedt # define ftrace_startup_sysctl()	do { } while (0)
3283b0fc494fSSteven Rostedt # define ftrace_shutdown_sysctl()	do { } while (0)
32843d083395SSteven Rostedt #endif /* CONFIG_DYNAMIC_FTRACE */
32853d083395SSteven Rostedt 
3286e32d8956SSteven Rostedt static void clear_ftrace_swapper(void)
3287e32d8956SSteven Rostedt {
3288e32d8956SSteven Rostedt 	struct task_struct *p;
3289e32d8956SSteven Rostedt 	int cpu;
3290e32d8956SSteven Rostedt 
3291e32d8956SSteven Rostedt 	get_online_cpus();
3292e32d8956SSteven Rostedt 	for_each_online_cpu(cpu) {
3293e32d8956SSteven Rostedt 		p = idle_task(cpu);
3294e32d8956SSteven Rostedt 		clear_tsk_trace_trace(p);
3295e32d8956SSteven Rostedt 	}
3296e32d8956SSteven Rostedt 	put_online_cpus();
3297e32d8956SSteven Rostedt }
3298e32d8956SSteven Rostedt 
3299e32d8956SSteven Rostedt static void set_ftrace_swapper(void)
3300e32d8956SSteven Rostedt {
3301e32d8956SSteven Rostedt 	struct task_struct *p;
3302e32d8956SSteven Rostedt 	int cpu;
3303e32d8956SSteven Rostedt 
3304e32d8956SSteven Rostedt 	get_online_cpus();
3305e32d8956SSteven Rostedt 	for_each_online_cpu(cpu) {
3306e32d8956SSteven Rostedt 		p = idle_task(cpu);
3307e32d8956SSteven Rostedt 		set_tsk_trace_trace(p);
3308e32d8956SSteven Rostedt 	}
3309e32d8956SSteven Rostedt 	put_online_cpus();
3310e32d8956SSteven Rostedt }
3311e32d8956SSteven Rostedt 
3312e32d8956SSteven Rostedt static void clear_ftrace_pid(struct pid *pid)
3313978f3a45SSteven Rostedt {
3314978f3a45SSteven Rostedt 	struct task_struct *p;
3315978f3a45SSteven Rostedt 
3316229c4ef8SOleg Nesterov 	rcu_read_lock();
3317e32d8956SSteven Rostedt 	do_each_pid_task(pid, PIDTYPE_PID, p) {
3318978f3a45SSteven Rostedt 		clear_tsk_trace_trace(p);
3319e32d8956SSteven Rostedt 	} while_each_pid_task(pid, PIDTYPE_PID, p);
3320229c4ef8SOleg Nesterov 	rcu_read_unlock();
3321229c4ef8SOleg Nesterov 
3322e32d8956SSteven Rostedt 	put_pid(pid);
3323978f3a45SSteven Rostedt }
3324978f3a45SSteven Rostedt 
3325e32d8956SSteven Rostedt static void set_ftrace_pid(struct pid *pid)
3326978f3a45SSteven Rostedt {
3327978f3a45SSteven Rostedt 	struct task_struct *p;
3328978f3a45SSteven Rostedt 
3329229c4ef8SOleg Nesterov 	rcu_read_lock();
3330978f3a45SSteven Rostedt 	do_each_pid_task(pid, PIDTYPE_PID, p) {
3331978f3a45SSteven Rostedt 		set_tsk_trace_trace(p);
3332978f3a45SSteven Rostedt 	} while_each_pid_task(pid, PIDTYPE_PID, p);
3333229c4ef8SOleg Nesterov 	rcu_read_unlock();
3334978f3a45SSteven Rostedt }
3335978f3a45SSteven Rostedt 
3336756d17eeS[email protected] static void clear_ftrace_pid_task(struct pid *pid)
3337e32d8956SSteven Rostedt {
3338756d17eeS[email protected] 	if (pid == ftrace_swapper_pid)
3339e32d8956SSteven Rostedt 		clear_ftrace_swapper();
3340e32d8956SSteven Rostedt 	else
3341756d17eeS[email protected] 		clear_ftrace_pid(pid);
3342e32d8956SSteven Rostedt }
3343e32d8956SSteven Rostedt 
3344e32d8956SSteven Rostedt static void set_ftrace_pid_task(struct pid *pid)
3345e32d8956SSteven Rostedt {
3346e32d8956SSteven Rostedt 	if (pid == ftrace_swapper_pid)
3347e32d8956SSteven Rostedt 		set_ftrace_swapper();
3348e32d8956SSteven Rostedt 	else
3349e32d8956SSteven Rostedt 		set_ftrace_pid(pid);
3350e32d8956SSteven Rostedt }
3351e32d8956SSteven Rostedt 
3352756d17eeS[email protected] static int ftrace_pid_add(int p)
3353756d17eeS[email protected] {
3354756d17eeS[email protected] 	struct pid *pid;
3355756d17eeS[email protected] 	struct ftrace_pid *fpid;
3356756d17eeS[email protected] 	int ret = -EINVAL;
3357756d17eeS[email protected] 
3358756d17eeS[email protected] 	mutex_lock(&ftrace_lock);
3359756d17eeS[email protected] 
3360756d17eeS[email protected] 	if (!p)
3361756d17eeS[email protected] 		pid = ftrace_swapper_pid;
3362756d17eeS[email protected] 	else
3363756d17eeS[email protected] 		pid = find_get_pid(p);
3364756d17eeS[email protected] 
3365756d17eeS[email protected] 	if (!pid)
3366756d17eeS[email protected] 		goto out;
3367756d17eeS[email protected] 
3368756d17eeS[email protected] 	ret = 0;
3369756d17eeS[email protected] 
3370756d17eeS[email protected] 	list_for_each_entry(fpid, &ftrace_pids, list)
3371756d17eeS[email protected] 		if (fpid->pid == pid)
3372756d17eeS[email protected] 			goto out_put;
3373756d17eeS[email protected] 
3374756d17eeS[email protected] 	ret = -ENOMEM;
3375756d17eeS[email protected] 
3376756d17eeS[email protected] 	fpid = kmalloc(sizeof(*fpid), GFP_KERNEL);
3377756d17eeS[email protected] 	if (!fpid)
3378756d17eeS[email protected] 		goto out_put;
3379756d17eeS[email protected] 
3380756d17eeS[email protected] 	list_add(&fpid->list, &ftrace_pids);
3381756d17eeS[email protected] 	fpid->pid = pid;
3382756d17eeS[email protected] 
3383756d17eeS[email protected] 	set_ftrace_pid_task(pid);
3384756d17eeS[email protected] 
3385756d17eeS[email protected] 	ftrace_update_pid_func();
3386756d17eeS[email protected] 	ftrace_startup_enable(0);
3387756d17eeS[email protected] 
3388756d17eeS[email protected] 	mutex_unlock(&ftrace_lock);
3389756d17eeS[email protected] 	return 0;
3390756d17eeS[email protected] 
3391756d17eeS[email protected] out_put:
3392756d17eeS[email protected] 	if (pid != ftrace_swapper_pid)
3393756d17eeS[email protected] 		put_pid(pid);
3394756d17eeS[email protected] 
3395756d17eeS[email protected] out:
3396756d17eeS[email protected] 	mutex_unlock(&ftrace_lock);
3397756d17eeS[email protected] 	return ret;
3398756d17eeS[email protected] }
3399756d17eeS[email protected] 
3400756d17eeS[email protected] static void ftrace_pid_reset(void)
3401756d17eeS[email protected] {
3402756d17eeS[email protected] 	struct ftrace_pid *fpid, *safe;
3403756d17eeS[email protected] 
3404756d17eeS[email protected] 	mutex_lock(&ftrace_lock);
3405756d17eeS[email protected] 	list_for_each_entry_safe(fpid, safe, &ftrace_pids, list) {
3406756d17eeS[email protected] 		struct pid *pid = fpid->pid;
3407756d17eeS[email protected] 
3408756d17eeS[email protected] 		clear_ftrace_pid_task(pid);
3409756d17eeS[email protected] 
3410756d17eeS[email protected] 		list_del(&fpid->list);
3411756d17eeS[email protected] 		kfree(fpid);
3412756d17eeS[email protected] 	}
3413756d17eeS[email protected] 
3414756d17eeS[email protected] 	ftrace_update_pid_func();
3415756d17eeS[email protected] 	ftrace_startup_enable(0);
3416756d17eeS[email protected] 
3417756d17eeS[email protected] 	mutex_unlock(&ftrace_lock);
3418756d17eeS[email protected] }
3419756d17eeS[email protected] 
3420756d17eeS[email protected] static void *fpid_start(struct seq_file *m, loff_t *pos)
3421756d17eeS[email protected] {
3422756d17eeS[email protected] 	mutex_lock(&ftrace_lock);
3423756d17eeS[email protected] 
3424756d17eeS[email protected] 	if (list_empty(&ftrace_pids) && (!*pos))
3425756d17eeS[email protected] 		return (void *) 1;
3426756d17eeS[email protected] 
3427756d17eeS[email protected] 	return seq_list_start(&ftrace_pids, *pos);
3428756d17eeS[email protected] }
3429756d17eeS[email protected] 
3430756d17eeS[email protected] static void *fpid_next(struct seq_file *m, void *v, loff_t *pos)
3431756d17eeS[email protected] {
3432756d17eeS[email protected] 	if (v == (void *)1)
3433756d17eeS[email protected] 		return NULL;
3434756d17eeS[email protected] 
3435756d17eeS[email protected] 	return seq_list_next(v, &ftrace_pids, pos);
3436756d17eeS[email protected] }
3437756d17eeS[email protected] 
3438756d17eeS[email protected] static void fpid_stop(struct seq_file *m, void *p)
3439756d17eeS[email protected] {
3440756d17eeS[email protected] 	mutex_unlock(&ftrace_lock);
3441756d17eeS[email protected] }
3442756d17eeS[email protected] 
3443756d17eeS[email protected] static int fpid_show(struct seq_file *m, void *v)
3444756d17eeS[email protected] {
3445756d17eeS[email protected] 	const struct ftrace_pid *fpid = list_entry(v, struct ftrace_pid, list);
3446756d17eeS[email protected] 
3447756d17eeS[email protected] 	if (v == (void *)1) {
3448756d17eeS[email protected] 		seq_printf(m, "no pid\n");
3449756d17eeS[email protected] 		return 0;
3450756d17eeS[email protected] 	}
3451756d17eeS[email protected] 
3452756d17eeS[email protected] 	if (fpid->pid == ftrace_swapper_pid)
3453756d17eeS[email protected] 		seq_printf(m, "swapper tasks\n");
3454756d17eeS[email protected] 	else
3455756d17eeS[email protected] 		seq_printf(m, "%u\n", pid_vnr(fpid->pid));
3456756d17eeS[email protected] 
3457756d17eeS[email protected] 	return 0;
3458756d17eeS[email protected] }
3459756d17eeS[email protected] 
3460756d17eeS[email protected] static const struct seq_operations ftrace_pid_sops = {
3461756d17eeS[email protected] 	.start = fpid_start,
3462756d17eeS[email protected] 	.next = fpid_next,
3463756d17eeS[email protected] 	.stop = fpid_stop,
3464756d17eeS[email protected] 	.show = fpid_show,
3465756d17eeS[email protected] };
3466756d17eeS[email protected] 
3467756d17eeS[email protected] static int
3468756d17eeS[email protected] ftrace_pid_open(struct inode *inode, struct file *file)
3469756d17eeS[email protected] {
3470756d17eeS[email protected] 	int ret = 0;
3471756d17eeS[email protected] 
3472756d17eeS[email protected] 	if ((file->f_mode & FMODE_WRITE) &&
3473756d17eeS[email protected] 	    (file->f_flags & O_TRUNC))
3474756d17eeS[email protected] 		ftrace_pid_reset();
3475756d17eeS[email protected] 
3476756d17eeS[email protected] 	if (file->f_mode & FMODE_READ)
3477756d17eeS[email protected] 		ret = seq_open(file, &ftrace_pid_sops);
3478756d17eeS[email protected] 
3479756d17eeS[email protected] 	return ret;
3480756d17eeS[email protected] }
3481756d17eeS[email protected] 
3482df4fc315SSteven Rostedt static ssize_t
3483df4fc315SSteven Rostedt ftrace_pid_write(struct file *filp, const char __user *ubuf,
3484df4fc315SSteven Rostedt 		   size_t cnt, loff_t *ppos)
3485df4fc315SSteven Rostedt {
3486457dc928SIngo Molnar 	char buf[64], *tmp;
3487df4fc315SSteven Rostedt 	long val;
3488df4fc315SSteven Rostedt 	int ret;
3489df4fc315SSteven Rostedt 
3490df4fc315SSteven Rostedt 	if (cnt >= sizeof(buf))
3491df4fc315SSteven Rostedt 		return -EINVAL;
3492df4fc315SSteven Rostedt 
3493df4fc315SSteven Rostedt 	if (copy_from_user(&buf, ubuf, cnt))
3494df4fc315SSteven Rostedt 		return -EFAULT;
3495df4fc315SSteven Rostedt 
3496df4fc315SSteven Rostedt 	buf[cnt] = 0;
3497df4fc315SSteven Rostedt 
3498756d17eeS[email protected] 	/*
3499756d17eeS[email protected] 	 * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid"
3500756d17eeS[email protected] 	 * to clean the filter quietly.
3501756d17eeS[email protected] 	 */
3502457dc928SIngo Molnar 	tmp = strstrip(buf);
3503457dc928SIngo Molnar 	if (strlen(tmp) == 0)
3504756d17eeS[email protected] 		return 1;
3505756d17eeS[email protected] 
3506457dc928SIngo Molnar 	ret = strict_strtol(tmp, 10, &val);
3507df4fc315SSteven Rostedt 	if (ret < 0)
3508df4fc315SSteven Rostedt 		return ret;
3509df4fc315SSteven Rostedt 
3510756d17eeS[email protected] 	ret = ftrace_pid_add(val);
3511978f3a45SSteven Rostedt 
3512756d17eeS[email protected] 	return ret ? ret : cnt;
3513e32d8956SSteven Rostedt }
3514978f3a45SSteven Rostedt 
3515756d17eeS[email protected] static int
3516756d17eeS[email protected] ftrace_pid_release(struct inode *inode, struct file *file)
3517756d17eeS[email protected] {
3518756d17eeS[email protected] 	if (file->f_mode & FMODE_READ)
3519756d17eeS[email protected] 		seq_release(inode, file);
3520978f3a45SSteven Rostedt 
3521756d17eeS[email protected] 	return 0;
3522df4fc315SSteven Rostedt }
3523df4fc315SSteven Rostedt 
35245e2336a0SSteven Rostedt static const struct file_operations ftrace_pid_fops = {
3525756d17eeS[email protected] 	.open		= ftrace_pid_open,
3526df4fc315SSteven Rostedt 	.write		= ftrace_pid_write,
3527756d17eeS[email protected] 	.read		= seq_read,
3528756d17eeS[email protected] 	.llseek		= seq_lseek,
3529756d17eeS[email protected] 	.release	= ftrace_pid_release,
3530df4fc315SSteven Rostedt };
3531df4fc315SSteven Rostedt 
3532df4fc315SSteven Rostedt static __init int ftrace_init_debugfs(void)
3533df4fc315SSteven Rostedt {
3534df4fc315SSteven Rostedt 	struct dentry *d_tracer;
3535df4fc315SSteven Rostedt 
3536df4fc315SSteven Rostedt 	d_tracer = tracing_init_dentry();
3537df4fc315SSteven Rostedt 	if (!d_tracer)
3538df4fc315SSteven Rostedt 		return 0;
3539df4fc315SSteven Rostedt 
3540df4fc315SSteven Rostedt 	ftrace_init_dyn_debugfs(d_tracer);
3541df4fc315SSteven Rostedt 
35425452af66SFrederic Weisbecker 	trace_create_file("set_ftrace_pid", 0644, d_tracer,
3543df4fc315SSteven Rostedt 			    NULL, &ftrace_pid_fops);
3544493762fcSSteven Rostedt 
3545493762fcSSteven Rostedt 	ftrace_profile_debugfs(d_tracer);
3546493762fcSSteven Rostedt 
3547df4fc315SSteven Rostedt 	return 0;
3548df4fc315SSteven Rostedt }
3549df4fc315SSteven Rostedt fs_initcall(ftrace_init_debugfs);
3550df4fc315SSteven Rostedt 
35513d083395SSteven Rostedt /**
355281adbdc0SSteven Rostedt  * ftrace_kill - kill ftrace
3553a2bb6a3dSSteven Rostedt  *
3554a2bb6a3dSSteven Rostedt  * This function should be used by panic code. It stops ftrace
3555a2bb6a3dSSteven Rostedt  * but in a not so nice way. If you need to simply kill ftrace
3556a2bb6a3dSSteven Rostedt  * from a non-atomic section, use ftrace_kill.
3557a2bb6a3dSSteven Rostedt  */
355881adbdc0SSteven Rostedt void ftrace_kill(void)
3559a2bb6a3dSSteven Rostedt {
3560a2bb6a3dSSteven Rostedt 	ftrace_disabled = 1;
3561a2bb6a3dSSteven Rostedt 	ftrace_enabled = 0;
3562a2bb6a3dSSteven Rostedt 	clear_ftrace_function();
3563a2bb6a3dSSteven Rostedt }
3564a2bb6a3dSSteven Rostedt 
3565a2bb6a3dSSteven Rostedt /**
35663d083395SSteven Rostedt  * register_ftrace_function - register a function for profiling
35673d083395SSteven Rostedt  * @ops - ops structure that holds the function for profiling.
35683d083395SSteven Rostedt  *
35693d083395SSteven Rostedt  * Register a function to be called by all functions in the
35703d083395SSteven Rostedt  * kernel.
35713d083395SSteven Rostedt  *
35723d083395SSteven Rostedt  * Note: @ops->func and all the functions it calls must be labeled
35733d083395SSteven Rostedt  *       with "notrace", otherwise it will go into a
35743d083395SSteven Rostedt  *       recursive loop.
35753d083395SSteven Rostedt  */
35763d083395SSteven Rostedt int register_ftrace_function(struct ftrace_ops *ops)
35773d083395SSteven Rostedt {
357845a4a237SSteven Rostedt 	int ret = -1;
35794eebcc81SSteven Rostedt 
3580e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
3581e7d3737eSFrederic Weisbecker 
358245a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
358345a4a237SSteven Rostedt 		goto out_unlock;
358445a4a237SSteven Rostedt 
3585b0fc494fSSteven Rostedt 	ret = __register_ftrace_function(ops);
3586*bd69c30bSSteven Rostedt 	ftrace_startup(&global_ops, 0);
3587b0fc494fSSteven Rostedt 
358845a4a237SSteven Rostedt  out_unlock:
3589e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
3590b0fc494fSSteven Rostedt 	return ret;
35913d083395SSteven Rostedt }
35923d083395SSteven Rostedt 
35933d083395SSteven Rostedt /**
359432632920SUwe Kleine-Koenig  * unregister_ftrace_function - unregister a function for profiling.
35953d083395SSteven Rostedt  * @ops - ops structure that holds the function to unregister
35963d083395SSteven Rostedt  *
35973d083395SSteven Rostedt  * Unregister a function that was added to be called by ftrace profiling.
35983d083395SSteven Rostedt  */
35993d083395SSteven Rostedt int unregister_ftrace_function(struct ftrace_ops *ops)
36003d083395SSteven Rostedt {
36013d083395SSteven Rostedt 	int ret;
36023d083395SSteven Rostedt 
3603e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
36043d083395SSteven Rostedt 	ret = __unregister_ftrace_function(ops);
3605*bd69c30bSSteven Rostedt 	ftrace_shutdown(&global_ops, 0);
3606e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
3607b0fc494fSSteven Rostedt 
3608b0fc494fSSteven Rostedt 	return ret;
3609b0fc494fSSteven Rostedt }
3610b0fc494fSSteven Rostedt 
3611e309b41dSIngo Molnar int
3612b0fc494fSSteven Rostedt ftrace_enable_sysctl(struct ctl_table *table, int write,
36138d65af78SAlexey Dobriyan 		     void __user *buffer, size_t *lenp,
3614b0fc494fSSteven Rostedt 		     loff_t *ppos)
3615b0fc494fSSteven Rostedt {
361645a4a237SSteven Rostedt 	int ret = -ENODEV;
36174eebcc81SSteven Rostedt 
3618e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
3619b0fc494fSSteven Rostedt 
362045a4a237SSteven Rostedt 	if (unlikely(ftrace_disabled))
362145a4a237SSteven Rostedt 		goto out;
362245a4a237SSteven Rostedt 
36238d65af78SAlexey Dobriyan 	ret = proc_dointvec(table, write, buffer, lenp, ppos);
3624b0fc494fSSteven Rostedt 
3625a32c7765SLi Zefan 	if (ret || !write || (last_ftrace_enabled == !!ftrace_enabled))
3626b0fc494fSSteven Rostedt 		goto out;
3627b0fc494fSSteven Rostedt 
3628a32c7765SLi Zefan 	last_ftrace_enabled = !!ftrace_enabled;
3629b0fc494fSSteven Rostedt 
3630b0fc494fSSteven Rostedt 	if (ftrace_enabled) {
3631b0fc494fSSteven Rostedt 
3632b0fc494fSSteven Rostedt 		ftrace_startup_sysctl();
3633b0fc494fSSteven Rostedt 
3634b0fc494fSSteven Rostedt 		/* we are starting ftrace again */
3635b0fc494fSSteven Rostedt 		if (ftrace_list != &ftrace_list_end) {
3636b0fc494fSSteven Rostedt 			if (ftrace_list->next == &ftrace_list_end)
3637b0fc494fSSteven Rostedt 				ftrace_trace_function = ftrace_list->func;
3638b0fc494fSSteven Rostedt 			else
3639b0fc494fSSteven Rostedt 				ftrace_trace_function = ftrace_list_func;
3640b0fc494fSSteven Rostedt 		}
3641b0fc494fSSteven Rostedt 
3642b0fc494fSSteven Rostedt 	} else {
3643b0fc494fSSteven Rostedt 		/* stopping ftrace calls (just send to ftrace_stub) */
3644b0fc494fSSteven Rostedt 		ftrace_trace_function = ftrace_stub;
3645b0fc494fSSteven Rostedt 
3646b0fc494fSSteven Rostedt 		ftrace_shutdown_sysctl();
3647b0fc494fSSteven Rostedt 	}
3648b0fc494fSSteven Rostedt 
3649b0fc494fSSteven Rostedt  out:
3650e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
36513d083395SSteven Rostedt 	return ret;
365216444a8aSArnaldo Carvalho de Melo }
3653f17845e5SIngo Molnar 
3654fb52607aSFrederic Weisbecker #ifdef CONFIG_FUNCTION_GRAPH_TRACER
3655e7d3737eSFrederic Weisbecker 
3656597af815SSteven Rostedt static int ftrace_graph_active;
36574a2b8ddaSFrederic Weisbecker static struct notifier_block ftrace_suspend_notifier;
3658f201ae23SFrederic Weisbecker 
3659e49dc19cSSteven Rostedt int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
3660e49dc19cSSteven Rostedt {
3661e49dc19cSSteven Rostedt 	return 0;
3662e49dc19cSSteven Rostedt }
3663e49dc19cSSteven Rostedt 
3664287b6e68SFrederic Weisbecker /* The callbacks that hook a function */
3665287b6e68SFrederic Weisbecker trace_func_graph_ret_t ftrace_graph_return =
3666287b6e68SFrederic Weisbecker 			(trace_func_graph_ret_t)ftrace_stub;
3667e49dc19cSSteven Rostedt trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
3668f201ae23SFrederic Weisbecker 
3669f201ae23SFrederic Weisbecker /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */
3670f201ae23SFrederic Weisbecker static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
3671f201ae23SFrederic Weisbecker {
3672f201ae23SFrederic Weisbecker 	int i;
3673f201ae23SFrederic Weisbecker 	int ret = 0;
3674f201ae23SFrederic Weisbecker 	unsigned long flags;
3675f201ae23SFrederic Weisbecker 	int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
3676f201ae23SFrederic Weisbecker 	struct task_struct *g, *t;
3677f201ae23SFrederic Weisbecker 
3678f201ae23SFrederic Weisbecker 	for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) {
3679f201ae23SFrederic Weisbecker 		ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH
3680f201ae23SFrederic Weisbecker 					* sizeof(struct ftrace_ret_stack),
3681f201ae23SFrederic Weisbecker 					GFP_KERNEL);
3682f201ae23SFrederic Weisbecker 		if (!ret_stack_list[i]) {
3683f201ae23SFrederic Weisbecker 			start = 0;
3684f201ae23SFrederic Weisbecker 			end = i;
3685f201ae23SFrederic Weisbecker 			ret = -ENOMEM;
3686f201ae23SFrederic Weisbecker 			goto free;
3687f201ae23SFrederic Weisbecker 		}
3688f201ae23SFrederic Weisbecker 	}
3689f201ae23SFrederic Weisbecker 
3690f201ae23SFrederic Weisbecker 	read_lock_irqsave(&tasklist_lock, flags);
3691f201ae23SFrederic Weisbecker 	do_each_thread(g, t) {
3692f201ae23SFrederic Weisbecker 		if (start == end) {
3693f201ae23SFrederic Weisbecker 			ret = -EAGAIN;
3694f201ae23SFrederic Weisbecker 			goto unlock;
3695f201ae23SFrederic Weisbecker 		}
3696f201ae23SFrederic Weisbecker 
3697f201ae23SFrederic Weisbecker 		if (t->ret_stack == NULL) {
3698380c4b14SFrederic Weisbecker 			atomic_set(&t->tracing_graph_pause, 0);
3699f201ae23SFrederic Weisbecker 			atomic_set(&t->trace_overrun, 0);
370026c01624SSteven Rostedt 			t->curr_ret_stack = -1;
370126c01624SSteven Rostedt 			/* Make sure the tasks see the -1 first: */
370226c01624SSteven Rostedt 			smp_wmb();
370326c01624SSteven Rostedt 			t->ret_stack = ret_stack_list[start++];
3704f201ae23SFrederic Weisbecker 		}
3705f201ae23SFrederic Weisbecker 	} while_each_thread(g, t);
3706f201ae23SFrederic Weisbecker 
3707f201ae23SFrederic Weisbecker unlock:
3708f201ae23SFrederic Weisbecker 	read_unlock_irqrestore(&tasklist_lock, flags);
3709f201ae23SFrederic Weisbecker free:
3710f201ae23SFrederic Weisbecker 	for (i = start; i < end; i++)
3711f201ae23SFrederic Weisbecker 		kfree(ret_stack_list[i]);
3712f201ae23SFrederic Weisbecker 	return ret;
3713f201ae23SFrederic Weisbecker }
3714f201ae23SFrederic Weisbecker 
37158aef2d28SSteven Rostedt static void
371638516ab5SSteven Rostedt ftrace_graph_probe_sched_switch(void *ignore,
371738516ab5SSteven Rostedt 			struct task_struct *prev, struct task_struct *next)
37188aef2d28SSteven Rostedt {
37198aef2d28SSteven Rostedt 	unsigned long long timestamp;
37208aef2d28SSteven Rostedt 	int index;
37218aef2d28SSteven Rostedt 
3722be6f164aSSteven Rostedt 	/*
3723be6f164aSSteven Rostedt 	 * Does the user want to count the time a function was asleep.
3724be6f164aSSteven Rostedt 	 * If so, do not update the time stamps.
3725be6f164aSSteven Rostedt 	 */
3726be6f164aSSteven Rostedt 	if (trace_flags & TRACE_ITER_SLEEP_TIME)
3727be6f164aSSteven Rostedt 		return;
3728be6f164aSSteven Rostedt 
37298aef2d28SSteven Rostedt 	timestamp = trace_clock_local();
37308aef2d28SSteven Rostedt 
37318aef2d28SSteven Rostedt 	prev->ftrace_timestamp = timestamp;
37328aef2d28SSteven Rostedt 
37338aef2d28SSteven Rostedt 	/* only process tasks that we timestamped */
37348aef2d28SSteven Rostedt 	if (!next->ftrace_timestamp)
37358aef2d28SSteven Rostedt 		return;
37368aef2d28SSteven Rostedt 
37378aef2d28SSteven Rostedt 	/*
37388aef2d28SSteven Rostedt 	 * Update all the counters in next to make up for the
37398aef2d28SSteven Rostedt 	 * time next was sleeping.
37408aef2d28SSteven Rostedt 	 */
37418aef2d28SSteven Rostedt 	timestamp -= next->ftrace_timestamp;
37428aef2d28SSteven Rostedt 
37438aef2d28SSteven Rostedt 	for (index = next->curr_ret_stack; index >= 0; index--)
37448aef2d28SSteven Rostedt 		next->ret_stack[index].calltime += timestamp;
37458aef2d28SSteven Rostedt }
37468aef2d28SSteven Rostedt 
3747f201ae23SFrederic Weisbecker /* Allocate a return stack for each task */
3748fb52607aSFrederic Weisbecker static int start_graph_tracing(void)
3749f201ae23SFrederic Weisbecker {
3750f201ae23SFrederic Weisbecker 	struct ftrace_ret_stack **ret_stack_list;
37515b058bcdSFrederic Weisbecker 	int ret, cpu;
3752f201ae23SFrederic Weisbecker 
3753f201ae23SFrederic Weisbecker 	ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE *
3754f201ae23SFrederic Weisbecker 				sizeof(struct ftrace_ret_stack *),
3755f201ae23SFrederic Weisbecker 				GFP_KERNEL);
3756f201ae23SFrederic Weisbecker 
3757f201ae23SFrederic Weisbecker 	if (!ret_stack_list)
3758f201ae23SFrederic Weisbecker 		return -ENOMEM;
3759f201ae23SFrederic Weisbecker 
37605b058bcdSFrederic Weisbecker 	/* The cpu_boot init_task->ret_stack will never be freed */
3761179c498aSSteven Rostedt 	for_each_online_cpu(cpu) {
3762179c498aSSteven Rostedt 		if (!idle_task(cpu)->ret_stack)
3763868baf07SSteven Rostedt 			ftrace_graph_init_idle_task(idle_task(cpu), cpu);
3764179c498aSSteven Rostedt 	}
37655b058bcdSFrederic Weisbecker 
3766f201ae23SFrederic Weisbecker 	do {
3767f201ae23SFrederic Weisbecker 		ret = alloc_retstack_tasklist(ret_stack_list);
3768f201ae23SFrederic Weisbecker 	} while (ret == -EAGAIN);
3769f201ae23SFrederic Weisbecker 
37708aef2d28SSteven Rostedt 	if (!ret) {
377138516ab5SSteven Rostedt 		ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
37728aef2d28SSteven Rostedt 		if (ret)
37738aef2d28SSteven Rostedt 			pr_info("ftrace_graph: Couldn't activate tracepoint"
37748aef2d28SSteven Rostedt 				" probe to kernel_sched_switch\n");
37758aef2d28SSteven Rostedt 	}
37768aef2d28SSteven Rostedt 
3777f201ae23SFrederic Weisbecker 	kfree(ret_stack_list);
3778f201ae23SFrederic Weisbecker 	return ret;
3779f201ae23SFrederic Weisbecker }
3780f201ae23SFrederic Weisbecker 
37814a2b8ddaSFrederic Weisbecker /*
37824a2b8ddaSFrederic Weisbecker  * Hibernation protection.
37834a2b8ddaSFrederic Weisbecker  * The state of the current task is too much unstable during
37844a2b8ddaSFrederic Weisbecker  * suspend/restore to disk. We want to protect against that.
37854a2b8ddaSFrederic Weisbecker  */
37864a2b8ddaSFrederic Weisbecker static int
37874a2b8ddaSFrederic Weisbecker ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
37884a2b8ddaSFrederic Weisbecker 							void *unused)
37894a2b8ddaSFrederic Weisbecker {
37904a2b8ddaSFrederic Weisbecker 	switch (state) {
37914a2b8ddaSFrederic Weisbecker 	case PM_HIBERNATION_PREPARE:
37924a2b8ddaSFrederic Weisbecker 		pause_graph_tracing();
37934a2b8ddaSFrederic Weisbecker 		break;
37944a2b8ddaSFrederic Weisbecker 
37954a2b8ddaSFrederic Weisbecker 	case PM_POST_HIBERNATION:
37964a2b8ddaSFrederic Weisbecker 		unpause_graph_tracing();
37974a2b8ddaSFrederic Weisbecker 		break;
37984a2b8ddaSFrederic Weisbecker 	}
37994a2b8ddaSFrederic Weisbecker 	return NOTIFY_DONE;
38004a2b8ddaSFrederic Weisbecker }
38014a2b8ddaSFrederic Weisbecker 
3802287b6e68SFrederic Weisbecker int register_ftrace_graph(trace_func_graph_ret_t retfunc,
3803287b6e68SFrederic Weisbecker 			trace_func_graph_ent_t entryfunc)
380415e6cb36SFrederic Weisbecker {
3805e7d3737eSFrederic Weisbecker 	int ret = 0;
3806e7d3737eSFrederic Weisbecker 
3807e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
3808e7d3737eSFrederic Weisbecker 
380905ce5818SSteven Rostedt 	/* we currently allow only one tracer registered at a time */
3810597af815SSteven Rostedt 	if (ftrace_graph_active) {
381105ce5818SSteven Rostedt 		ret = -EBUSY;
381205ce5818SSteven Rostedt 		goto out;
381305ce5818SSteven Rostedt 	}
381405ce5818SSteven Rostedt 
38154a2b8ddaSFrederic Weisbecker 	ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
38164a2b8ddaSFrederic Weisbecker 	register_pm_notifier(&ftrace_suspend_notifier);
38174a2b8ddaSFrederic Weisbecker 
3818597af815SSteven Rostedt 	ftrace_graph_active++;
3819fb52607aSFrederic Weisbecker 	ret = start_graph_tracing();
3820f201ae23SFrederic Weisbecker 	if (ret) {
3821597af815SSteven Rostedt 		ftrace_graph_active--;
3822f201ae23SFrederic Weisbecker 		goto out;
3823f201ae23SFrederic Weisbecker 	}
3824e53a6319SSteven Rostedt 
3825287b6e68SFrederic Weisbecker 	ftrace_graph_return = retfunc;
3826287b6e68SFrederic Weisbecker 	ftrace_graph_entry = entryfunc;
3827e53a6319SSteven Rostedt 
3828*bd69c30bSSteven Rostedt 	ftrace_startup(&global_ops, FTRACE_START_FUNC_RET);
3829e7d3737eSFrederic Weisbecker 
3830e7d3737eSFrederic Weisbecker out:
3831e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
3832e7d3737eSFrederic Weisbecker 	return ret;
383315e6cb36SFrederic Weisbecker }
383415e6cb36SFrederic Weisbecker 
3835fb52607aSFrederic Weisbecker void unregister_ftrace_graph(void)
383615e6cb36SFrederic Weisbecker {
3837e6ea44e9SSteven Rostedt 	mutex_lock(&ftrace_lock);
3838e7d3737eSFrederic Weisbecker 
3839597af815SSteven Rostedt 	if (unlikely(!ftrace_graph_active))
38402aad1b76SSteven Rostedt 		goto out;
38412aad1b76SSteven Rostedt 
3842597af815SSteven Rostedt 	ftrace_graph_active--;
3843287b6e68SFrederic Weisbecker 	ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
3844e49dc19cSSteven Rostedt 	ftrace_graph_entry = ftrace_graph_entry_stub;
3845*bd69c30bSSteven Rostedt 	ftrace_shutdown(&global_ops, FTRACE_STOP_FUNC_RET);
38464a2b8ddaSFrederic Weisbecker 	unregister_pm_notifier(&ftrace_suspend_notifier);
384738516ab5SSteven Rostedt 	unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL);
3848e7d3737eSFrederic Weisbecker 
38492aad1b76SSteven Rostedt  out:
3850e6ea44e9SSteven Rostedt 	mutex_unlock(&ftrace_lock);
385115e6cb36SFrederic Weisbecker }
3852f201ae23SFrederic Weisbecker 
3853868baf07SSteven Rostedt static DEFINE_PER_CPU(struct ftrace_ret_stack *, idle_ret_stack);
3854868baf07SSteven Rostedt 
3855868baf07SSteven Rostedt static void
3856868baf07SSteven Rostedt graph_init_task(struct task_struct *t, struct ftrace_ret_stack *ret_stack)
3857868baf07SSteven Rostedt {
3858868baf07SSteven Rostedt 	atomic_set(&t->tracing_graph_pause, 0);
3859868baf07SSteven Rostedt 	atomic_set(&t->trace_overrun, 0);
3860868baf07SSteven Rostedt 	t->ftrace_timestamp = 0;
386125985edcSLucas De Marchi 	/* make curr_ret_stack visible before we add the ret_stack */
3862868baf07SSteven Rostedt 	smp_wmb();
3863868baf07SSteven Rostedt 	t->ret_stack = ret_stack;
3864868baf07SSteven Rostedt }
3865868baf07SSteven Rostedt 
3866868baf07SSteven Rostedt /*
3867868baf07SSteven Rostedt  * Allocate a return stack for the idle task. May be the first
3868868baf07SSteven Rostedt  * time through, or it may be done by CPU hotplug online.
3869868baf07SSteven Rostedt  */
3870868baf07SSteven Rostedt void ftrace_graph_init_idle_task(struct task_struct *t, int cpu)
3871868baf07SSteven Rostedt {
3872868baf07SSteven Rostedt 	t->curr_ret_stack = -1;
3873868baf07SSteven Rostedt 	/*
3874868baf07SSteven Rostedt 	 * The idle task has no parent, it either has its own
3875868baf07SSteven Rostedt 	 * stack or no stack at all.
3876868baf07SSteven Rostedt 	 */
3877868baf07SSteven Rostedt 	if (t->ret_stack)
3878868baf07SSteven Rostedt 		WARN_ON(t->ret_stack != per_cpu(idle_ret_stack, cpu));
3879868baf07SSteven Rostedt 
3880868baf07SSteven Rostedt 	if (ftrace_graph_active) {
3881868baf07SSteven Rostedt 		struct ftrace_ret_stack *ret_stack;
3882868baf07SSteven Rostedt 
3883868baf07SSteven Rostedt 		ret_stack = per_cpu(idle_ret_stack, cpu);
3884868baf07SSteven Rostedt 		if (!ret_stack) {
3885868baf07SSteven Rostedt 			ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
3886868baf07SSteven Rostedt 					    * sizeof(struct ftrace_ret_stack),
3887868baf07SSteven Rostedt 					    GFP_KERNEL);
3888868baf07SSteven Rostedt 			if (!ret_stack)
3889868baf07SSteven Rostedt 				return;
3890868baf07SSteven Rostedt 			per_cpu(idle_ret_stack, cpu) = ret_stack;
3891868baf07SSteven Rostedt 		}
3892868baf07SSteven Rostedt 		graph_init_task(t, ret_stack);
3893868baf07SSteven Rostedt 	}
3894868baf07SSteven Rostedt }
3895868baf07SSteven Rostedt 
3896f201ae23SFrederic Weisbecker /* Allocate a return stack for newly created task */
3897fb52607aSFrederic Weisbecker void ftrace_graph_init_task(struct task_struct *t)
3898f201ae23SFrederic Weisbecker {
389984047e36SSteven Rostedt 	/* Make sure we do not use the parent ret_stack */
390084047e36SSteven Rostedt 	t->ret_stack = NULL;
3901ea14eb71SSteven Rostedt 	t->curr_ret_stack = -1;
390284047e36SSteven Rostedt 
3903597af815SSteven Rostedt 	if (ftrace_graph_active) {
390482310a32SSteven Rostedt 		struct ftrace_ret_stack *ret_stack;
390582310a32SSteven Rostedt 
390682310a32SSteven Rostedt 		ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
3907f201ae23SFrederic Weisbecker 				* sizeof(struct ftrace_ret_stack),
3908f201ae23SFrederic Weisbecker 				GFP_KERNEL);
390982310a32SSteven Rostedt 		if (!ret_stack)
3910f201ae23SFrederic Weisbecker 			return;
3911868baf07SSteven Rostedt 		graph_init_task(t, ret_stack);
391284047e36SSteven Rostedt 	}
3913f201ae23SFrederic Weisbecker }
3914f201ae23SFrederic Weisbecker 
3915fb52607aSFrederic Weisbecker void ftrace_graph_exit_task(struct task_struct *t)
3916f201ae23SFrederic Weisbecker {
3917eae849caSFrederic Weisbecker 	struct ftrace_ret_stack	*ret_stack = t->ret_stack;
3918eae849caSFrederic Weisbecker 
3919f201ae23SFrederic Weisbecker 	t->ret_stack = NULL;
3920eae849caSFrederic Weisbecker 	/* NULL must become visible to IRQs before we free it: */
3921eae849caSFrederic Weisbecker 	barrier();
3922eae849caSFrederic Weisbecker 
3923eae849caSFrederic Weisbecker 	kfree(ret_stack);
3924f201ae23SFrederic Weisbecker }
392514a866c5SSteven Rostedt 
392614a866c5SSteven Rostedt void ftrace_graph_stop(void)
392714a866c5SSteven Rostedt {
392814a866c5SSteven Rostedt 	ftrace_stop();
392914a866c5SSteven Rostedt }
393015e6cb36SFrederic Weisbecker #endif
3931