2 * Infrastructure for profiling code inserted by 'gcc -pg'.
4 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
5 * Copyright (C) 2004-2008 Ingo Molnar <mingo@redhat.com>
7 * Originally ported from the -rt patch by:
8 * Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
10 * Based on code in the latency_tracer, that is:
12 * Copyright (C) 2004-2006 Ingo Molnar
13 * Copyright (C) 2004 William Lee Irwin III
16 #include <linux/module.h>
17 #include <linux/ftrace.h>
19 static DEFINE_SPINLOCK(ftrace_func_lock);
20 static struct ftrace_ops ftrace_list_end __read_mostly =
25 static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
26 ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
28 /* mcount is defined per arch in assembly */
29 EXPORT_SYMBOL(mcount);
31 notrace void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
33 struct ftrace_ops *op = ftrace_list;
35 /* in case someone actually ports this to alpha! */
36 read_barrier_depends();
38 while (op != &ftrace_list_end) {
40 read_barrier_depends();
41 op->func(ip, parent_ip);
47 * register_ftrace_function - register a function for profiling
48 * @ops - ops structure that holds the function for profiling.
50 * Register a function to be called by all functions in the
53 * Note: @ops->func and all the functions it calls must be labeled
54 * with "notrace", otherwise it will go into a
57 int register_ftrace_function(struct ftrace_ops *ops)
61 spin_lock_irqsave(&ftrace_func_lock, flags);
62 ops->next = ftrace_list;
64 * We are entering ops into the ftrace_list but another
65 * CPU might be walking that list. We need to make sure
66 * the ops->next pointer is valid before another CPU sees
67 * the ops pointer included into the ftrace_list.
72 * For one func, simply call it directly.
73 * For more than one func, call the chain.
75 if (ops->next == &ftrace_list_end)
76 ftrace_trace_function = ops->func;
78 ftrace_trace_function = ftrace_list_func;
79 spin_unlock_irqrestore(&ftrace_func_lock, flags);
85 * unregister_ftrace_function - unresgister a function for profiling.
86 * @ops - ops structure that holds the function to unregister
88 * Unregister a function that was added to be called by ftrace profiling.
90 int unregister_ftrace_function(struct ftrace_ops *ops)
93 struct ftrace_ops **p;
96 spin_lock_irqsave(&ftrace_func_lock, flags);
99 * If we are the only function, then the ftrace pointer is
100 * pointing directly to that function.
102 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
103 ftrace_trace_function = ftrace_stub;
104 ftrace_list = &ftrace_list_end;
108 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
119 /* If we only have one func left, then call that directly */
120 if (ftrace_list->next == &ftrace_list_end)
121 ftrace_trace_function = ftrace_list->func;
124 spin_unlock_irqrestore(&ftrace_func_lock, flags);
130 * clear_ftrace_function - reset the ftrace function
132 * This NULLs the ftrace function and in essence stops
133 * tracing. There may be lag
135 void clear_ftrace_function(void)
137 ftrace_trace_function = ftrace_stub;