blob: d7a06a0d9447d77f4c9ec6fb469b1d88da0f55da [file] [log] [blame]
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02001/*
2 * Infrastructure for profiling code inserted by 'gcc -pg'.
3 *
4 * Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
5 * Copyright (C) 2004-2008 Ingo Molnar <mingo@redhat.com>
6 *
7 * Originally ported from the -rt patch by:
8 * Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
9 *
10 * Based on code in the latency_tracer, that is:
11 *
12 * Copyright (C) 2004-2006 Ingo Molnar
13 * Copyright (C) 2004 William Lee Irwin III
14 */
15
Steven Rostedt3d083392008-05-12 21:20:42 +020016#include <linux/stop_machine.h>
17#include <linux/clocksource.h>
18#include <linux/kallsyms.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020019#include <linux/seq_file.h>
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -080020#include <linux/suspend.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020021#include <linux/debugfs.h>
Steven Rostedt3d083392008-05-12 21:20:42 +020022#include <linux/hardirq.h>
Ingo Molnar2d8b8202008-02-23 16:55:50 +010023#include <linux/kthread.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020024#include <linux/uaccess.h>
Abhishek Sagarf22f9a82008-06-21 23:50:29 +053025#include <linux/kprobes.h>
Ingo Molnar2d8b8202008-02-23 16:55:50 +010026#include <linux/ftrace.h>
Steven Rostedtb0fc4942008-05-12 21:20:43 +020027#include <linux/sysctl.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020028#include <linux/ctype.h>
Steven Rostedt3d083392008-05-12 21:20:42 +020029#include <linux/list.h>
Steven Rostedt59df055f2009-02-14 15:29:06 -050030#include <linux/hash.h>
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020031
Abhishek Sagar395a59d2008-06-21 23:47:27 +053032#include <asm/ftrace.h>
33
Steven Rostedt3d083392008-05-12 21:20:42 +020034#include "trace.h"
35
Steven Rostedt6912896e2008-10-23 09:33:03 -040036#define FTRACE_WARN_ON(cond) \
37 do { \
38 if (WARN_ON(cond)) \
39 ftrace_kill(); \
40 } while (0)
41
42#define FTRACE_WARN_ON_ONCE(cond) \
43 do { \
44 if (WARN_ON_ONCE(cond)) \
45 ftrace_kill(); \
46 } while (0)
47
Steven Rostedt8fc0c702009-02-16 15:28:00 -050048/* hash bits for specific function selection */
49#define FTRACE_HASH_BITS 7
50#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
51
Steven Rostedt4eebcc82008-05-12 21:20:48 +020052/* ftrace_enabled is a method to turn ftrace on or off */
53int ftrace_enabled __read_mostly;
Steven Rostedtd61f82d2008-05-12 21:20:43 +020054static int last_ftrace_enabled;
Steven Rostedtb0fc4942008-05-12 21:20:43 +020055
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050056/* Quick disabling of function tracer. */
57int function_trace_stop;
58
Steven Rostedt4eebcc82008-05-12 21:20:48 +020059/*
60 * ftrace_disabled is set when an anomaly is discovered.
61 * ftrace_disabled is much stronger than ftrace_enabled.
62 */
63static int ftrace_disabled __read_mostly;
64
Steven Rostedt52baf112009-02-14 01:15:39 -050065static DEFINE_MUTEX(ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +020066
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020067static struct ftrace_ops ftrace_list_end __read_mostly =
68{
69 .func = ftrace_stub,
70};
71
72static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
73ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050074ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -050075ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020076
Ingo Molnarf2252932008-05-22 10:37:48 +020077static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020078{
79 struct ftrace_ops *op = ftrace_list;
80
81 /* in case someone actually ports this to alpha! */
82 read_barrier_depends();
83
84 while (op != &ftrace_list_end) {
85 /* silly alpha */
86 read_barrier_depends();
87 op->func(ip, parent_ip);
88 op = op->next;
89 };
90}
91
Steven Rostedtdf4fc312008-11-26 00:16:23 -050092static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip)
93{
Steven Rostedt0ef8cde2008-12-03 15:36:58 -050094 if (!test_tsk_trace_trace(current))
Steven Rostedtdf4fc312008-11-26 00:16:23 -050095 return;
96
97 ftrace_pid_function(ip, parent_ip);
98}
99
100static void set_ftrace_pid_function(ftrace_func_t func)
101{
102 /* do not set ftrace_pid_function to itself! */
103 if (func != ftrace_pid_func)
104 ftrace_pid_function = func;
105}
106
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200107/**
Steven Rostedt3d083392008-05-12 21:20:42 +0200108 * clear_ftrace_function - reset the ftrace function
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200109 *
Steven Rostedt3d083392008-05-12 21:20:42 +0200110 * This NULLs the ftrace function and in essence stops
111 * tracing. There may be lag
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200112 */
Steven Rostedt3d083392008-05-12 21:20:42 +0200113void clear_ftrace_function(void)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200114{
Steven Rostedt3d083392008-05-12 21:20:42 +0200115 ftrace_trace_function = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500116 __ftrace_trace_function = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500117 ftrace_pid_function = ftrace_stub;
Steven Rostedt3d083392008-05-12 21:20:42 +0200118}
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200119
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500120#ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
121/*
122 * For those archs that do not test ftrace_trace_stop in their
123 * mcount call site, we need to do it from C.
124 */
125static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
126{
127 if (function_trace_stop)
128 return;
129
130 __ftrace_trace_function(ip, parent_ip);
131}
132#endif
133
Ingo Molnare309b412008-05-12 21:20:51 +0200134static int __register_ftrace_function(struct ftrace_ops *ops)
Steven Rostedt3d083392008-05-12 21:20:42 +0200135{
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200136 ops->next = ftrace_list;
137 /*
138 * We are entering ops into the ftrace_list but another
139 * CPU might be walking that list. We need to make sure
140 * the ops->next pointer is valid before another CPU sees
141 * the ops pointer included into the ftrace_list.
142 */
143 smp_wmb();
144 ftrace_list = ops;
Steven Rostedt3d083392008-05-12 21:20:42 +0200145
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200146 if (ftrace_enabled) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500147 ftrace_func_t func;
148
149 if (ops->next == &ftrace_list_end)
150 func = ops->func;
151 else
152 func = ftrace_list_func;
153
Steven Rostedt978f3a42008-12-04 00:26:40 -0500154 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500155 set_ftrace_pid_function(func);
156 func = ftrace_pid_func;
157 }
158
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200159 /*
160 * For one func, simply call it directly.
161 * For more than one func, call the chain.
162 */
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500163#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500164 ftrace_trace_function = func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500165#else
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500166 __ftrace_trace_function = func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500167 ftrace_trace_function = ftrace_test_stop_func;
168#endif
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200169 }
Steven Rostedt3d083392008-05-12 21:20:42 +0200170
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200171 return 0;
172}
173
Ingo Molnare309b412008-05-12 21:20:51 +0200174static int __unregister_ftrace_function(struct ftrace_ops *ops)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200175{
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200176 struct ftrace_ops **p;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200177
178 /*
Steven Rostedt3d083392008-05-12 21:20:42 +0200179 * If we are removing the last function, then simply point
180 * to the ftrace_stub.
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200181 */
182 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
183 ftrace_trace_function = ftrace_stub;
184 ftrace_list = &ftrace_list_end;
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500185 return 0;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200186 }
187
188 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
189 if (*p == ops)
190 break;
191
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500192 if (*p != ops)
193 return -1;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200194
195 *p = (*p)->next;
196
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200197 if (ftrace_enabled) {
198 /* If we only have one func left, then call that directly */
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500199 if (ftrace_list->next == &ftrace_list_end) {
200 ftrace_func_t func = ftrace_list->func;
201
Steven Rostedt978f3a42008-12-04 00:26:40 -0500202 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500203 set_ftrace_pid_function(func);
204 func = ftrace_pid_func;
205 }
206#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
207 ftrace_trace_function = func;
208#else
209 __ftrace_trace_function = func;
210#endif
211 }
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200212 }
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200213
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500214 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +0200215}
216
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500217static void ftrace_update_pid_func(void)
218{
219 ftrace_func_t func;
220
Steven Rostedt52baf112009-02-14 01:15:39 -0500221 mutex_lock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500222
223 if (ftrace_trace_function == ftrace_stub)
224 goto out;
225
226 func = ftrace_trace_function;
227
Steven Rostedt978f3a42008-12-04 00:26:40 -0500228 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500229 set_ftrace_pid_function(func);
230 func = ftrace_pid_func;
231 } else {
Liming Wang66eafeb2008-12-02 10:33:08 +0800232 if (func == ftrace_pid_func)
233 func = ftrace_pid_function;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500234 }
235
236#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
237 ftrace_trace_function = func;
238#else
239 __ftrace_trace_function = func;
240#endif
241
242 out:
Steven Rostedt52baf112009-02-14 01:15:39 -0500243 mutex_unlock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500244}
245
Ingo Molnar73d3fd92009-02-17 11:48:18 +0100246/* set when tracing only a pid */
247struct pid *ftrace_pid_trace;
248static struct pid * const ftrace_swapper_pid = &init_struct_pid;
249
Steven Rostedt3d083392008-05-12 21:20:42 +0200250#ifdef CONFIG_DYNAMIC_FTRACE
Ingo Molnar73d3fd92009-02-17 11:48:18 +0100251
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400252#ifndef CONFIG_FTRACE_MCOUNT_RECORD
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400253# error Dynamic ftrace depends on MCOUNT_RECORD
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400254#endif
255
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500256static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
257
Steven Rostedtb6887d72009-02-17 12:32:04 -0500258struct ftrace_func_probe {
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500259 struct hlist_node node;
Steven Rostedtb6887d72009-02-17 12:32:04 -0500260 struct ftrace_probe_ops *ops;
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500261 unsigned long flags;
262 unsigned long ip;
263 void *data;
264 struct rcu_head rcu;
265};
266
267
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200268enum {
269 FTRACE_ENABLE_CALLS = (1 << 0),
270 FTRACE_DISABLE_CALLS = (1 << 1),
271 FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
272 FTRACE_ENABLE_MCOUNT = (1 << 3),
273 FTRACE_DISABLE_MCOUNT = (1 << 4),
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500274 FTRACE_START_FUNC_RET = (1 << 5),
275 FTRACE_STOP_FUNC_RET = (1 << 6),
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200276};
277
Steven Rostedt5072c592008-05-12 21:20:43 +0200278static int ftrace_filtered;
279
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400280static LIST_HEAD(ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200281
Steven Rostedt41c52c02008-05-22 11:46:33 -0400282static DEFINE_MUTEX(ftrace_regex_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200283
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200284struct ftrace_page {
285 struct ftrace_page *next;
Steven Rostedt431aa3f2009-01-06 12:43:01 -0500286 int index;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200287 struct dyn_ftrace records[];
David Milleraa5e5ce2008-05-13 22:06:56 -0700288};
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200289
290#define ENTRIES_PER_PAGE \
291 ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
292
293/* estimate from running different kernels */
294#define NR_TO_INIT 10000
295
296static struct ftrace_page *ftrace_pages_start;
297static struct ftrace_page *ftrace_pages;
298
Steven Rostedt37ad5082008-05-12 21:20:48 +0200299static struct dyn_ftrace *ftrace_free_records;
300
Steven Rostedt265c8312009-02-13 12:43:56 -0500301/*
302 * This is a double for. Do not use 'break' to break out of the loop,
303 * you must use a goto.
304 */
305#define do_for_each_ftrace_rec(pg, rec) \
306 for (pg = ftrace_pages_start; pg; pg = pg->next) { \
307 int _____i; \
308 for (_____i = 0; _____i < pg->index; _____i++) { \
309 rec = &pg->records[_____i];
310
311#define while_for_each_ftrace_rec() \
312 } \
313 }
Abhishek Sagarecea6562008-06-21 23:47:53 +0530314
315#ifdef CONFIG_KPROBES
Ingo Molnarf17845e2008-10-24 12:47:10 +0200316
317static int frozen_record_count;
318
Abhishek Sagarecea6562008-06-21 23:47:53 +0530319static inline void freeze_record(struct dyn_ftrace *rec)
320{
321 if (!(rec->flags & FTRACE_FL_FROZEN)) {
322 rec->flags |= FTRACE_FL_FROZEN;
323 frozen_record_count++;
324 }
325}
326
327static inline void unfreeze_record(struct dyn_ftrace *rec)
328{
329 if (rec->flags & FTRACE_FL_FROZEN) {
330 rec->flags &= ~FTRACE_FL_FROZEN;
331 frozen_record_count--;
332 }
333}
334
335static inline int record_frozen(struct dyn_ftrace *rec)
336{
337 return rec->flags & FTRACE_FL_FROZEN;
338}
339#else
340# define freeze_record(rec) ({ 0; })
341# define unfreeze_record(rec) ({ 0; })
342# define record_frozen(rec) ({ 0; })
343#endif /* CONFIG_KPROBES */
344
Ingo Molnare309b412008-05-12 21:20:51 +0200345static void ftrace_free_rec(struct dyn_ftrace *rec)
Steven Rostedt37ad5082008-05-12 21:20:48 +0200346{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200347 rec->ip = (unsigned long)ftrace_free_records;
348 ftrace_free_records = rec;
349 rec->flags |= FTRACE_FL_FREE;
350}
351
Steven Rostedtfed19392008-08-14 22:47:19 -0400352void ftrace_release(void *start, unsigned long size)
353{
354 struct dyn_ftrace *rec;
355 struct ftrace_page *pg;
356 unsigned long s = (unsigned long)start;
357 unsigned long e = s + size;
Steven Rostedtfed19392008-08-14 22:47:19 -0400358
Steven Rostedt00fd61a2008-08-15 21:40:04 -0400359 if (ftrace_disabled || !start)
Steven Rostedtfed19392008-08-14 22:47:19 -0400360 return;
361
Steven Rostedt52baf112009-02-14 01:15:39 -0500362 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -0500363 do_for_each_ftrace_rec(pg, rec) {
364 if ((rec->ip >= s) && (rec->ip < e))
365 ftrace_free_rec(rec);
366 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -0500367 mutex_unlock(&ftrace_lock);
Steven Rostedtfed19392008-08-14 22:47:19 -0400368}
369
Ingo Molnare309b412008-05-12 21:20:51 +0200370static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200371{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200372 struct dyn_ftrace *rec;
373
374 /* First check for freed records */
375 if (ftrace_free_records) {
376 rec = ftrace_free_records;
377
Steven Rostedt37ad5082008-05-12 21:20:48 +0200378 if (unlikely(!(rec->flags & FTRACE_FL_FREE))) {
Steven Rostedt6912896e2008-10-23 09:33:03 -0400379 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt37ad5082008-05-12 21:20:48 +0200380 ftrace_free_records = NULL;
381 return NULL;
382 }
383
384 ftrace_free_records = (void *)rec->ip;
385 memset(rec, 0, sizeof(*rec));
386 return rec;
387 }
388
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200389 if (ftrace_pages->index == ENTRIES_PER_PAGE) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400390 if (!ftrace_pages->next) {
391 /* allocate another page */
392 ftrace_pages->next =
393 (void *)get_zeroed_page(GFP_KERNEL);
394 if (!ftrace_pages->next)
395 return NULL;
396 }
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200397 ftrace_pages = ftrace_pages->next;
398 }
399
400 return &ftrace_pages->records[ftrace_pages->index++];
401}
402
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400403static struct dyn_ftrace *
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200404ftrace_record_ip(unsigned long ip)
Steven Rostedt3d083392008-05-12 21:20:42 +0200405{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400406 struct dyn_ftrace *rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200407
Steven Rostedtf3c7ac42008-11-14 16:21:19 -0800408 if (ftrace_disabled)
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400409 return NULL;
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200410
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400411 rec = ftrace_alloc_dyn_node(ip);
412 if (!rec)
413 return NULL;
Steven Rostedt3d083392008-05-12 21:20:42 +0200414
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400415 rec->ip = ip;
Steven Rostedt3d083392008-05-12 21:20:42 +0200416
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400417 list_add(&rec->list, &ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200418
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400419 return rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200420}
421
Steven Rostedt05736a42008-09-22 14:55:47 -0700422static void print_ip_ins(const char *fmt, unsigned char *p)
423{
424 int i;
425
426 printk(KERN_CONT "%s", fmt);
427
428 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
429 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
430}
431
Steven Rostedt31e88902008-11-14 16:21:19 -0800432static void ftrace_bug(int failed, unsigned long ip)
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800433{
434 switch (failed) {
435 case -EFAULT:
436 FTRACE_WARN_ON_ONCE(1);
437 pr_info("ftrace faulted on modifying ");
438 print_ip_sym(ip);
439 break;
440 case -EINVAL:
441 FTRACE_WARN_ON_ONCE(1);
442 pr_info("ftrace failed to modify ");
443 print_ip_sym(ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800444 print_ip_ins(" actual: ", (unsigned char *)ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800445 printk(KERN_CONT "\n");
446 break;
447 case -EPERM:
448 FTRACE_WARN_ON_ONCE(1);
449 pr_info("ftrace faulted on writing ");
450 print_ip_sym(ip);
451 break;
452 default:
453 FTRACE_WARN_ON_ONCE(1);
454 pr_info("ftrace faulted on unknown error ");
455 print_ip_sym(ip);
456 }
457}
458
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200459
Abhishek Sagar492a7ea52008-05-25 00:10:04 +0530460static int
Steven Rostedt31e88902008-11-14 16:21:19 -0800461__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200462{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100463 unsigned long ftrace_addr;
Steven Rostedt6a24a242009-02-17 11:20:26 -0500464 unsigned long ip, fl;
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100465
Shaohua Lif0001202009-01-09 11:29:42 +0800466 ftrace_addr = (unsigned long)FTRACE_ADDR;
Steven Rostedt5072c592008-05-12 21:20:43 +0200467
468 ip = rec->ip;
469
Steven Rostedt982c3502008-11-15 16:31:41 -0500470 /*
471 * If this record is not to be traced and
472 * it is not enabled then do nothing.
473 *
474 * If this record is not to be traced and
Wenji Huang57794a92009-02-06 17:33:27 +0800475 * it is enabled then disable it.
Steven Rostedt982c3502008-11-15 16:31:41 -0500476 *
477 */
478 if (rec->flags & FTRACE_FL_NOTRACE) {
479 if (rec->flags & FTRACE_FL_ENABLED)
480 rec->flags &= ~FTRACE_FL_ENABLED;
481 else
Steven Rostedt5072c592008-05-12 21:20:43 +0200482 return 0;
483
Steven Rostedt982c3502008-11-15 16:31:41 -0500484 } else if (ftrace_filtered && enable) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200485 /*
Steven Rostedt982c3502008-11-15 16:31:41 -0500486 * Filtering is on:
Steven Rostedt5072c592008-05-12 21:20:43 +0200487 */
Steven Rostedt982c3502008-11-15 16:31:41 -0500488
489 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED);
490
491 /* Record is filtered and enabled, do nothing */
492 if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
493 return 0;
494
Wenji Huang57794a92009-02-06 17:33:27 +0800495 /* Record is not filtered or enabled, do nothing */
Steven Rostedt982c3502008-11-15 16:31:41 -0500496 if (!fl)
497 return 0;
498
499 /* Record is not filtered but enabled, disable it */
500 if (fl == FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +0200501 rec->flags &= ~FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -0500502 else
503 /* Otherwise record is filtered but not enabled, enable it */
Steven Rostedt5072c592008-05-12 21:20:43 +0200504 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt5072c592008-05-12 21:20:43 +0200505 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -0500506 /* Disable or not filtered */
Steven Rostedt5072c592008-05-12 21:20:43 +0200507
508 if (enable) {
Steven Rostedt982c3502008-11-15 16:31:41 -0500509 /* if record is enabled, do nothing */
Steven Rostedt41c52c02008-05-22 11:46:33 -0400510 if (rec->flags & FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +0200511 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -0500512
Steven Rostedt41c52c02008-05-22 11:46:33 -0400513 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -0500514
Steven Rostedt5072c592008-05-12 21:20:43 +0200515 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -0500516
Wenji Huang57794a92009-02-06 17:33:27 +0800517 /* if record is not enabled, do nothing */
Steven Rostedt5072c592008-05-12 21:20:43 +0200518 if (!(rec->flags & FTRACE_FL_ENABLED))
519 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -0500520
Steven Rostedt5072c592008-05-12 21:20:43 +0200521 rec->flags &= ~FTRACE_FL_ENABLED;
522 }
523 }
524
Steven Rostedt982c3502008-11-15 16:31:41 -0500525 if (rec->flags & FTRACE_FL_ENABLED)
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100526 return ftrace_make_call(rec, ftrace_addr);
Steven Rostedt31e88902008-11-14 16:21:19 -0800527 else
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100528 return ftrace_make_nop(NULL, rec, ftrace_addr);
Steven Rostedt5072c592008-05-12 21:20:43 +0200529}
530
531static void ftrace_replace_code(int enable)
532{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200533 struct dyn_ftrace *rec;
534 struct ftrace_page *pg;
Steven Rostedt6a24a242009-02-17 11:20:26 -0500535 int failed;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200536
Steven Rostedt265c8312009-02-13 12:43:56 -0500537 do_for_each_ftrace_rec(pg, rec) {
538 /*
539 * Skip over free records and records that have
540 * failed.
541 */
542 if (rec->flags & FTRACE_FL_FREE ||
543 rec->flags & FTRACE_FL_FAILED)
544 continue;
Steven Rostedt5072c592008-05-12 21:20:43 +0200545
Steven Rostedt265c8312009-02-13 12:43:56 -0500546 /* ignore updates to this record's mcount site */
547 if (get_kprobe((void *)rec->ip)) {
548 freeze_record(rec);
549 continue;
550 } else {
551 unfreeze_record(rec);
Steven Rostedt5072c592008-05-12 21:20:43 +0200552 }
Steven Rostedt265c8312009-02-13 12:43:56 -0500553
554 failed = __ftrace_replace_code(rec, enable);
555 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
556 rec->flags |= FTRACE_FL_FAILED;
557 if ((system_state == SYSTEM_BOOTING) ||
558 !core_kernel_text(rec->ip)) {
559 ftrace_free_rec(rec);
Steven Rostedt43772452009-02-19 13:41:27 -0500560 } else {
Steven Rostedt265c8312009-02-13 12:43:56 -0500561 ftrace_bug(failed, rec->ip);
Steven Rostedt43772452009-02-19 13:41:27 -0500562 /* Stop processing */
563 return;
564 }
Steven Rostedt265c8312009-02-13 12:43:56 -0500565 }
566 } while_for_each_ftrace_rec();
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200567}
568
Ingo Molnare309b412008-05-12 21:20:51 +0200569static int
Steven Rostedt31e88902008-11-14 16:21:19 -0800570ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200571{
572 unsigned long ip;
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400573 int ret;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200574
575 ip = rec->ip;
576
Shaohua Li25aac9d2009-01-09 11:29:40 +0800577 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400578 if (ret) {
Steven Rostedt31e88902008-11-14 16:21:19 -0800579 ftrace_bug(ret, ip);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200580 rec->flags |= FTRACE_FL_FAILED;
Abhishek Sagar492a7ea52008-05-25 00:10:04 +0530581 return 0;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200582 }
Abhishek Sagar492a7ea52008-05-25 00:10:04 +0530583 return 1;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200584}
585
Steven Rostedt000ab692009-02-17 13:35:06 -0500586/*
587 * archs can override this function if they must do something
588 * before the modifying code is performed.
589 */
590int __weak ftrace_arch_code_modify_prepare(void)
591{
592 return 0;
593}
594
595/*
596 * archs can override this function if they must do something
597 * after the modifying code is performed.
598 */
599int __weak ftrace_arch_code_modify_post_process(void)
600{
601 return 0;
602}
603
Ingo Molnare309b412008-05-12 21:20:51 +0200604static int __ftrace_modify_code(void *data)
Steven Rostedt3d083392008-05-12 21:20:42 +0200605{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200606 int *command = data;
607
Steven Rostedta3583242008-11-11 15:01:42 -0500608 if (*command & FTRACE_ENABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200609 ftrace_replace_code(1);
Steven Rostedta3583242008-11-11 15:01:42 -0500610 else if (*command & FTRACE_DISABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200611 ftrace_replace_code(0);
612
613 if (*command & FTRACE_UPDATE_TRACE_FUNC)
614 ftrace_update_ftrace_func(ftrace_trace_function);
615
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500616 if (*command & FTRACE_START_FUNC_RET)
617 ftrace_enable_ftrace_graph_caller();
618 else if (*command & FTRACE_STOP_FUNC_RET)
619 ftrace_disable_ftrace_graph_caller();
620
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200621 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +0200622}
623
Ingo Molnare309b412008-05-12 21:20:51 +0200624static void ftrace_run_update_code(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200625{
Steven Rostedt000ab692009-02-17 13:35:06 -0500626 int ret;
627
628 ret = ftrace_arch_code_modify_prepare();
629 FTRACE_WARN_ON(ret);
630 if (ret)
631 return;
632
Rusty Russell784e2d72008-07-28 12:16:31 -0500633 stop_machine(__ftrace_modify_code, &command, NULL);
Steven Rostedt000ab692009-02-17 13:35:06 -0500634
635 ret = ftrace_arch_code_modify_post_process();
636 FTRACE_WARN_ON(ret);
Steven Rostedt3d083392008-05-12 21:20:42 +0200637}
638
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200639static ftrace_func_t saved_ftrace_func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500640static int ftrace_start_up;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500641
642static void ftrace_startup_enable(int command)
643{
644 if (saved_ftrace_func != ftrace_trace_function) {
645 saved_ftrace_func = ftrace_trace_function;
646 command |= FTRACE_UPDATE_TRACE_FUNC;
647 }
648
649 if (!command || !ftrace_enabled)
650 return;
651
652 ftrace_run_update_code(command);
653}
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200654
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500655static void ftrace_startup(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200656{
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200657 if (unlikely(ftrace_disabled))
658 return;
659
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500660 ftrace_start_up++;
Steven Rostedt982c3502008-11-15 16:31:41 -0500661 command |= FTRACE_ENABLE_CALLS;
Steven Rostedt3d083392008-05-12 21:20:42 +0200662
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500663 ftrace_startup_enable(command);
Steven Rostedt3d083392008-05-12 21:20:42 +0200664}
665
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500666static void ftrace_shutdown(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200667{
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200668 if (unlikely(ftrace_disabled))
669 return;
670
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500671 ftrace_start_up--;
672 if (!ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200673 command |= FTRACE_DISABLE_CALLS;
674
675 if (saved_ftrace_func != ftrace_trace_function) {
676 saved_ftrace_func = ftrace_trace_function;
677 command |= FTRACE_UPDATE_TRACE_FUNC;
678 }
679
680 if (!command || !ftrace_enabled)
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500681 return;
Steven Rostedt3d083392008-05-12 21:20:42 +0200682
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200683 ftrace_run_update_code(command);
Steven Rostedt3d083392008-05-12 21:20:42 +0200684}
685
Ingo Molnare309b412008-05-12 21:20:51 +0200686static void ftrace_startup_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200687{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200688 int command = FTRACE_ENABLE_MCOUNT;
689
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200690 if (unlikely(ftrace_disabled))
691 return;
692
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200693 /* Force update next time */
694 saved_ftrace_func = NULL;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500695 /* ftrace_start_up is true if we want ftrace running */
696 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200697 command |= FTRACE_ENABLE_CALLS;
698
699 ftrace_run_update_code(command);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200700}
701
Ingo Molnare309b412008-05-12 21:20:51 +0200702static void ftrace_shutdown_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200703{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200704 int command = FTRACE_DISABLE_MCOUNT;
705
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200706 if (unlikely(ftrace_disabled))
707 return;
708
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500709 /* ftrace_start_up is true if ftrace is running */
710 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200711 command |= FTRACE_DISABLE_CALLS;
712
713 ftrace_run_update_code(command);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200714}
715
Steven Rostedt3d083392008-05-12 21:20:42 +0200716static cycle_t ftrace_update_time;
717static unsigned long ftrace_update_cnt;
718unsigned long ftrace_update_tot_cnt;
719
Steven Rostedt31e88902008-11-14 16:21:19 -0800720static int ftrace_update_code(struct module *mod)
Steven Rostedt3d083392008-05-12 21:20:42 +0200721{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400722 struct dyn_ftrace *p, *t;
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530723 cycle_t start, stop;
Steven Rostedt3d083392008-05-12 21:20:42 +0200724
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200725 start = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200726 ftrace_update_cnt = 0;
727
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400728 list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530729
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400730 /* If something went wrong, bail without enabling anything */
731 if (unlikely(ftrace_disabled))
732 return -1;
Steven Rostedt3d083392008-05-12 21:20:42 +0200733
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400734 list_del_init(&p->list);
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530735
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400736 /* convert record (i.e, patch mcount-call with NOP) */
Steven Rostedt31e88902008-11-14 16:21:19 -0800737 if (ftrace_code_disable(mod, p)) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400738 p->flags |= FTRACE_FL_CONVERTED;
739 ftrace_update_cnt++;
740 } else
741 ftrace_free_rec(p);
Steven Rostedt3d083392008-05-12 21:20:42 +0200742 }
743
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200744 stop = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200745 ftrace_update_time = stop - start;
746 ftrace_update_tot_cnt += ftrace_update_cnt;
747
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200748 return 0;
749}
750
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400751static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200752{
753 struct ftrace_page *pg;
754 int cnt;
755 int i;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200756
757 /* allocate a few pages */
758 ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
759 if (!ftrace_pages_start)
760 return -1;
761
762 /*
763 * Allocate a few more pages.
764 *
765 * TODO: have some parser search vmlinux before
766 * final linking to find all calls to ftrace.
767 * Then we can:
768 * a) know how many pages to allocate.
769 * and/or
770 * b) set up the table then.
771 *
772 * The dynamic code is still necessary for
773 * modules.
774 */
775
776 pg = ftrace_pages = ftrace_pages_start;
777
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400778 cnt = num_to_init / ENTRIES_PER_PAGE;
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400779 pr_info("ftrace: allocating %ld entries in %d pages\n",
walimis5821e1b2008-11-15 15:19:06 +0800780 num_to_init, cnt + 1);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200781
782 for (i = 0; i < cnt; i++) {
783 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
784
785 /* If we fail, we'll try later anyway */
786 if (!pg->next)
787 break;
788
789 pg = pg->next;
790 }
791
792 return 0;
793}
794
Steven Rostedt5072c592008-05-12 21:20:43 +0200795enum {
796 FTRACE_ITER_FILTER = (1 << 0),
797 FTRACE_ITER_CONT = (1 << 1),
Steven Rostedt41c52c02008-05-22 11:46:33 -0400798 FTRACE_ITER_NOTRACE = (1 << 2),
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530799 FTRACE_ITER_FAILURES = (1 << 3),
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500800 FTRACE_ITER_PRINTALL = (1 << 4),
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500801 FTRACE_ITER_HASH = (1 << 5),
Steven Rostedt5072c592008-05-12 21:20:43 +0200802};
803
804#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
805
806struct ftrace_iterator {
Steven Rostedt5072c592008-05-12 21:20:43 +0200807 struct ftrace_page *pg;
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500808 int hidx;
Steven Rostedt431aa3f2009-01-06 12:43:01 -0500809 int idx;
Steven Rostedt5072c592008-05-12 21:20:43 +0200810 unsigned flags;
811 unsigned char buffer[FTRACE_BUFF_MAX+1];
812 unsigned buffer_idx;
813 unsigned filtered;
814};
815
Ingo Molnare309b412008-05-12 21:20:51 +0200816static void *
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500817t_hash_next(struct seq_file *m, void *v, loff_t *pos)
818{
819 struct ftrace_iterator *iter = m->private;
820 struct hlist_node *hnd = v;
821 struct hlist_head *hhd;
822
823 WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
824
825 (*pos)++;
826
827 retry:
828 if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
829 return NULL;
830
831 hhd = &ftrace_func_hash[iter->hidx];
832
833 if (hlist_empty(hhd)) {
834 iter->hidx++;
835 hnd = NULL;
836 goto retry;
837 }
838
839 if (!hnd)
840 hnd = hhd->first;
841 else {
842 hnd = hnd->next;
843 if (!hnd) {
844 iter->hidx++;
845 goto retry;
846 }
847 }
848
849 return hnd;
850}
851
852static void *t_hash_start(struct seq_file *m, loff_t *pos)
853{
854 struct ftrace_iterator *iter = m->private;
855 void *p = NULL;
856
857 iter->flags |= FTRACE_ITER_HASH;
858
859 return t_hash_next(m, p, pos);
860}
861
862static int t_hash_show(struct seq_file *m, void *v)
863{
Steven Rostedtb6887d72009-02-17 12:32:04 -0500864 struct ftrace_func_probe *rec;
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500865 struct hlist_node *hnd = v;
866 char str[KSYM_SYMBOL_LEN];
867
Steven Rostedtb6887d72009-02-17 12:32:04 -0500868 rec = hlist_entry(hnd, struct ftrace_func_probe, node);
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500869
Steven Rostedt809dcf22009-02-16 23:06:01 -0500870 if (rec->ops->print)
871 return rec->ops->print(m, rec->ip, rec->ops, rec->data);
872
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500873 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
874 seq_printf(m, "%s:", str);
875
876 kallsyms_lookup((unsigned long)rec->ops->func, NULL, NULL, NULL, str);
877 seq_printf(m, "%s", str);
878
879 if (rec->data)
880 seq_printf(m, ":%p", rec->data);
881 seq_putc(m, '\n');
882
883 return 0;
884}
885
886static void *
Steven Rostedt5072c592008-05-12 21:20:43 +0200887t_next(struct seq_file *m, void *v, loff_t *pos)
888{
889 struct ftrace_iterator *iter = m->private;
890 struct dyn_ftrace *rec = NULL;
891
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500892 if (iter->flags & FTRACE_ITER_HASH)
893 return t_hash_next(m, v, pos);
894
Steven Rostedt5072c592008-05-12 21:20:43 +0200895 (*pos)++;
896
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500897 if (iter->flags & FTRACE_ITER_PRINTALL)
898 return NULL;
899
Steven Rostedt5072c592008-05-12 21:20:43 +0200900 retry:
901 if (iter->idx >= iter->pg->index) {
902 if (iter->pg->next) {
903 iter->pg = iter->pg->next;
904 iter->idx = 0;
905 goto retry;
Liming Wang50cdaf02008-11-28 12:13:21 +0800906 } else {
907 iter->idx = -1;
Steven Rostedt5072c592008-05-12 21:20:43 +0200908 }
909 } else {
910 rec = &iter->pg->records[iter->idx++];
Steven Rostedta9fdda32008-08-14 22:47:17 -0400911 if ((rec->flags & FTRACE_FL_FREE) ||
912
913 (!(iter->flags & FTRACE_ITER_FAILURES) &&
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530914 (rec->flags & FTRACE_FL_FAILED)) ||
915
916 ((iter->flags & FTRACE_ITER_FAILURES) &&
Steven Rostedta9fdda32008-08-14 22:47:17 -0400917 !(rec->flags & FTRACE_FL_FAILED)) ||
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530918
Steven Rostedt0183fb12008-11-07 22:36:02 -0500919 ((iter->flags & FTRACE_ITER_FILTER) &&
920 !(rec->flags & FTRACE_FL_FILTER)) ||
921
Steven Rostedt41c52c02008-05-22 11:46:33 -0400922 ((iter->flags & FTRACE_ITER_NOTRACE) &&
923 !(rec->flags & FTRACE_FL_NOTRACE))) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200924 rec = NULL;
925 goto retry;
926 }
927 }
928
Steven Rostedt5072c592008-05-12 21:20:43 +0200929 return rec;
930}
931
932static void *t_start(struct seq_file *m, loff_t *pos)
933{
934 struct ftrace_iterator *iter = m->private;
935 void *p = NULL;
Steven Rostedt5072c592008-05-12 21:20:43 +0200936
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500937 mutex_lock(&ftrace_lock);
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500938 /*
939 * For set_ftrace_filter reading, if we have the filter
940 * off, we can short cut and just print out that all
941 * functions are enabled.
942 */
943 if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
944 if (*pos > 0)
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500945 return t_hash_start(m, pos);
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500946 iter->flags |= FTRACE_ITER_PRINTALL;
947 (*pos)++;
948 return iter;
949 }
950
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500951 if (iter->flags & FTRACE_ITER_HASH)
952 return t_hash_start(m, pos);
953
Liming Wang50cdaf02008-11-28 12:13:21 +0800954 if (*pos > 0) {
955 if (iter->idx < 0)
956 return p;
957 (*pos)--;
958 iter->idx--;
959 }
walimis5821e1b2008-11-15 15:19:06 +0800960
Liming Wang50cdaf02008-11-28 12:13:21 +0800961 p = t_next(m, p, pos);
Steven Rostedt5072c592008-05-12 21:20:43 +0200962
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500963 if (!p)
964 return t_hash_start(m, pos);
965
Steven Rostedt5072c592008-05-12 21:20:43 +0200966 return p;
967}
968
969static void t_stop(struct seq_file *m, void *p)
970{
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500971 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200972}
973
974static int t_show(struct seq_file *m, void *v)
975{
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500976 struct ftrace_iterator *iter = m->private;
Steven Rostedt5072c592008-05-12 21:20:43 +0200977 struct dyn_ftrace *rec = v;
978 char str[KSYM_SYMBOL_LEN];
979
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500980 if (iter->flags & FTRACE_ITER_HASH)
981 return t_hash_show(m, v);
982
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500983 if (iter->flags & FTRACE_ITER_PRINTALL) {
984 seq_printf(m, "#### all functions enabled ####\n");
985 return 0;
986 }
987
Steven Rostedt5072c592008-05-12 21:20:43 +0200988 if (!rec)
989 return 0;
990
991 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
992
Liming Wang50cdaf02008-11-28 12:13:21 +0800993 seq_printf(m, "%s\n", str);
Steven Rostedt5072c592008-05-12 21:20:43 +0200994
995 return 0;
996}
997
998static struct seq_operations show_ftrace_seq_ops = {
999 .start = t_start,
1000 .next = t_next,
1001 .stop = t_stop,
1002 .show = t_show,
1003};
1004
Ingo Molnare309b412008-05-12 21:20:51 +02001005static int
Steven Rostedt5072c592008-05-12 21:20:43 +02001006ftrace_avail_open(struct inode *inode, struct file *file)
1007{
1008 struct ftrace_iterator *iter;
1009 int ret;
1010
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001011 if (unlikely(ftrace_disabled))
1012 return -ENODEV;
1013
Steven Rostedt5072c592008-05-12 21:20:43 +02001014 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
1015 if (!iter)
1016 return -ENOMEM;
1017
1018 iter->pg = ftrace_pages_start;
Steven Rostedt5072c592008-05-12 21:20:43 +02001019
1020 ret = seq_open(file, &show_ftrace_seq_ops);
1021 if (!ret) {
1022 struct seq_file *m = file->private_data;
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001023
Steven Rostedt5072c592008-05-12 21:20:43 +02001024 m->private = iter;
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001025 } else {
Steven Rostedt5072c592008-05-12 21:20:43 +02001026 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001027 }
Steven Rostedt5072c592008-05-12 21:20:43 +02001028
1029 return ret;
1030}
1031
1032int ftrace_avail_release(struct inode *inode, struct file *file)
1033{
1034 struct seq_file *m = (struct seq_file *)file->private_data;
1035 struct ftrace_iterator *iter = m->private;
1036
1037 seq_release(inode, file);
1038 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001039
Steven Rostedt5072c592008-05-12 21:20:43 +02001040 return 0;
1041}
1042
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301043static int
1044ftrace_failures_open(struct inode *inode, struct file *file)
1045{
1046 int ret;
1047 struct seq_file *m;
1048 struct ftrace_iterator *iter;
1049
1050 ret = ftrace_avail_open(inode, file);
1051 if (!ret) {
1052 m = (struct seq_file *)file->private_data;
1053 iter = (struct ftrace_iterator *)m->private;
1054 iter->flags = FTRACE_ITER_FAILURES;
1055 }
1056
1057 return ret;
1058}
1059
1060
Steven Rostedt41c52c02008-05-22 11:46:33 -04001061static void ftrace_filter_reset(int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001062{
1063 struct ftrace_page *pg;
1064 struct dyn_ftrace *rec;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001065 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +02001066
Steven Rostedt52baf112009-02-14 01:15:39 -05001067 mutex_lock(&ftrace_lock);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001068 if (enable)
1069 ftrace_filtered = 0;
Steven Rostedt265c8312009-02-13 12:43:56 -05001070 do_for_each_ftrace_rec(pg, rec) {
1071 if (rec->flags & FTRACE_FL_FAILED)
1072 continue;
1073 rec->flags &= ~type;
1074 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001075 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001076}
1077
Ingo Molnare309b412008-05-12 21:20:51 +02001078static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04001079ftrace_regex_open(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001080{
1081 struct ftrace_iterator *iter;
1082 int ret = 0;
1083
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001084 if (unlikely(ftrace_disabled))
1085 return -ENODEV;
1086
Steven Rostedt5072c592008-05-12 21:20:43 +02001087 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
1088 if (!iter)
1089 return -ENOMEM;
1090
Steven Rostedt41c52c02008-05-22 11:46:33 -04001091 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001092 if ((file->f_mode & FMODE_WRITE) &&
1093 !(file->f_flags & O_APPEND))
Steven Rostedt41c52c02008-05-22 11:46:33 -04001094 ftrace_filter_reset(enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001095
1096 if (file->f_mode & FMODE_READ) {
1097 iter->pg = ftrace_pages_start;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001098 iter->flags = enable ? FTRACE_ITER_FILTER :
1099 FTRACE_ITER_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +02001100
1101 ret = seq_open(file, &show_ftrace_seq_ops);
1102 if (!ret) {
1103 struct seq_file *m = file->private_data;
1104 m->private = iter;
1105 } else
1106 kfree(iter);
1107 } else
1108 file->private_data = iter;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001109 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001110
1111 return ret;
1112}
1113
Steven Rostedt41c52c02008-05-22 11:46:33 -04001114static int
1115ftrace_filter_open(struct inode *inode, struct file *file)
1116{
1117 return ftrace_regex_open(inode, file, 1);
1118}
1119
1120static int
1121ftrace_notrace_open(struct inode *inode, struct file *file)
1122{
1123 return ftrace_regex_open(inode, file, 0);
1124}
1125
Ingo Molnare309b412008-05-12 21:20:51 +02001126static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001127ftrace_regex_read(struct file *file, char __user *ubuf,
Steven Rostedt5072c592008-05-12 21:20:43 +02001128 size_t cnt, loff_t *ppos)
1129{
1130 if (file->f_mode & FMODE_READ)
1131 return seq_read(file, ubuf, cnt, ppos);
1132 else
1133 return -EPERM;
1134}
1135
Ingo Molnare309b412008-05-12 21:20:51 +02001136static loff_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001137ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
Steven Rostedt5072c592008-05-12 21:20:43 +02001138{
1139 loff_t ret;
1140
1141 if (file->f_mode & FMODE_READ)
1142 ret = seq_lseek(file, offset, origin);
1143 else
1144 file->f_pos = ret = 1;
1145
1146 return ret;
1147}
1148
1149enum {
1150 MATCH_FULL,
1151 MATCH_FRONT_ONLY,
1152 MATCH_MIDDLE_ONLY,
1153 MATCH_END_ONLY,
1154};
1155
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001156/*
1157 * (static function - no need for kernel doc)
1158 *
1159 * Pass in a buffer containing a glob and this function will
1160 * set search to point to the search part of the buffer and
1161 * return the type of search it is (see enum above).
1162 * This does modify buff.
1163 *
1164 * Returns enum type.
1165 * search returns the pointer to use for comparison.
1166 * not returns 1 if buff started with a '!'
1167 * 0 otherwise.
1168 */
1169static int
Steven Rostedt64e7c442009-02-13 17:08:48 -05001170ftrace_setup_glob(char *buff, int len, char **search, int *not)
Steven Rostedt5072c592008-05-12 21:20:43 +02001171{
Steven Rostedt5072c592008-05-12 21:20:43 +02001172 int type = MATCH_FULL;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001173 int i;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001174
1175 if (buff[0] == '!') {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001176 *not = 1;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001177 buff++;
1178 len--;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001179 } else
1180 *not = 0;
1181
1182 *search = buff;
Steven Rostedt5072c592008-05-12 21:20:43 +02001183
1184 for (i = 0; i < len; i++) {
1185 if (buff[i] == '*') {
1186 if (!i) {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001187 *search = buff + 1;
Steven Rostedt5072c592008-05-12 21:20:43 +02001188 type = MATCH_END_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001189 } else {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001190 if (type == MATCH_END_ONLY)
Steven Rostedt5072c592008-05-12 21:20:43 +02001191 type = MATCH_MIDDLE_ONLY;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001192 else
Steven Rostedt5072c592008-05-12 21:20:43 +02001193 type = MATCH_FRONT_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001194 buff[i] = 0;
1195 break;
1196 }
1197 }
1198 }
1199
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001200 return type;
1201}
1202
Steven Rostedt64e7c442009-02-13 17:08:48 -05001203static int ftrace_match(char *str, char *regex, int len, int type)
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001204{
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001205 int matched = 0;
1206 char *ptr;
1207
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001208 switch (type) {
1209 case MATCH_FULL:
1210 if (strcmp(str, regex) == 0)
1211 matched = 1;
1212 break;
1213 case MATCH_FRONT_ONLY:
1214 if (strncmp(str, regex, len) == 0)
1215 matched = 1;
1216 break;
1217 case MATCH_MIDDLE_ONLY:
1218 if (strstr(str, regex))
1219 matched = 1;
1220 break;
1221 case MATCH_END_ONLY:
1222 ptr = strstr(str, regex);
1223 if (ptr && (ptr[len] == 0))
1224 matched = 1;
1225 break;
1226 }
1227
1228 return matched;
1229}
1230
Steven Rostedt64e7c442009-02-13 17:08:48 -05001231static int
1232ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
1233{
1234 char str[KSYM_SYMBOL_LEN];
1235
1236 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1237 return ftrace_match(str, regex, len, type);
1238}
1239
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001240static void ftrace_match_records(char *buff, int len, int enable)
1241{
Steven Rostedt6a24a242009-02-17 11:20:26 -05001242 unsigned int search_len;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001243 struct ftrace_page *pg;
1244 struct dyn_ftrace *rec;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001245 unsigned long flag;
1246 char *search;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001247 int type;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001248 int not;
1249
Steven Rostedt6a24a242009-02-17 11:20:26 -05001250 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001251 type = ftrace_setup_glob(buff, len, &search, &not);
1252
1253 search_len = strlen(search);
1254
Steven Rostedt52baf112009-02-14 01:15:39 -05001255 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05001256 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedt5072c592008-05-12 21:20:43 +02001257
Steven Rostedt265c8312009-02-13 12:43:56 -05001258 if (rec->flags & FTRACE_FL_FAILED)
1259 continue;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001260
1261 if (ftrace_match_record(rec, search, search_len, type)) {
Steven Rostedt265c8312009-02-13 12:43:56 -05001262 if (not)
1263 rec->flags &= ~flag;
1264 else
1265 rec->flags |= flag;
1266 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001267 /*
1268 * Only enable filtering if we have a function that
1269 * is filtered on.
1270 */
1271 if (enable && (rec->flags & FTRACE_FL_FILTER))
1272 ftrace_filtered = 1;
Steven Rostedt265c8312009-02-13 12:43:56 -05001273 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001274 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001275}
1276
Steven Rostedt64e7c442009-02-13 17:08:48 -05001277static int
1278ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
1279 char *regex, int len, int type)
1280{
1281 char str[KSYM_SYMBOL_LEN];
1282 char *modname;
1283
1284 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1285
1286 if (!modname || strcmp(modname, mod))
1287 return 0;
1288
1289 /* blank search means to match all funcs in the mod */
1290 if (len)
1291 return ftrace_match(str, regex, len, type);
1292 else
1293 return 1;
1294}
1295
1296static void ftrace_match_module_records(char *buff, char *mod, int enable)
1297{
Steven Rostedt6a24a242009-02-17 11:20:26 -05001298 unsigned search_len = 0;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001299 struct ftrace_page *pg;
1300 struct dyn_ftrace *rec;
1301 int type = MATCH_FULL;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001302 char *search = buff;
1303 unsigned long flag;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001304 int not = 0;
1305
Steven Rostedt6a24a242009-02-17 11:20:26 -05001306 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1307
Steven Rostedt64e7c442009-02-13 17:08:48 -05001308 /* blank or '*' mean the same */
1309 if (strcmp(buff, "*") == 0)
1310 buff[0] = 0;
1311
1312 /* handle the case of 'dont filter this module' */
1313 if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
1314 buff[0] = 0;
1315 not = 1;
1316 }
1317
1318 if (strlen(buff)) {
1319 type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
1320 search_len = strlen(search);
1321 }
1322
Steven Rostedt52baf112009-02-14 01:15:39 -05001323 mutex_lock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001324 do_for_each_ftrace_rec(pg, rec) {
1325
1326 if (rec->flags & FTRACE_FL_FAILED)
1327 continue;
1328
1329 if (ftrace_match_module_record(rec, mod,
1330 search, search_len, type)) {
1331 if (not)
1332 rec->flags &= ~flag;
1333 else
1334 rec->flags |= flag;
1335 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001336 if (enable && (rec->flags & FTRACE_FL_FILTER))
1337 ftrace_filtered = 1;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001338
1339 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001340 mutex_unlock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001341}
1342
Steven Rostedtf6180772009-02-14 00:40:25 -05001343/*
1344 * We register the module command as a template to show others how
1345 * to register the a command as well.
1346 */
1347
1348static int
1349ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1350{
1351 char *mod;
1352
1353 /*
1354 * cmd == 'mod' because we only registered this func
1355 * for the 'mod' ftrace_func_command.
1356 * But if you register one func with multiple commands,
1357 * you can tell which command was used by the cmd
1358 * parameter.
1359 */
1360
1361 /* we must have a module name */
1362 if (!param)
1363 return -EINVAL;
1364
1365 mod = strsep(&param, ":");
1366 if (!strlen(mod))
1367 return -EINVAL;
1368
1369 ftrace_match_module_records(func, mod, enable);
1370 return 0;
1371}
1372
1373static struct ftrace_func_command ftrace_mod_cmd = {
1374 .name = "mod",
1375 .func = ftrace_mod_callback,
1376};
1377
1378static int __init ftrace_mod_cmd_init(void)
1379{
1380 return register_ftrace_command(&ftrace_mod_cmd);
1381}
1382device_initcall(ftrace_mod_cmd_init);
1383
Steven Rostedt59df055f2009-02-14 15:29:06 -05001384static void
Steven Rostedtb6887d72009-02-17 12:32:04 -05001385function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001386{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001387 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001388 struct hlist_head *hhd;
1389 struct hlist_node *n;
1390 unsigned long key;
1391 int resched;
1392
1393 key = hash_long(ip, FTRACE_HASH_BITS);
1394
1395 hhd = &ftrace_func_hash[key];
1396
1397 if (hlist_empty(hhd))
1398 return;
1399
1400 /*
1401 * Disable preemption for these calls to prevent a RCU grace
1402 * period. This syncs the hash iteration and freeing of items
1403 * on the hash. rcu_read_lock is too dangerous here.
1404 */
1405 resched = ftrace_preempt_disable();
1406 hlist_for_each_entry_rcu(entry, n, hhd, node) {
1407 if (entry->ip == ip)
1408 entry->ops->func(ip, parent_ip, &entry->data);
1409 }
1410 ftrace_preempt_enable(resched);
1411}
1412
Steven Rostedtb6887d72009-02-17 12:32:04 -05001413static struct ftrace_ops trace_probe_ops __read_mostly =
Steven Rostedt59df055f2009-02-14 15:29:06 -05001414{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001415 .func = function_trace_probe_call,
Steven Rostedt59df055f2009-02-14 15:29:06 -05001416};
1417
Steven Rostedtb6887d72009-02-17 12:32:04 -05001418static int ftrace_probe_registered;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001419
Steven Rostedtb6887d72009-02-17 12:32:04 -05001420static void __enable_ftrace_function_probe(void)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001421{
1422 int i;
1423
Steven Rostedtb6887d72009-02-17 12:32:04 -05001424 if (ftrace_probe_registered)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001425 return;
1426
1427 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1428 struct hlist_head *hhd = &ftrace_func_hash[i];
1429 if (hhd->first)
1430 break;
1431 }
1432 /* Nothing registered? */
1433 if (i == FTRACE_FUNC_HASHSIZE)
1434 return;
1435
Steven Rostedtb6887d72009-02-17 12:32:04 -05001436 __register_ftrace_function(&trace_probe_ops);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001437 ftrace_startup(0);
Steven Rostedtb6887d72009-02-17 12:32:04 -05001438 ftrace_probe_registered = 1;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001439}
1440
Steven Rostedtb6887d72009-02-17 12:32:04 -05001441static void __disable_ftrace_function_probe(void)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001442{
1443 int i;
1444
Steven Rostedtb6887d72009-02-17 12:32:04 -05001445 if (!ftrace_probe_registered)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001446 return;
1447
1448 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1449 struct hlist_head *hhd = &ftrace_func_hash[i];
1450 if (hhd->first)
1451 return;
1452 }
1453
1454 /* no more funcs left */
Steven Rostedtb6887d72009-02-17 12:32:04 -05001455 __unregister_ftrace_function(&trace_probe_ops);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001456 ftrace_shutdown(0);
Steven Rostedtb6887d72009-02-17 12:32:04 -05001457 ftrace_probe_registered = 0;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001458}
1459
1460
1461static void ftrace_free_entry_rcu(struct rcu_head *rhp)
1462{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001463 struct ftrace_func_probe *entry =
1464 container_of(rhp, struct ftrace_func_probe, rcu);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001465
1466 if (entry->ops->free)
1467 entry->ops->free(&entry->data);
1468 kfree(entry);
1469}
1470
1471
1472int
Steven Rostedtb6887d72009-02-17 12:32:04 -05001473register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05001474 void *data)
1475{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001476 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001477 struct ftrace_page *pg;
1478 struct dyn_ftrace *rec;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001479 int type, len, not;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001480 unsigned long key;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001481 int count = 0;
1482 char *search;
1483
1484 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
1485 len = strlen(search);
1486
Steven Rostedtb6887d72009-02-17 12:32:04 -05001487 /* we do not support '!' for function probes */
Steven Rostedt59df055f2009-02-14 15:29:06 -05001488 if (WARN_ON(not))
1489 return -EINVAL;
1490
1491 mutex_lock(&ftrace_lock);
1492 do_for_each_ftrace_rec(pg, rec) {
1493
1494 if (rec->flags & FTRACE_FL_FAILED)
1495 continue;
1496
1497 if (!ftrace_match_record(rec, search, len, type))
1498 continue;
1499
1500 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
1501 if (!entry) {
Steven Rostedtb6887d72009-02-17 12:32:04 -05001502 /* If we did not process any, then return error */
Steven Rostedt59df055f2009-02-14 15:29:06 -05001503 if (!count)
1504 count = -ENOMEM;
1505 goto out_unlock;
1506 }
1507
1508 count++;
1509
1510 entry->data = data;
1511
1512 /*
1513 * The caller might want to do something special
1514 * for each function we find. We call the callback
1515 * to give the caller an opportunity to do so.
1516 */
1517 if (ops->callback) {
1518 if (ops->callback(rec->ip, &entry->data) < 0) {
1519 /* caller does not like this func */
1520 kfree(entry);
1521 continue;
1522 }
1523 }
1524
1525 entry->ops = ops;
1526 entry->ip = rec->ip;
1527
1528 key = hash_long(entry->ip, FTRACE_HASH_BITS);
1529 hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
1530
1531 } while_for_each_ftrace_rec();
Steven Rostedtb6887d72009-02-17 12:32:04 -05001532 __enable_ftrace_function_probe();
Steven Rostedt59df055f2009-02-14 15:29:06 -05001533
1534 out_unlock:
1535 mutex_unlock(&ftrace_lock);
1536
1537 return count;
1538}
1539
1540enum {
Steven Rostedtb6887d72009-02-17 12:32:04 -05001541 PROBE_TEST_FUNC = 1,
1542 PROBE_TEST_DATA = 2
Steven Rostedt59df055f2009-02-14 15:29:06 -05001543};
1544
1545static void
Steven Rostedtb6887d72009-02-17 12:32:04 -05001546__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05001547 void *data, int flags)
1548{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001549 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001550 struct hlist_node *n, *tmp;
1551 char str[KSYM_SYMBOL_LEN];
1552 int type = MATCH_FULL;
1553 int i, len = 0;
1554 char *search;
1555
1556 if (glob && (strcmp(glob, "*") || !strlen(glob)))
1557 glob = NULL;
1558 else {
1559 int not;
1560
1561 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
1562 len = strlen(search);
1563
Steven Rostedtb6887d72009-02-17 12:32:04 -05001564 /* we do not support '!' for function probes */
Steven Rostedt59df055f2009-02-14 15:29:06 -05001565 if (WARN_ON(not))
1566 return;
1567 }
1568
1569 mutex_lock(&ftrace_lock);
1570 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1571 struct hlist_head *hhd = &ftrace_func_hash[i];
1572
1573 hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
1574
1575 /* break up if statements for readability */
Steven Rostedtb6887d72009-02-17 12:32:04 -05001576 if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001577 continue;
1578
Steven Rostedtb6887d72009-02-17 12:32:04 -05001579 if ((flags & PROBE_TEST_DATA) && entry->data != data)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001580 continue;
1581
1582 /* do this last, since it is the most expensive */
1583 if (glob) {
1584 kallsyms_lookup(entry->ip, NULL, NULL,
1585 NULL, str);
1586 if (!ftrace_match(str, glob, len, type))
1587 continue;
1588 }
1589
1590 hlist_del(&entry->node);
1591 call_rcu(&entry->rcu, ftrace_free_entry_rcu);
1592 }
1593 }
Steven Rostedtb6887d72009-02-17 12:32:04 -05001594 __disable_ftrace_function_probe();
Steven Rostedt59df055f2009-02-14 15:29:06 -05001595 mutex_unlock(&ftrace_lock);
1596}
1597
1598void
Steven Rostedtb6887d72009-02-17 12:32:04 -05001599unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05001600 void *data)
1601{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001602 __unregister_ftrace_function_probe(glob, ops, data,
1603 PROBE_TEST_FUNC | PROBE_TEST_DATA);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001604}
1605
1606void
Steven Rostedtb6887d72009-02-17 12:32:04 -05001607unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001608{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001609 __unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001610}
1611
Steven Rostedtb6887d72009-02-17 12:32:04 -05001612void unregister_ftrace_function_probe_all(char *glob)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001613{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001614 __unregister_ftrace_function_probe(glob, NULL, NULL, 0);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001615}
1616
Steven Rostedtf6180772009-02-14 00:40:25 -05001617static LIST_HEAD(ftrace_commands);
1618static DEFINE_MUTEX(ftrace_cmd_mutex);
1619
1620int register_ftrace_command(struct ftrace_func_command *cmd)
1621{
1622 struct ftrace_func_command *p;
1623 int ret = 0;
1624
1625 mutex_lock(&ftrace_cmd_mutex);
1626 list_for_each_entry(p, &ftrace_commands, list) {
1627 if (strcmp(cmd->name, p->name) == 0) {
1628 ret = -EBUSY;
1629 goto out_unlock;
1630 }
1631 }
1632 list_add(&cmd->list, &ftrace_commands);
1633 out_unlock:
1634 mutex_unlock(&ftrace_cmd_mutex);
1635
1636 return ret;
1637}
1638
1639int unregister_ftrace_command(struct ftrace_func_command *cmd)
1640{
1641 struct ftrace_func_command *p, *n;
1642 int ret = -ENODEV;
1643
1644 mutex_lock(&ftrace_cmd_mutex);
1645 list_for_each_entry_safe(p, n, &ftrace_commands, list) {
1646 if (strcmp(cmd->name, p->name) == 0) {
1647 ret = 0;
1648 list_del_init(&p->list);
1649 goto out_unlock;
1650 }
1651 }
1652 out_unlock:
1653 mutex_unlock(&ftrace_cmd_mutex);
1654
1655 return ret;
1656}
1657
Steven Rostedt64e7c442009-02-13 17:08:48 -05001658static int ftrace_process_regex(char *buff, int len, int enable)
1659{
Steven Rostedtf6180772009-02-14 00:40:25 -05001660 char *func, *command, *next = buff;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001661 struct ftrace_func_command *p;
Steven Rostedtf6180772009-02-14 00:40:25 -05001662 int ret = -EINVAL;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001663
1664 func = strsep(&next, ":");
1665
1666 if (!next) {
1667 ftrace_match_records(func, len, enable);
1668 return 0;
1669 }
1670
Steven Rostedtf6180772009-02-14 00:40:25 -05001671 /* command found */
Steven Rostedt64e7c442009-02-13 17:08:48 -05001672
1673 command = strsep(&next, ":");
1674
Steven Rostedtf6180772009-02-14 00:40:25 -05001675 mutex_lock(&ftrace_cmd_mutex);
1676 list_for_each_entry(p, &ftrace_commands, list) {
1677 if (strcmp(p->name, command) == 0) {
1678 ret = p->func(func, command, next, enable);
1679 goto out_unlock;
1680 }
Steven Rostedt64e7c442009-02-13 17:08:48 -05001681 }
Steven Rostedtf6180772009-02-14 00:40:25 -05001682 out_unlock:
1683 mutex_unlock(&ftrace_cmd_mutex);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001684
Steven Rostedtf6180772009-02-14 00:40:25 -05001685 return ret;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001686}
1687
Ingo Molnare309b412008-05-12 21:20:51 +02001688static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001689ftrace_regex_write(struct file *file, const char __user *ubuf,
1690 size_t cnt, loff_t *ppos, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001691{
1692 struct ftrace_iterator *iter;
1693 char ch;
1694 size_t read = 0;
1695 ssize_t ret;
1696
1697 if (!cnt || cnt < 0)
1698 return 0;
1699
Steven Rostedt41c52c02008-05-22 11:46:33 -04001700 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001701
1702 if (file->f_mode & FMODE_READ) {
1703 struct seq_file *m = file->private_data;
1704 iter = m->private;
1705 } else
1706 iter = file->private_data;
1707
1708 if (!*ppos) {
1709 iter->flags &= ~FTRACE_ITER_CONT;
1710 iter->buffer_idx = 0;
1711 }
1712
1713 ret = get_user(ch, ubuf++);
1714 if (ret)
1715 goto out;
1716 read++;
1717 cnt--;
1718
1719 if (!(iter->flags & ~FTRACE_ITER_CONT)) {
1720 /* skip white space */
1721 while (cnt && isspace(ch)) {
1722 ret = get_user(ch, ubuf++);
1723 if (ret)
1724 goto out;
1725 read++;
1726 cnt--;
1727 }
1728
Steven Rostedt5072c592008-05-12 21:20:43 +02001729 if (isspace(ch)) {
1730 file->f_pos += read;
1731 ret = read;
1732 goto out;
1733 }
1734
1735 iter->buffer_idx = 0;
1736 }
1737
1738 while (cnt && !isspace(ch)) {
1739 if (iter->buffer_idx < FTRACE_BUFF_MAX)
1740 iter->buffer[iter->buffer_idx++] = ch;
1741 else {
1742 ret = -EINVAL;
1743 goto out;
1744 }
1745 ret = get_user(ch, ubuf++);
1746 if (ret)
1747 goto out;
1748 read++;
1749 cnt--;
1750 }
1751
1752 if (isspace(ch)) {
1753 iter->filtered++;
1754 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001755 ret = ftrace_process_regex(iter->buffer,
1756 iter->buffer_idx, enable);
1757 if (ret)
1758 goto out;
Steven Rostedt5072c592008-05-12 21:20:43 +02001759 iter->buffer_idx = 0;
1760 } else
1761 iter->flags |= FTRACE_ITER_CONT;
1762
1763
1764 file->f_pos += read;
1765
1766 ret = read;
1767 out:
Steven Rostedt41c52c02008-05-22 11:46:33 -04001768 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001769
1770 return ret;
1771}
1772
Steven Rostedt41c52c02008-05-22 11:46:33 -04001773static ssize_t
1774ftrace_filter_write(struct file *file, const char __user *ubuf,
1775 size_t cnt, loff_t *ppos)
1776{
1777 return ftrace_regex_write(file, ubuf, cnt, ppos, 1);
1778}
1779
1780static ssize_t
1781ftrace_notrace_write(struct file *file, const char __user *ubuf,
1782 size_t cnt, loff_t *ppos)
1783{
1784 return ftrace_regex_write(file, ubuf, cnt, ppos, 0);
1785}
1786
1787static void
1788ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
1789{
1790 if (unlikely(ftrace_disabled))
1791 return;
1792
1793 mutex_lock(&ftrace_regex_lock);
1794 if (reset)
1795 ftrace_filter_reset(enable);
1796 if (buf)
Steven Rostedt7f24b312009-02-13 14:37:33 -05001797 ftrace_match_records(buf, len, enable);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001798 mutex_unlock(&ftrace_regex_lock);
1799}
1800
Steven Rostedt77a2b372008-05-12 21:20:45 +02001801/**
1802 * ftrace_set_filter - set a function to filter on in ftrace
1803 * @buf - the string that holds the function filter text.
1804 * @len - the length of the string.
1805 * @reset - non zero to reset all filters before applying this filter.
1806 *
1807 * Filters denote which functions should be enabled when tracing is enabled.
1808 * If @buf is NULL and reset is set, all functions will be enabled for tracing.
1809 */
Ingo Molnare309b412008-05-12 21:20:51 +02001810void ftrace_set_filter(unsigned char *buf, int len, int reset)
Steven Rostedt77a2b372008-05-12 21:20:45 +02001811{
Steven Rostedt41c52c02008-05-22 11:46:33 -04001812 ftrace_set_regex(buf, len, reset, 1);
1813}
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001814
Steven Rostedt41c52c02008-05-22 11:46:33 -04001815/**
1816 * ftrace_set_notrace - set a function to not trace in ftrace
1817 * @buf - the string that holds the function notrace text.
1818 * @len - the length of the string.
1819 * @reset - non zero to reset all filters before applying this filter.
1820 *
1821 * Notrace Filters denote which functions should not be enabled when tracing
1822 * is enabled. If @buf is NULL and reset is set, all functions will be enabled
1823 * for tracing.
1824 */
1825void ftrace_set_notrace(unsigned char *buf, int len, int reset)
1826{
1827 ftrace_set_regex(buf, len, reset, 0);
Steven Rostedt77a2b372008-05-12 21:20:45 +02001828}
1829
Ingo Molnare309b412008-05-12 21:20:51 +02001830static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04001831ftrace_regex_release(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001832{
1833 struct seq_file *m = (struct seq_file *)file->private_data;
1834 struct ftrace_iterator *iter;
1835
Steven Rostedt41c52c02008-05-22 11:46:33 -04001836 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001837 if (file->f_mode & FMODE_READ) {
1838 iter = m->private;
1839
1840 seq_release(inode, file);
1841 } else
1842 iter = file->private_data;
1843
1844 if (iter->buffer_idx) {
1845 iter->filtered++;
1846 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt7f24b312009-02-13 14:37:33 -05001847 ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001848 }
1849
Steven Rostedte6ea44e2009-02-14 01:42:44 -05001850 mutex_lock(&ftrace_lock);
Steven Rostedtee02a2e2008-11-15 16:31:41 -05001851 if (ftrace_start_up && ftrace_enabled)
Steven Rostedt5072c592008-05-12 21:20:43 +02001852 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05001853 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001854
1855 kfree(iter);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001856 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001857 return 0;
1858}
1859
Steven Rostedt41c52c02008-05-22 11:46:33 -04001860static int
1861ftrace_filter_release(struct inode *inode, struct file *file)
1862{
1863 return ftrace_regex_release(inode, file, 1);
1864}
1865
1866static int
1867ftrace_notrace_release(struct inode *inode, struct file *file)
1868{
1869 return ftrace_regex_release(inode, file, 0);
1870}
1871
Steven Rostedt5e2336a2009-03-05 21:44:55 -05001872static const struct file_operations ftrace_avail_fops = {
Steven Rostedt5072c592008-05-12 21:20:43 +02001873 .open = ftrace_avail_open,
1874 .read = seq_read,
1875 .llseek = seq_lseek,
1876 .release = ftrace_avail_release,
1877};
1878
Steven Rostedt5e2336a2009-03-05 21:44:55 -05001879static const struct file_operations ftrace_failures_fops = {
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301880 .open = ftrace_failures_open,
1881 .read = seq_read,
1882 .llseek = seq_lseek,
1883 .release = ftrace_avail_release,
1884};
1885
Steven Rostedt5e2336a2009-03-05 21:44:55 -05001886static const struct file_operations ftrace_filter_fops = {
Steven Rostedt5072c592008-05-12 21:20:43 +02001887 .open = ftrace_filter_open,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001888 .read = ftrace_regex_read,
Steven Rostedt5072c592008-05-12 21:20:43 +02001889 .write = ftrace_filter_write,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001890 .llseek = ftrace_regex_lseek,
Steven Rostedt5072c592008-05-12 21:20:43 +02001891 .release = ftrace_filter_release,
1892};
1893
Steven Rostedt5e2336a2009-03-05 21:44:55 -05001894static const struct file_operations ftrace_notrace_fops = {
Steven Rostedt41c52c02008-05-22 11:46:33 -04001895 .open = ftrace_notrace_open,
1896 .read = ftrace_regex_read,
1897 .write = ftrace_notrace_write,
1898 .llseek = ftrace_regex_lseek,
1899 .release = ftrace_notrace_release,
1900};
1901
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001902#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1903
1904static DEFINE_MUTEX(graph_lock);
1905
1906int ftrace_graph_count;
1907unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
1908
1909static void *
1910g_next(struct seq_file *m, void *v, loff_t *pos)
1911{
1912 unsigned long *array = m->private;
1913 int index = *pos;
1914
1915 (*pos)++;
1916
1917 if (index >= ftrace_graph_count)
1918 return NULL;
1919
1920 return &array[index];
1921}
1922
1923static void *g_start(struct seq_file *m, loff_t *pos)
1924{
1925 void *p = NULL;
1926
1927 mutex_lock(&graph_lock);
1928
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01001929 /* Nothing, tell g_show to print all functions are enabled */
1930 if (!ftrace_graph_count && !*pos)
1931 return (void *)1;
1932
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001933 p = g_next(m, p, pos);
1934
1935 return p;
1936}
1937
1938static void g_stop(struct seq_file *m, void *p)
1939{
1940 mutex_unlock(&graph_lock);
1941}
1942
1943static int g_show(struct seq_file *m, void *v)
1944{
1945 unsigned long *ptr = v;
1946 char str[KSYM_SYMBOL_LEN];
1947
1948 if (!ptr)
1949 return 0;
1950
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01001951 if (ptr == (unsigned long *)1) {
1952 seq_printf(m, "#### all functions enabled ####\n");
1953 return 0;
1954 }
1955
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001956 kallsyms_lookup(*ptr, NULL, NULL, NULL, str);
1957
1958 seq_printf(m, "%s\n", str);
1959
1960 return 0;
1961}
1962
1963static struct seq_operations ftrace_graph_seq_ops = {
1964 .start = g_start,
1965 .next = g_next,
1966 .stop = g_stop,
1967 .show = g_show,
1968};
1969
1970static int
1971ftrace_graph_open(struct inode *inode, struct file *file)
1972{
1973 int ret = 0;
1974
1975 if (unlikely(ftrace_disabled))
1976 return -ENODEV;
1977
1978 mutex_lock(&graph_lock);
1979 if ((file->f_mode & FMODE_WRITE) &&
1980 !(file->f_flags & O_APPEND)) {
1981 ftrace_graph_count = 0;
1982 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
1983 }
1984
1985 if (file->f_mode & FMODE_READ) {
1986 ret = seq_open(file, &ftrace_graph_seq_ops);
1987 if (!ret) {
1988 struct seq_file *m = file->private_data;
1989 m->private = ftrace_graph_funcs;
1990 }
1991 } else
1992 file->private_data = ftrace_graph_funcs;
1993 mutex_unlock(&graph_lock);
1994
1995 return ret;
1996}
1997
1998static ssize_t
1999ftrace_graph_read(struct file *file, char __user *ubuf,
2000 size_t cnt, loff_t *ppos)
2001{
2002 if (file->f_mode & FMODE_READ)
2003 return seq_read(file, ubuf, cnt, ppos);
2004 else
2005 return -EPERM;
2006}
2007
2008static int
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002009ftrace_set_func(unsigned long *array, int *idx, char *buffer)
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002010{
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002011 struct dyn_ftrace *rec;
2012 struct ftrace_page *pg;
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002013 int search_len;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002014 int found = 0;
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002015 int type, not;
2016 char *search;
2017 bool exists;
2018 int i;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002019
2020 if (ftrace_disabled)
2021 return -ENODEV;
2022
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002023 /* decode regex */
2024 type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
2025 if (not)
2026 return -EINVAL;
2027
2028 search_len = strlen(search);
2029
Steven Rostedt52baf112009-02-14 01:15:39 -05002030 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05002031 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002032
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002033 if (*idx >= FTRACE_GRAPH_MAX_FUNCS)
2034 break;
2035
Steven Rostedt265c8312009-02-13 12:43:56 -05002036 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
2037 continue;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002038
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002039 if (ftrace_match_record(rec, search, search_len, type)) {
2040 /* ensure it is not already in the array */
2041 exists = false;
2042 for (i = 0; i < *idx; i++)
2043 if (array[i] == rec->ip) {
2044 exists = true;
Steven Rostedt265c8312009-02-13 12:43:56 -05002045 break;
2046 }
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002047 if (!exists) {
2048 array[(*idx)++] = rec->ip;
2049 found = 1;
2050 }
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002051 }
Steven Rostedt265c8312009-02-13 12:43:56 -05002052 } while_for_each_ftrace_rec();
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002053
Steven Rostedt52baf112009-02-14 01:15:39 -05002054 mutex_unlock(&ftrace_lock);
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002055
2056 return found ? 0 : -EINVAL;
2057}
2058
2059static ssize_t
2060ftrace_graph_write(struct file *file, const char __user *ubuf,
2061 size_t cnt, loff_t *ppos)
2062{
2063 unsigned char buffer[FTRACE_BUFF_MAX+1];
2064 unsigned long *array;
2065 size_t read = 0;
2066 ssize_t ret;
2067 int index = 0;
2068 char ch;
2069
2070 if (!cnt || cnt < 0)
2071 return 0;
2072
2073 mutex_lock(&graph_lock);
2074
2075 if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) {
2076 ret = -EBUSY;
2077 goto out;
2078 }
2079
2080 if (file->f_mode & FMODE_READ) {
2081 struct seq_file *m = file->private_data;
2082 array = m->private;
2083 } else
2084 array = file->private_data;
2085
2086 ret = get_user(ch, ubuf++);
2087 if (ret)
2088 goto out;
2089 read++;
2090 cnt--;
2091
2092 /* skip white space */
2093 while (cnt && isspace(ch)) {
2094 ret = get_user(ch, ubuf++);
2095 if (ret)
2096 goto out;
2097 read++;
2098 cnt--;
2099 }
2100
2101 if (isspace(ch)) {
2102 *ppos += read;
2103 ret = read;
2104 goto out;
2105 }
2106
2107 while (cnt && !isspace(ch)) {
2108 if (index < FTRACE_BUFF_MAX)
2109 buffer[index++] = ch;
2110 else {
2111 ret = -EINVAL;
2112 goto out;
2113 }
2114 ret = get_user(ch, ubuf++);
2115 if (ret)
2116 goto out;
2117 read++;
2118 cnt--;
2119 }
2120 buffer[index] = 0;
2121
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002122 /* we allow only one expression at a time */
2123 ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002124 if (ret)
2125 goto out;
2126
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002127 file->f_pos += read;
2128
2129 ret = read;
2130 out:
2131 mutex_unlock(&graph_lock);
2132
2133 return ret;
2134}
2135
2136static const struct file_operations ftrace_graph_fops = {
2137 .open = ftrace_graph_open,
2138 .read = ftrace_graph_read,
2139 .write = ftrace_graph_write,
2140};
2141#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2142
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002143static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
Steven Rostedt5072c592008-05-12 21:20:43 +02002144{
Steven Rostedt5072c592008-05-12 21:20:43 +02002145 struct dentry *entry;
2146
Steven Rostedt5072c592008-05-12 21:20:43 +02002147 entry = debugfs_create_file("available_filter_functions", 0444,
2148 d_tracer, NULL, &ftrace_avail_fops);
2149 if (!entry)
2150 pr_warning("Could not create debugfs "
2151 "'available_filter_functions' entry\n");
2152
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05302153 entry = debugfs_create_file("failures", 0444,
2154 d_tracer, NULL, &ftrace_failures_fops);
2155 if (!entry)
2156 pr_warning("Could not create debugfs 'failures' entry\n");
2157
Steven Rostedt5072c592008-05-12 21:20:43 +02002158 entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer,
2159 NULL, &ftrace_filter_fops);
2160 if (!entry)
2161 pr_warning("Could not create debugfs "
2162 "'set_ftrace_filter' entry\n");
Steven Rostedt41c52c02008-05-22 11:46:33 -04002163
2164 entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer,
2165 NULL, &ftrace_notrace_fops);
2166 if (!entry)
2167 pr_warning("Could not create debugfs "
2168 "'set_ftrace_notrace' entry\n");
Steven Rostedtad90c0e2008-05-27 20:48:37 -04002169
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002170#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2171 entry = debugfs_create_file("set_graph_function", 0444, d_tracer,
2172 NULL,
2173 &ftrace_graph_fops);
2174 if (!entry)
2175 pr_warning("Could not create debugfs "
2176 "'set_graph_function' entry\n");
2177#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2178
Steven Rostedt5072c592008-05-12 21:20:43 +02002179 return 0;
2180}
2181
Steven Rostedt31e88902008-11-14 16:21:19 -08002182static int ftrace_convert_nops(struct module *mod,
2183 unsigned long *start,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002184 unsigned long *end)
2185{
2186 unsigned long *p;
2187 unsigned long addr;
2188 unsigned long flags;
2189
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002190 mutex_lock(&ftrace_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002191 p = start;
2192 while (p < end) {
2193 addr = ftrace_call_adjust(*p++);
Steven Rostedt20e52272008-11-14 16:21:19 -08002194 /*
2195 * Some architecture linkers will pad between
2196 * the different mcount_loc sections of different
2197 * object files to satisfy alignments.
2198 * Skip any NULL pointers.
2199 */
2200 if (!addr)
2201 continue;
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002202 ftrace_record_ip(addr);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002203 }
2204
Steven Rostedt08f5ac902008-10-23 09:33:07 -04002205 /* disable interrupts to prevent kstop machine */
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002206 local_irq_save(flags);
Steven Rostedt31e88902008-11-14 16:21:19 -08002207 ftrace_update_code(mod);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002208 local_irq_restore(flags);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002209 mutex_unlock(&ftrace_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002210
2211 return 0;
2212}
2213
Steven Rostedt31e88902008-11-14 16:21:19 -08002214void ftrace_init_module(struct module *mod,
2215 unsigned long *start, unsigned long *end)
Steven Rostedt90d595f2008-08-14 15:45:09 -04002216{
Steven Rostedt00fd61a2008-08-15 21:40:04 -04002217 if (ftrace_disabled || start == end)
Steven Rostedtfed19392008-08-14 22:47:19 -04002218 return;
Steven Rostedt31e88902008-11-14 16:21:19 -08002219 ftrace_convert_nops(mod, start, end);
Steven Rostedt90d595f2008-08-14 15:45:09 -04002220}
2221
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002222extern unsigned long __start_mcount_loc[];
2223extern unsigned long __stop_mcount_loc[];
2224
2225void __init ftrace_init(void)
2226{
2227 unsigned long count, addr, flags;
2228 int ret;
2229
2230 /* Keep the ftrace pointer to the stub */
2231 addr = (unsigned long)ftrace_stub;
2232
2233 local_irq_save(flags);
2234 ftrace_dyn_arch_init(&addr);
2235 local_irq_restore(flags);
2236
2237 /* ftrace_dyn_arch_init places the return code in addr */
2238 if (addr)
2239 goto failed;
2240
2241 count = __stop_mcount_loc - __start_mcount_loc;
2242
2243 ret = ftrace_dyn_table_alloc(count);
2244 if (ret)
2245 goto failed;
2246
2247 last_ftrace_enabled = ftrace_enabled = 1;
2248
Steven Rostedt31e88902008-11-14 16:21:19 -08002249 ret = ftrace_convert_nops(NULL,
2250 __start_mcount_loc,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002251 __stop_mcount_loc);
2252
2253 return;
2254 failed:
2255 ftrace_disabled = 1;
2256}
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002257
Steven Rostedt3d083392008-05-12 21:20:42 +02002258#else
Frederic Weisbecker0b6e4d52008-10-28 20:17:38 +01002259
2260static int __init ftrace_nodyn_init(void)
2261{
2262 ftrace_enabled = 1;
2263 return 0;
2264}
2265device_initcall(ftrace_nodyn_init);
2266
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002267static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
2268static inline void ftrace_startup_enable(int command) { }
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002269/* Keep as macros so we do not need to define the commands */
2270# define ftrace_startup(command) do { } while (0)
2271# define ftrace_shutdown(command) do { } while (0)
Ingo Molnarc7aafc52008-05-12 21:20:45 +02002272# define ftrace_startup_sysctl() do { } while (0)
2273# define ftrace_shutdown_sysctl() do { } while (0)
Steven Rostedt3d083392008-05-12 21:20:42 +02002274#endif /* CONFIG_DYNAMIC_FTRACE */
2275
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002276static ssize_t
2277ftrace_pid_read(struct file *file, char __user *ubuf,
2278 size_t cnt, loff_t *ppos)
2279{
2280 char buf[64];
2281 int r;
2282
Steven Rostedte32d8952008-12-04 00:26:41 -05002283 if (ftrace_pid_trace == ftrace_swapper_pid)
2284 r = sprintf(buf, "swapper tasks\n");
2285 else if (ftrace_pid_trace)
Steven Rostedt978f3a42008-12-04 00:26:40 -05002286 r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace));
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002287 else
2288 r = sprintf(buf, "no pid\n");
2289
2290 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2291}
2292
Steven Rostedte32d8952008-12-04 00:26:41 -05002293static void clear_ftrace_swapper(void)
2294{
2295 struct task_struct *p;
2296 int cpu;
2297
2298 get_online_cpus();
2299 for_each_online_cpu(cpu) {
2300 p = idle_task(cpu);
2301 clear_tsk_trace_trace(p);
2302 }
2303 put_online_cpus();
2304}
2305
2306static void set_ftrace_swapper(void)
2307{
2308 struct task_struct *p;
2309 int cpu;
2310
2311 get_online_cpus();
2312 for_each_online_cpu(cpu) {
2313 p = idle_task(cpu);
2314 set_tsk_trace_trace(p);
2315 }
2316 put_online_cpus();
2317}
2318
2319static void clear_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05002320{
2321 struct task_struct *p;
2322
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002323 rcu_read_lock();
Steven Rostedte32d8952008-12-04 00:26:41 -05002324 do_each_pid_task(pid, PIDTYPE_PID, p) {
Steven Rostedt978f3a42008-12-04 00:26:40 -05002325 clear_tsk_trace_trace(p);
Steven Rostedte32d8952008-12-04 00:26:41 -05002326 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002327 rcu_read_unlock();
2328
Steven Rostedte32d8952008-12-04 00:26:41 -05002329 put_pid(pid);
Steven Rostedt978f3a42008-12-04 00:26:40 -05002330}
2331
Steven Rostedte32d8952008-12-04 00:26:41 -05002332static void set_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05002333{
2334 struct task_struct *p;
2335
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002336 rcu_read_lock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05002337 do_each_pid_task(pid, PIDTYPE_PID, p) {
2338 set_tsk_trace_trace(p);
2339 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002340 rcu_read_unlock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05002341}
2342
Steven Rostedte32d8952008-12-04 00:26:41 -05002343static void clear_ftrace_pid_task(struct pid **pid)
2344{
2345 if (*pid == ftrace_swapper_pid)
2346 clear_ftrace_swapper();
2347 else
2348 clear_ftrace_pid(*pid);
2349
2350 *pid = NULL;
2351}
2352
2353static void set_ftrace_pid_task(struct pid *pid)
2354{
2355 if (pid == ftrace_swapper_pid)
2356 set_ftrace_swapper();
2357 else
2358 set_ftrace_pid(pid);
2359}
2360
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002361static ssize_t
2362ftrace_pid_write(struct file *filp, const char __user *ubuf,
2363 size_t cnt, loff_t *ppos)
2364{
Steven Rostedt978f3a42008-12-04 00:26:40 -05002365 struct pid *pid;
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002366 char buf[64];
2367 long val;
2368 int ret;
2369
2370 if (cnt >= sizeof(buf))
2371 return -EINVAL;
2372
2373 if (copy_from_user(&buf, ubuf, cnt))
2374 return -EFAULT;
2375
2376 buf[cnt] = 0;
2377
2378 ret = strict_strtol(buf, 10, &val);
2379 if (ret < 0)
2380 return ret;
2381
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002382 mutex_lock(&ftrace_lock);
Steven Rostedt978f3a42008-12-04 00:26:40 -05002383 if (val < 0) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002384 /* disable pid tracing */
Steven Rostedt978f3a42008-12-04 00:26:40 -05002385 if (!ftrace_pid_trace)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002386 goto out;
Steven Rostedt978f3a42008-12-04 00:26:40 -05002387
2388 clear_ftrace_pid_task(&ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002389
2390 } else {
Steven Rostedte32d8952008-12-04 00:26:41 -05002391 /* swapper task is special */
2392 if (!val) {
2393 pid = ftrace_swapper_pid;
2394 if (pid == ftrace_pid_trace)
2395 goto out;
2396 } else {
2397 pid = find_get_pid(val);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002398
Steven Rostedte32d8952008-12-04 00:26:41 -05002399 if (pid == ftrace_pid_trace) {
2400 put_pid(pid);
2401 goto out;
2402 }
Steven Rostedt978f3a42008-12-04 00:26:40 -05002403 }
2404
2405 if (ftrace_pid_trace)
2406 clear_ftrace_pid_task(&ftrace_pid_trace);
2407
2408 if (!pid)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002409 goto out;
2410
Steven Rostedt978f3a42008-12-04 00:26:40 -05002411 ftrace_pid_trace = pid;
Steven Rostedt0ef8cde2008-12-03 15:36:58 -05002412
Steven Rostedt978f3a42008-12-04 00:26:40 -05002413 set_ftrace_pid_task(ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002414 }
2415
2416 /* update the function call */
2417 ftrace_update_pid_func();
2418 ftrace_startup_enable(0);
2419
2420 out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002421 mutex_unlock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002422
2423 return cnt;
2424}
2425
Steven Rostedt5e2336a2009-03-05 21:44:55 -05002426static const struct file_operations ftrace_pid_fops = {
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002427 .read = ftrace_pid_read,
2428 .write = ftrace_pid_write,
2429};
2430
2431static __init int ftrace_init_debugfs(void)
2432{
2433 struct dentry *d_tracer;
2434 struct dentry *entry;
2435
2436 d_tracer = tracing_init_dentry();
2437 if (!d_tracer)
2438 return 0;
2439
2440 ftrace_init_dyn_debugfs(d_tracer);
2441
2442 entry = debugfs_create_file("set_ftrace_pid", 0644, d_tracer,
2443 NULL, &ftrace_pid_fops);
2444 if (!entry)
2445 pr_warning("Could not create debugfs "
2446 "'set_ftrace_pid' entry\n");
2447 return 0;
2448}
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002449fs_initcall(ftrace_init_debugfs);
2450
Steven Rostedt3d083392008-05-12 21:20:42 +02002451/**
Steven Rostedt81adbdc2008-10-23 09:33:02 -04002452 * ftrace_kill - kill ftrace
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002453 *
2454 * This function should be used by panic code. It stops ftrace
2455 * but in a not so nice way. If you need to simply kill ftrace
2456 * from a non-atomic section, use ftrace_kill.
2457 */
Steven Rostedt81adbdc2008-10-23 09:33:02 -04002458void ftrace_kill(void)
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002459{
2460 ftrace_disabled = 1;
2461 ftrace_enabled = 0;
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002462 clear_ftrace_function();
2463}
2464
2465/**
Steven Rostedt3d083392008-05-12 21:20:42 +02002466 * register_ftrace_function - register a function for profiling
2467 * @ops - ops structure that holds the function for profiling.
2468 *
2469 * Register a function to be called by all functions in the
2470 * kernel.
2471 *
2472 * Note: @ops->func and all the functions it calls must be labeled
2473 * with "notrace", otherwise it will go into a
2474 * recursive loop.
2475 */
2476int register_ftrace_function(struct ftrace_ops *ops)
2477{
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002478 int ret;
2479
Steven Rostedt4eebcc82008-05-12 21:20:48 +02002480 if (unlikely(ftrace_disabled))
2481 return -1;
2482
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002483 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002484
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002485 ret = __register_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002486 ftrace_startup(0);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002487
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002488 mutex_unlock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002489 return ret;
Steven Rostedt3d083392008-05-12 21:20:42 +02002490}
2491
2492/**
Uwe Kleine-Koenig32632922009-01-12 23:35:50 +01002493 * unregister_ftrace_function - unregister a function for profiling.
Steven Rostedt3d083392008-05-12 21:20:42 +02002494 * @ops - ops structure that holds the function to unregister
2495 *
2496 * Unregister a function that was added to be called by ftrace profiling.
2497 */
2498int unregister_ftrace_function(struct ftrace_ops *ops)
2499{
2500 int ret;
2501
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002502 mutex_lock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02002503 ret = __unregister_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002504 ftrace_shutdown(0);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002505 mutex_unlock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002506
2507 return ret;
2508}
2509
Ingo Molnare309b412008-05-12 21:20:51 +02002510int
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002511ftrace_enable_sysctl(struct ctl_table *table, int write,
Steven Rostedt5072c592008-05-12 21:20:43 +02002512 struct file *file, void __user *buffer, size_t *lenp,
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002513 loff_t *ppos)
2514{
2515 int ret;
2516
Steven Rostedt4eebcc82008-05-12 21:20:48 +02002517 if (unlikely(ftrace_disabled))
2518 return -ENODEV;
2519
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002520 mutex_lock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002521
Steven Rostedt5072c592008-05-12 21:20:43 +02002522 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002523
2524 if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
2525 goto out;
2526
2527 last_ftrace_enabled = ftrace_enabled;
2528
2529 if (ftrace_enabled) {
2530
2531 ftrace_startup_sysctl();
2532
2533 /* we are starting ftrace again */
2534 if (ftrace_list != &ftrace_list_end) {
2535 if (ftrace_list->next == &ftrace_list_end)
2536 ftrace_trace_function = ftrace_list->func;
2537 else
2538 ftrace_trace_function = ftrace_list_func;
2539 }
2540
2541 } else {
2542 /* stopping ftrace calls (just send to ftrace_stub) */
2543 ftrace_trace_function = ftrace_stub;
2544
2545 ftrace_shutdown_sysctl();
2546 }
2547
2548 out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002549 mutex_unlock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02002550 return ret;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02002551}
Ingo Molnarf17845e2008-10-24 12:47:10 +02002552
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002553#ifdef CONFIG_FUNCTION_GRAPH_TRACER
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002554
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002555static atomic_t ftrace_graph_active;
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002556static struct notifier_block ftrace_suspend_notifier;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002557
Steven Rostedte49dc192008-12-02 23:50:05 -05002558int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
2559{
2560 return 0;
2561}
2562
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002563/* The callbacks that hook a function */
2564trace_func_graph_ret_t ftrace_graph_return =
2565 (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05002566trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002567
2568/* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */
2569static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
2570{
2571 int i;
2572 int ret = 0;
2573 unsigned long flags;
2574 int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
2575 struct task_struct *g, *t;
2576
2577 for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) {
2578 ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH
2579 * sizeof(struct ftrace_ret_stack),
2580 GFP_KERNEL);
2581 if (!ret_stack_list[i]) {
2582 start = 0;
2583 end = i;
2584 ret = -ENOMEM;
2585 goto free;
2586 }
2587 }
2588
2589 read_lock_irqsave(&tasklist_lock, flags);
2590 do_each_thread(g, t) {
2591 if (start == end) {
2592 ret = -EAGAIN;
2593 goto unlock;
2594 }
2595
2596 if (t->ret_stack == NULL) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002597 t->curr_ret_stack = -1;
Frederic Weisbecker48d68b22008-12-02 00:20:39 +01002598 /* Make sure IRQs see the -1 first: */
2599 barrier();
2600 t->ret_stack = ret_stack_list[start++];
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01002601 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002602 atomic_set(&t->trace_overrun, 0);
2603 }
2604 } while_each_thread(g, t);
2605
2606unlock:
2607 read_unlock_irqrestore(&tasklist_lock, flags);
2608free:
2609 for (i = start; i < end; i++)
2610 kfree(ret_stack_list[i]);
2611 return ret;
2612}
2613
2614/* Allocate a return stack for each task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002615static int start_graph_tracing(void)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002616{
2617 struct ftrace_ret_stack **ret_stack_list;
Frederic Weisbecker5b058bc2009-02-17 18:35:34 +01002618 int ret, cpu;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002619
2620 ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE *
2621 sizeof(struct ftrace_ret_stack *),
2622 GFP_KERNEL);
2623
2624 if (!ret_stack_list)
2625 return -ENOMEM;
2626
Frederic Weisbecker5b058bc2009-02-17 18:35:34 +01002627 /* The cpu_boot init_task->ret_stack will never be freed */
2628 for_each_online_cpu(cpu)
2629 ftrace_graph_init_task(idle_task(cpu));
2630
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002631 do {
2632 ret = alloc_retstack_tasklist(ret_stack_list);
2633 } while (ret == -EAGAIN);
2634
2635 kfree(ret_stack_list);
2636 return ret;
2637}
2638
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002639/*
2640 * Hibernation protection.
2641 * The state of the current task is too much unstable during
2642 * suspend/restore to disk. We want to protect against that.
2643 */
2644static int
2645ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
2646 void *unused)
2647{
2648 switch (state) {
2649 case PM_HIBERNATION_PREPARE:
2650 pause_graph_tracing();
2651 break;
2652
2653 case PM_POST_HIBERNATION:
2654 unpause_graph_tracing();
2655 break;
2656 }
2657 return NOTIFY_DONE;
2658}
2659
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002660int register_ftrace_graph(trace_func_graph_ret_t retfunc,
2661 trace_func_graph_ent_t entryfunc)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002662{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002663 int ret = 0;
2664
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002665 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002666
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002667 ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
2668 register_pm_notifier(&ftrace_suspend_notifier);
2669
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002670 atomic_inc(&ftrace_graph_active);
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002671 ret = start_graph_tracing();
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002672 if (ret) {
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002673 atomic_dec(&ftrace_graph_active);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002674 goto out;
2675 }
Steven Rostedte53a6312008-11-26 00:16:25 -05002676
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002677 ftrace_graph_return = retfunc;
2678 ftrace_graph_entry = entryfunc;
Steven Rostedte53a6312008-11-26 00:16:25 -05002679
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002680 ftrace_startup(FTRACE_START_FUNC_RET);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002681
2682out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002683 mutex_unlock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002684 return ret;
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002685}
2686
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002687void unregister_ftrace_graph(void)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002688{
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002689 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002690
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002691 atomic_dec(&ftrace_graph_active);
2692 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05002693 ftrace_graph_entry = ftrace_graph_entry_stub;
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002694 ftrace_shutdown(FTRACE_STOP_FUNC_RET);
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002695 unregister_pm_notifier(&ftrace_suspend_notifier);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002696
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002697 mutex_unlock(&ftrace_lock);
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002698}
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002699
2700/* Allocate a return stack for newly created task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002701void ftrace_graph_init_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002702{
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002703 if (atomic_read(&ftrace_graph_active)) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002704 t->ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
2705 * sizeof(struct ftrace_ret_stack),
2706 GFP_KERNEL);
2707 if (!t->ret_stack)
2708 return;
2709 t->curr_ret_stack = -1;
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01002710 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002711 atomic_set(&t->trace_overrun, 0);
2712 } else
2713 t->ret_stack = NULL;
2714}
2715
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002716void ftrace_graph_exit_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002717{
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01002718 struct ftrace_ret_stack *ret_stack = t->ret_stack;
2719
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002720 t->ret_stack = NULL;
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01002721 /* NULL must become visible to IRQs before we free it: */
2722 barrier();
2723
2724 kfree(ret_stack);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002725}
Steven Rostedt14a866c2008-12-02 23:50:02 -05002726
2727void ftrace_graph_stop(void)
2728{
2729 ftrace_stop();
2730}
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002731#endif
2732