blob: 4771732037eefa10fc3589aa3e45e035ca3b8498 [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>
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020030
Abhishek Sagar395a59d2008-06-21 23:47:27 +053031#include <asm/ftrace.h>
32
Steven Rostedt3d083392008-05-12 21:20:42 +020033#include "trace.h"
34
Steven Rostedt69128962008-10-23 09:33:03 -040035#define FTRACE_WARN_ON(cond) \
36 do { \
37 if (WARN_ON(cond)) \
38 ftrace_kill(); \
39 } while (0)
40
41#define FTRACE_WARN_ON_ONCE(cond) \
42 do { \
43 if (WARN_ON_ONCE(cond)) \
44 ftrace_kill(); \
45 } while (0)
46
Steven Rostedt4eebcc82008-05-12 21:20:48 +020047/* ftrace_enabled is a method to turn ftrace on or off */
48int ftrace_enabled __read_mostly;
Steven Rostedtd61f82d2008-05-12 21:20:43 +020049static int last_ftrace_enabled;
Steven Rostedtb0fc4942008-05-12 21:20:43 +020050
Steven Rostedt0ef8cde2008-12-03 15:36:58 -050051/* set when tracing only a pid */
Steven Rostedt978f3a42008-12-04 00:26:40 -050052struct pid *ftrace_pid_trace;
Steven Rostedt21bbecd2008-12-04 23:30:56 -050053static struct pid * const ftrace_swapper_pid = &init_struct_pid;
Steven Rostedtdf4fc312008-11-26 00:16:23 -050054
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050055/* Quick disabling of function tracer. */
56int function_trace_stop;
57
Steven Rostedt4eebcc82008-05-12 21:20:48 +020058/*
59 * ftrace_disabled is set when an anomaly is discovered.
60 * ftrace_disabled is much stronger than ftrace_enabled.
61 */
62static int ftrace_disabled __read_mostly;
63
Steven Rostedt52baf112009-02-14 01:15:39 -050064static DEFINE_MUTEX(ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +020065static DEFINE_MUTEX(ftrace_sysctl_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -050066static DEFINE_MUTEX(ftrace_start_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +020067
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020068static struct ftrace_ops ftrace_list_end __read_mostly =
69{
70 .func = ftrace_stub,
71};
72
73static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
74ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050075ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -050076ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020077
Ingo Molnarf2252932008-05-22 10:37:48 +020078static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020079{
80 struct ftrace_ops *op = ftrace_list;
81
82 /* in case someone actually ports this to alpha! */
83 read_barrier_depends();
84
85 while (op != &ftrace_list_end) {
86 /* silly alpha */
87 read_barrier_depends();
88 op->func(ip, parent_ip);
89 op = op->next;
90 };
91}
92
Steven Rostedtdf4fc312008-11-26 00:16:23 -050093static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip)
94{
Steven Rostedt0ef8cde2008-12-03 15:36:58 -050095 if (!test_tsk_trace_trace(current))
Steven Rostedtdf4fc312008-11-26 00:16:23 -050096 return;
97
98 ftrace_pid_function(ip, parent_ip);
99}
100
101static void set_ftrace_pid_function(ftrace_func_t func)
102{
103 /* do not set ftrace_pid_function to itself! */
104 if (func != ftrace_pid_func)
105 ftrace_pid_function = func;
106}
107
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200108/**
Steven Rostedt3d083392008-05-12 21:20:42 +0200109 * clear_ftrace_function - reset the ftrace function
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200110 *
Steven Rostedt3d083392008-05-12 21:20:42 +0200111 * This NULLs the ftrace function and in essence stops
112 * tracing. There may be lag
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200113 */
Steven Rostedt3d083392008-05-12 21:20:42 +0200114void clear_ftrace_function(void)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200115{
Steven Rostedt3d083392008-05-12 21:20:42 +0200116 ftrace_trace_function = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500117 __ftrace_trace_function = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500118 ftrace_pid_function = ftrace_stub;
Steven Rostedt3d083392008-05-12 21:20:42 +0200119}
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200120
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500121#ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
122/*
123 * For those archs that do not test ftrace_trace_stop in their
124 * mcount call site, we need to do it from C.
125 */
126static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
127{
128 if (function_trace_stop)
129 return;
130
131 __ftrace_trace_function(ip, parent_ip);
132}
133#endif
134
Ingo Molnare309b412008-05-12 21:20:51 +0200135static int __register_ftrace_function(struct ftrace_ops *ops)
Steven Rostedt3d083392008-05-12 21:20:42 +0200136{
Steven Rostedt52baf112009-02-14 01:15:39 -0500137 mutex_lock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200138
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200139 ops->next = ftrace_list;
140 /*
141 * We are entering ops into the ftrace_list but another
142 * CPU might be walking that list. We need to make sure
143 * the ops->next pointer is valid before another CPU sees
144 * the ops pointer included into the ftrace_list.
145 */
146 smp_wmb();
147 ftrace_list = ops;
Steven Rostedt3d083392008-05-12 21:20:42 +0200148
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200149 if (ftrace_enabled) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500150 ftrace_func_t func;
151
152 if (ops->next == &ftrace_list_end)
153 func = ops->func;
154 else
155 func = ftrace_list_func;
156
Steven Rostedt978f3a42008-12-04 00:26:40 -0500157 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500158 set_ftrace_pid_function(func);
159 func = ftrace_pid_func;
160 }
161
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200162 /*
163 * For one func, simply call it directly.
164 * For more than one func, call the chain.
165 */
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500166#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500167 ftrace_trace_function = func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500168#else
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500169 __ftrace_trace_function = func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500170 ftrace_trace_function = ftrace_test_stop_func;
171#endif
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200172 }
Steven Rostedt3d083392008-05-12 21:20:42 +0200173
Steven Rostedt52baf112009-02-14 01:15:39 -0500174 mutex_unlock(&ftrace_lock);
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200175
176 return 0;
177}
178
Ingo Molnare309b412008-05-12 21:20:51 +0200179static int __unregister_ftrace_function(struct ftrace_ops *ops)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200180{
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200181 struct ftrace_ops **p;
182 int ret = 0;
183
Steven Rostedt52baf112009-02-14 01:15:39 -0500184 mutex_lock(&ftrace_lock);
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200185
186 /*
Steven Rostedt3d083392008-05-12 21:20:42 +0200187 * If we are removing the last function, then simply point
188 * to the ftrace_stub.
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200189 */
190 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
191 ftrace_trace_function = ftrace_stub;
192 ftrace_list = &ftrace_list_end;
193 goto out;
194 }
195
196 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
197 if (*p == ops)
198 break;
199
200 if (*p != ops) {
201 ret = -1;
202 goto out;
203 }
204
205 *p = (*p)->next;
206
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200207 if (ftrace_enabled) {
208 /* If we only have one func left, then call that directly */
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500209 if (ftrace_list->next == &ftrace_list_end) {
210 ftrace_func_t func = ftrace_list->func;
211
Steven Rostedt978f3a42008-12-04 00:26:40 -0500212 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500213 set_ftrace_pid_function(func);
214 func = ftrace_pid_func;
215 }
216#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
217 ftrace_trace_function = func;
218#else
219 __ftrace_trace_function = func;
220#endif
221 }
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200222 }
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200223
224 out:
Steven Rostedt52baf112009-02-14 01:15:39 -0500225 mutex_unlock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200226
227 return ret;
228}
229
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500230static void ftrace_update_pid_func(void)
231{
232 ftrace_func_t func;
233
Steven Rostedt52baf112009-02-14 01:15:39 -0500234 mutex_lock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500235
236 if (ftrace_trace_function == ftrace_stub)
237 goto out;
238
239 func = ftrace_trace_function;
240
Steven Rostedt978f3a42008-12-04 00:26:40 -0500241 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500242 set_ftrace_pid_function(func);
243 func = ftrace_pid_func;
244 } else {
Liming Wang66eafeb2008-12-02 10:33:08 +0800245 if (func == ftrace_pid_func)
246 func = ftrace_pid_function;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500247 }
248
249#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
250 ftrace_trace_function = func;
251#else
252 __ftrace_trace_function = func;
253#endif
254
255 out:
Steven Rostedt52baf112009-02-14 01:15:39 -0500256 mutex_unlock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500257}
258
Steven Rostedt3d083392008-05-12 21:20:42 +0200259#ifdef CONFIG_DYNAMIC_FTRACE
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400260#ifndef CONFIG_FTRACE_MCOUNT_RECORD
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400261# error Dynamic ftrace depends on MCOUNT_RECORD
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400262#endif
263
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200264enum {
265 FTRACE_ENABLE_CALLS = (1 << 0),
266 FTRACE_DISABLE_CALLS = (1 << 1),
267 FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
268 FTRACE_ENABLE_MCOUNT = (1 << 3),
269 FTRACE_DISABLE_MCOUNT = (1 << 4),
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500270 FTRACE_START_FUNC_RET = (1 << 5),
271 FTRACE_STOP_FUNC_RET = (1 << 6),
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200272};
273
Steven Rostedt5072c592008-05-12 21:20:43 +0200274static int ftrace_filtered;
275
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400276static LIST_HEAD(ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200277
Steven Rostedt41c52c02008-05-22 11:46:33 -0400278static DEFINE_MUTEX(ftrace_regex_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200279
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200280struct ftrace_page {
281 struct ftrace_page *next;
Steven Rostedt431aa3f2009-01-06 12:43:01 -0500282 int index;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200283 struct dyn_ftrace records[];
David Milleraa5e5ce2008-05-13 22:06:56 -0700284};
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200285
286#define ENTRIES_PER_PAGE \
287 ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
288
289/* estimate from running different kernels */
290#define NR_TO_INIT 10000
291
292static struct ftrace_page *ftrace_pages_start;
293static struct ftrace_page *ftrace_pages;
294
Steven Rostedt37ad5082008-05-12 21:20:48 +0200295static struct dyn_ftrace *ftrace_free_records;
296
Steven Rostedt265c8312009-02-13 12:43:56 -0500297/*
298 * This is a double for. Do not use 'break' to break out of the loop,
299 * you must use a goto.
300 */
301#define do_for_each_ftrace_rec(pg, rec) \
302 for (pg = ftrace_pages_start; pg; pg = pg->next) { \
303 int _____i; \
304 for (_____i = 0; _____i < pg->index; _____i++) { \
305 rec = &pg->records[_____i];
306
307#define while_for_each_ftrace_rec() \
308 } \
309 }
Abhishek Sagarecea6562008-06-21 23:47:53 +0530310
311#ifdef CONFIG_KPROBES
Ingo Molnarf17845e2008-10-24 12:47:10 +0200312
313static int frozen_record_count;
314
Abhishek Sagarecea6562008-06-21 23:47:53 +0530315static inline void freeze_record(struct dyn_ftrace *rec)
316{
317 if (!(rec->flags & FTRACE_FL_FROZEN)) {
318 rec->flags |= FTRACE_FL_FROZEN;
319 frozen_record_count++;
320 }
321}
322
323static inline void unfreeze_record(struct dyn_ftrace *rec)
324{
325 if (rec->flags & FTRACE_FL_FROZEN) {
326 rec->flags &= ~FTRACE_FL_FROZEN;
327 frozen_record_count--;
328 }
329}
330
331static inline int record_frozen(struct dyn_ftrace *rec)
332{
333 return rec->flags & FTRACE_FL_FROZEN;
334}
335#else
336# define freeze_record(rec) ({ 0; })
337# define unfreeze_record(rec) ({ 0; })
338# define record_frozen(rec) ({ 0; })
339#endif /* CONFIG_KPROBES */
340
Ingo Molnare309b412008-05-12 21:20:51 +0200341static void ftrace_free_rec(struct dyn_ftrace *rec)
Steven Rostedt37ad5082008-05-12 21:20:48 +0200342{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200343 rec->ip = (unsigned long)ftrace_free_records;
344 ftrace_free_records = rec;
345 rec->flags |= FTRACE_FL_FREE;
346}
347
Steven Rostedtfed19392008-08-14 22:47:19 -0400348void ftrace_release(void *start, unsigned long size)
349{
350 struct dyn_ftrace *rec;
351 struct ftrace_page *pg;
352 unsigned long s = (unsigned long)start;
353 unsigned long e = s + size;
Steven Rostedtfed19392008-08-14 22:47:19 -0400354
Steven Rostedt00fd61a2008-08-15 21:40:04 -0400355 if (ftrace_disabled || !start)
Steven Rostedtfed19392008-08-14 22:47:19 -0400356 return;
357
Steven Rostedt52baf112009-02-14 01:15:39 -0500358 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -0500359 do_for_each_ftrace_rec(pg, rec) {
360 if ((rec->ip >= s) && (rec->ip < e))
361 ftrace_free_rec(rec);
362 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -0500363 mutex_unlock(&ftrace_lock);
Steven Rostedtfed19392008-08-14 22:47:19 -0400364}
365
Ingo Molnare309b412008-05-12 21:20:51 +0200366static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200367{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200368 struct dyn_ftrace *rec;
369
370 /* First check for freed records */
371 if (ftrace_free_records) {
372 rec = ftrace_free_records;
373
Steven Rostedt37ad5082008-05-12 21:20:48 +0200374 if (unlikely(!(rec->flags & FTRACE_FL_FREE))) {
Steven Rostedt69128962008-10-23 09:33:03 -0400375 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt37ad5082008-05-12 21:20:48 +0200376 ftrace_free_records = NULL;
377 return NULL;
378 }
379
380 ftrace_free_records = (void *)rec->ip;
381 memset(rec, 0, sizeof(*rec));
382 return rec;
383 }
384
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200385 if (ftrace_pages->index == ENTRIES_PER_PAGE) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400386 if (!ftrace_pages->next) {
387 /* allocate another page */
388 ftrace_pages->next =
389 (void *)get_zeroed_page(GFP_KERNEL);
390 if (!ftrace_pages->next)
391 return NULL;
392 }
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200393 ftrace_pages = ftrace_pages->next;
394 }
395
396 return &ftrace_pages->records[ftrace_pages->index++];
397}
398
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400399static struct dyn_ftrace *
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200400ftrace_record_ip(unsigned long ip)
Steven Rostedt3d083392008-05-12 21:20:42 +0200401{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400402 struct dyn_ftrace *rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200403
Steven Rostedtf3c7ac42008-11-14 16:21:19 -0800404 if (ftrace_disabled)
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400405 return NULL;
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200406
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400407 rec = ftrace_alloc_dyn_node(ip);
408 if (!rec)
409 return NULL;
Steven Rostedt3d083392008-05-12 21:20:42 +0200410
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400411 rec->ip = ip;
Steven Rostedt3d083392008-05-12 21:20:42 +0200412
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400413 list_add(&rec->list, &ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200414
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400415 return rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200416}
417
Steven Rostedt05736a42008-09-22 14:55:47 -0700418static void print_ip_ins(const char *fmt, unsigned char *p)
419{
420 int i;
421
422 printk(KERN_CONT "%s", fmt);
423
424 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
425 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
426}
427
Steven Rostedt31e88902008-11-14 16:21:19 -0800428static void ftrace_bug(int failed, unsigned long ip)
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800429{
430 switch (failed) {
431 case -EFAULT:
432 FTRACE_WARN_ON_ONCE(1);
433 pr_info("ftrace faulted on modifying ");
434 print_ip_sym(ip);
435 break;
436 case -EINVAL:
437 FTRACE_WARN_ON_ONCE(1);
438 pr_info("ftrace failed to modify ");
439 print_ip_sym(ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800440 print_ip_ins(" actual: ", (unsigned char *)ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -0800441 printk(KERN_CONT "\n");
442 break;
443 case -EPERM:
444 FTRACE_WARN_ON_ONCE(1);
445 pr_info("ftrace faulted on writing ");
446 print_ip_sym(ip);
447 break;
448 default:
449 FTRACE_WARN_ON_ONCE(1);
450 pr_info("ftrace faulted on unknown error ");
451 print_ip_sym(ip);
452 }
453}
454
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200455
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530456static int
Steven Rostedt31e88902008-11-14 16:21:19 -0800457__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200458{
Ingo Molnare309b412008-05-12 21:20:51 +0200459 unsigned long ip, fl;
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100460 unsigned long ftrace_addr;
461
Shaohua Lif0001202009-01-09 11:29:42 +0800462 ftrace_addr = (unsigned long)FTRACE_ADDR;
Steven Rostedt5072c592008-05-12 21:20:43 +0200463
464 ip = rec->ip;
465
Steven Rostedt982c3502008-11-15 16:31:41 -0500466 /*
467 * If this record is not to be traced and
468 * it is not enabled then do nothing.
469 *
470 * If this record is not to be traced and
Wenji Huang57794a92009-02-06 17:33:27 +0800471 * it is enabled then disable it.
Steven Rostedt982c3502008-11-15 16:31:41 -0500472 *
473 */
474 if (rec->flags & FTRACE_FL_NOTRACE) {
475 if (rec->flags & FTRACE_FL_ENABLED)
476 rec->flags &= ~FTRACE_FL_ENABLED;
477 else
Steven Rostedt5072c592008-05-12 21:20:43 +0200478 return 0;
479
Steven Rostedt982c3502008-11-15 16:31:41 -0500480 } else if (ftrace_filtered && enable) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200481 /*
Steven Rostedt982c3502008-11-15 16:31:41 -0500482 * Filtering is on:
Steven Rostedt5072c592008-05-12 21:20:43 +0200483 */
Steven Rostedt982c3502008-11-15 16:31:41 -0500484
485 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED);
486
487 /* Record is filtered and enabled, do nothing */
488 if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
489 return 0;
490
Wenji Huang57794a92009-02-06 17:33:27 +0800491 /* Record is not filtered or enabled, do nothing */
Steven Rostedt982c3502008-11-15 16:31:41 -0500492 if (!fl)
493 return 0;
494
495 /* Record is not filtered but enabled, disable it */
496 if (fl == FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +0200497 rec->flags &= ~FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -0500498 else
499 /* Otherwise record is filtered but not enabled, enable it */
Steven Rostedt5072c592008-05-12 21:20:43 +0200500 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt5072c592008-05-12 21:20:43 +0200501 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -0500502 /* Disable or not filtered */
Steven Rostedt5072c592008-05-12 21:20:43 +0200503
504 if (enable) {
Steven Rostedt982c3502008-11-15 16:31:41 -0500505 /* if record is enabled, do nothing */
Steven Rostedt41c52c02008-05-22 11:46:33 -0400506 if (rec->flags & FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +0200507 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -0500508
Steven Rostedt41c52c02008-05-22 11:46:33 -0400509 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -0500510
Steven Rostedt5072c592008-05-12 21:20:43 +0200511 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -0500512
Wenji Huang57794a92009-02-06 17:33:27 +0800513 /* if record is not enabled, do nothing */
Steven Rostedt5072c592008-05-12 21:20:43 +0200514 if (!(rec->flags & FTRACE_FL_ENABLED))
515 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -0500516
Steven Rostedt5072c592008-05-12 21:20:43 +0200517 rec->flags &= ~FTRACE_FL_ENABLED;
518 }
519 }
520
Steven Rostedt982c3502008-11-15 16:31:41 -0500521 if (rec->flags & FTRACE_FL_ENABLED)
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100522 return ftrace_make_call(rec, ftrace_addr);
Steven Rostedt31e88902008-11-14 16:21:19 -0800523 else
Frederic Weisbeckere7d37372008-11-16 06:02:06 +0100524 return ftrace_make_nop(NULL, rec, ftrace_addr);
Steven Rostedt5072c592008-05-12 21:20:43 +0200525}
526
527static void ftrace_replace_code(int enable)
528{
Steven Rostedt265c8312009-02-13 12:43:56 -0500529 int failed;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200530 struct dyn_ftrace *rec;
531 struct ftrace_page *pg;
532
Steven Rostedt265c8312009-02-13 12:43:56 -0500533 do_for_each_ftrace_rec(pg, rec) {
534 /*
535 * Skip over free records and records that have
536 * failed.
537 */
538 if (rec->flags & FTRACE_FL_FREE ||
539 rec->flags & FTRACE_FL_FAILED)
540 continue;
Steven Rostedt5072c592008-05-12 21:20:43 +0200541
Steven Rostedt265c8312009-02-13 12:43:56 -0500542 /* ignore updates to this record's mcount site */
543 if (get_kprobe((void *)rec->ip)) {
544 freeze_record(rec);
545 continue;
546 } else {
547 unfreeze_record(rec);
Steven Rostedt5072c592008-05-12 21:20:43 +0200548 }
Steven Rostedt265c8312009-02-13 12:43:56 -0500549
550 failed = __ftrace_replace_code(rec, enable);
551 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
552 rec->flags |= FTRACE_FL_FAILED;
553 if ((system_state == SYSTEM_BOOTING) ||
554 !core_kernel_text(rec->ip)) {
555 ftrace_free_rec(rec);
556 } else
557 ftrace_bug(failed, rec->ip);
558 }
559 } while_for_each_ftrace_rec();
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200560}
561
Ingo Molnare309b412008-05-12 21:20:51 +0200562static int
Steven Rostedt31e88902008-11-14 16:21:19 -0800563ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200564{
565 unsigned long ip;
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400566 int ret;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200567
568 ip = rec->ip;
569
Shaohua Li25aac9d2009-01-09 11:29:40 +0800570 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400571 if (ret) {
Steven Rostedt31e88902008-11-14 16:21:19 -0800572 ftrace_bug(ret, ip);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200573 rec->flags |= FTRACE_FL_FAILED;
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530574 return 0;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200575 }
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530576 return 1;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200577}
578
Ingo Molnare309b412008-05-12 21:20:51 +0200579static int __ftrace_modify_code(void *data)
Steven Rostedt3d083392008-05-12 21:20:42 +0200580{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200581 int *command = data;
582
Steven Rostedta3583242008-11-11 15:01:42 -0500583 if (*command & FTRACE_ENABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200584 ftrace_replace_code(1);
Steven Rostedta3583242008-11-11 15:01:42 -0500585 else if (*command & FTRACE_DISABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200586 ftrace_replace_code(0);
587
588 if (*command & FTRACE_UPDATE_TRACE_FUNC)
589 ftrace_update_ftrace_func(ftrace_trace_function);
590
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500591 if (*command & FTRACE_START_FUNC_RET)
592 ftrace_enable_ftrace_graph_caller();
593 else if (*command & FTRACE_STOP_FUNC_RET)
594 ftrace_disable_ftrace_graph_caller();
595
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200596 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +0200597}
598
Ingo Molnare309b412008-05-12 21:20:51 +0200599static void ftrace_run_update_code(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200600{
Rusty Russell784e2d72008-07-28 12:16:31 -0500601 stop_machine(__ftrace_modify_code, &command, NULL);
Steven Rostedt3d083392008-05-12 21:20:42 +0200602}
603
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200604static ftrace_func_t saved_ftrace_func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500605static int ftrace_start_up;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500606
607static void ftrace_startup_enable(int command)
608{
609 if (saved_ftrace_func != ftrace_trace_function) {
610 saved_ftrace_func = ftrace_trace_function;
611 command |= FTRACE_UPDATE_TRACE_FUNC;
612 }
613
614 if (!command || !ftrace_enabled)
615 return;
616
617 ftrace_run_update_code(command);
618}
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200619
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500620static void ftrace_startup(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200621{
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200622 if (unlikely(ftrace_disabled))
623 return;
624
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400625 mutex_lock(&ftrace_start_lock);
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500626 ftrace_start_up++;
Steven Rostedt982c3502008-11-15 16:31:41 -0500627 command |= FTRACE_ENABLE_CALLS;
Steven Rostedt3d083392008-05-12 21:20:42 +0200628
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500629 ftrace_startup_enable(command);
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200630
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400631 mutex_unlock(&ftrace_start_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200632}
633
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500634static void ftrace_shutdown(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200635{
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200636 if (unlikely(ftrace_disabled))
637 return;
638
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400639 mutex_lock(&ftrace_start_lock);
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500640 ftrace_start_up--;
641 if (!ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200642 command |= FTRACE_DISABLE_CALLS;
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)
Steven Rostedt3d083392008-05-12 21:20:42 +0200650 goto out;
651
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200652 ftrace_run_update_code(command);
Steven Rostedt3d083392008-05-12 21:20:42 +0200653 out:
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400654 mutex_unlock(&ftrace_start_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200655}
656
Ingo Molnare309b412008-05-12 21:20:51 +0200657static void ftrace_startup_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200658{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200659 int command = FTRACE_ENABLE_MCOUNT;
660
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200661 if (unlikely(ftrace_disabled))
662 return;
663
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400664 mutex_lock(&ftrace_start_lock);
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200665 /* Force update next time */
666 saved_ftrace_func = NULL;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500667 /* ftrace_start_up is true if we want ftrace running */
668 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200669 command |= FTRACE_ENABLE_CALLS;
670
671 ftrace_run_update_code(command);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400672 mutex_unlock(&ftrace_start_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200673}
674
Ingo Molnare309b412008-05-12 21:20:51 +0200675static void ftrace_shutdown_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200676{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200677 int command = FTRACE_DISABLE_MCOUNT;
678
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200679 if (unlikely(ftrace_disabled))
680 return;
681
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400682 mutex_lock(&ftrace_start_lock);
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500683 /* ftrace_start_up is true if ftrace is running */
684 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200685 command |= FTRACE_DISABLE_CALLS;
686
687 ftrace_run_update_code(command);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400688 mutex_unlock(&ftrace_start_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200689}
690
Steven Rostedt3d083392008-05-12 21:20:42 +0200691static cycle_t ftrace_update_time;
692static unsigned long ftrace_update_cnt;
693unsigned long ftrace_update_tot_cnt;
694
Steven Rostedt31e88902008-11-14 16:21:19 -0800695static int ftrace_update_code(struct module *mod)
Steven Rostedt3d083392008-05-12 21:20:42 +0200696{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400697 struct dyn_ftrace *p, *t;
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530698 cycle_t start, stop;
Steven Rostedt3d083392008-05-12 21:20:42 +0200699
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200700 start = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200701 ftrace_update_cnt = 0;
702
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400703 list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530704
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400705 /* If something went wrong, bail without enabling anything */
706 if (unlikely(ftrace_disabled))
707 return -1;
Steven Rostedt3d083392008-05-12 21:20:42 +0200708
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400709 list_del_init(&p->list);
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530710
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400711 /* convert record (i.e, patch mcount-call with NOP) */
Steven Rostedt31e88902008-11-14 16:21:19 -0800712 if (ftrace_code_disable(mod, p)) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400713 p->flags |= FTRACE_FL_CONVERTED;
714 ftrace_update_cnt++;
715 } else
716 ftrace_free_rec(p);
Steven Rostedt3d083392008-05-12 21:20:42 +0200717 }
718
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200719 stop = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200720 ftrace_update_time = stop - start;
721 ftrace_update_tot_cnt += ftrace_update_cnt;
722
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200723 return 0;
724}
725
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400726static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200727{
728 struct ftrace_page *pg;
729 int cnt;
730 int i;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200731
732 /* allocate a few pages */
733 ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
734 if (!ftrace_pages_start)
735 return -1;
736
737 /*
738 * Allocate a few more pages.
739 *
740 * TODO: have some parser search vmlinux before
741 * final linking to find all calls to ftrace.
742 * Then we can:
743 * a) know how many pages to allocate.
744 * and/or
745 * b) set up the table then.
746 *
747 * The dynamic code is still necessary for
748 * modules.
749 */
750
751 pg = ftrace_pages = ftrace_pages_start;
752
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400753 cnt = num_to_init / ENTRIES_PER_PAGE;
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400754 pr_info("ftrace: allocating %ld entries in %d pages\n",
walimis5821e1b2008-11-15 15:19:06 +0800755 num_to_init, cnt + 1);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200756
757 for (i = 0; i < cnt; i++) {
758 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
759
760 /* If we fail, we'll try later anyway */
761 if (!pg->next)
762 break;
763
764 pg = pg->next;
765 }
766
767 return 0;
768}
769
Steven Rostedt5072c592008-05-12 21:20:43 +0200770enum {
771 FTRACE_ITER_FILTER = (1 << 0),
772 FTRACE_ITER_CONT = (1 << 1),
Steven Rostedt41c52c02008-05-22 11:46:33 -0400773 FTRACE_ITER_NOTRACE = (1 << 2),
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530774 FTRACE_ITER_FAILURES = (1 << 3),
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500775 FTRACE_ITER_PRINTALL = (1 << 4),
Steven Rostedt5072c592008-05-12 21:20:43 +0200776};
777
778#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
779
780struct ftrace_iterator {
Steven Rostedt5072c592008-05-12 21:20:43 +0200781 struct ftrace_page *pg;
Steven Rostedt431aa3f2009-01-06 12:43:01 -0500782 int idx;
Steven Rostedt5072c592008-05-12 21:20:43 +0200783 unsigned flags;
784 unsigned char buffer[FTRACE_BUFF_MAX+1];
785 unsigned buffer_idx;
786 unsigned filtered;
787};
788
Ingo Molnare309b412008-05-12 21:20:51 +0200789static void *
Steven Rostedt5072c592008-05-12 21:20:43 +0200790t_next(struct seq_file *m, void *v, loff_t *pos)
791{
792 struct ftrace_iterator *iter = m->private;
793 struct dyn_ftrace *rec = NULL;
794
795 (*pos)++;
796
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500797 if (iter->flags & FTRACE_ITER_PRINTALL)
798 return NULL;
799
Steven Rostedt52baf112009-02-14 01:15:39 -0500800 mutex_lock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200801 retry:
802 if (iter->idx >= iter->pg->index) {
803 if (iter->pg->next) {
804 iter->pg = iter->pg->next;
805 iter->idx = 0;
806 goto retry;
Liming Wang50cdaf02008-11-28 12:13:21 +0800807 } else {
808 iter->idx = -1;
Steven Rostedt5072c592008-05-12 21:20:43 +0200809 }
810 } else {
811 rec = &iter->pg->records[iter->idx++];
Steven Rostedta9fdda32008-08-14 22:47:17 -0400812 if ((rec->flags & FTRACE_FL_FREE) ||
813
814 (!(iter->flags & FTRACE_ITER_FAILURES) &&
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530815 (rec->flags & FTRACE_FL_FAILED)) ||
816
817 ((iter->flags & FTRACE_ITER_FAILURES) &&
Steven Rostedta9fdda32008-08-14 22:47:17 -0400818 !(rec->flags & FTRACE_FL_FAILED)) ||
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530819
Steven Rostedt0183fb12008-11-07 22:36:02 -0500820 ((iter->flags & FTRACE_ITER_FILTER) &&
821 !(rec->flags & FTRACE_FL_FILTER)) ||
822
Steven Rostedt41c52c02008-05-22 11:46:33 -0400823 ((iter->flags & FTRACE_ITER_NOTRACE) &&
824 !(rec->flags & FTRACE_FL_NOTRACE))) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200825 rec = NULL;
826 goto retry;
827 }
828 }
Steven Rostedt52baf112009-02-14 01:15:39 -0500829 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200830
Steven Rostedt5072c592008-05-12 21:20:43 +0200831 return rec;
832}
833
834static void *t_start(struct seq_file *m, loff_t *pos)
835{
836 struct ftrace_iterator *iter = m->private;
837 void *p = NULL;
Steven Rostedt5072c592008-05-12 21:20:43 +0200838
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500839 /*
840 * For set_ftrace_filter reading, if we have the filter
841 * off, we can short cut and just print out that all
842 * functions are enabled.
843 */
844 if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
845 if (*pos > 0)
846 return NULL;
847 iter->flags |= FTRACE_ITER_PRINTALL;
848 (*pos)++;
849 return iter;
850 }
851
Liming Wang50cdaf02008-11-28 12:13:21 +0800852 if (*pos > 0) {
853 if (iter->idx < 0)
854 return p;
855 (*pos)--;
856 iter->idx--;
857 }
walimis5821e1b2008-11-15 15:19:06 +0800858
Liming Wang50cdaf02008-11-28 12:13:21 +0800859 p = t_next(m, p, pos);
Steven Rostedt5072c592008-05-12 21:20:43 +0200860
861 return p;
862}
863
864static void t_stop(struct seq_file *m, void *p)
865{
866}
867
868static int t_show(struct seq_file *m, void *v)
869{
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500870 struct ftrace_iterator *iter = m->private;
Steven Rostedt5072c592008-05-12 21:20:43 +0200871 struct dyn_ftrace *rec = v;
872 char str[KSYM_SYMBOL_LEN];
873
Steven Rostedt0c75a3e2009-02-16 11:21:52 -0500874 if (iter->flags & FTRACE_ITER_PRINTALL) {
875 seq_printf(m, "#### all functions enabled ####\n");
876 return 0;
877 }
878
Steven Rostedt5072c592008-05-12 21:20:43 +0200879 if (!rec)
880 return 0;
881
882 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
883
Liming Wang50cdaf02008-11-28 12:13:21 +0800884 seq_printf(m, "%s\n", str);
Steven Rostedt5072c592008-05-12 21:20:43 +0200885
886 return 0;
887}
888
889static struct seq_operations show_ftrace_seq_ops = {
890 .start = t_start,
891 .next = t_next,
892 .stop = t_stop,
893 .show = t_show,
894};
895
Ingo Molnare309b412008-05-12 21:20:51 +0200896static int
Steven Rostedt5072c592008-05-12 21:20:43 +0200897ftrace_avail_open(struct inode *inode, struct file *file)
898{
899 struct ftrace_iterator *iter;
900 int ret;
901
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200902 if (unlikely(ftrace_disabled))
903 return -ENODEV;
904
Steven Rostedt5072c592008-05-12 21:20:43 +0200905 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
906 if (!iter)
907 return -ENOMEM;
908
909 iter->pg = ftrace_pages_start;
Steven Rostedt5072c592008-05-12 21:20:43 +0200910
911 ret = seq_open(file, &show_ftrace_seq_ops);
912 if (!ret) {
913 struct seq_file *m = file->private_data;
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200914
Steven Rostedt5072c592008-05-12 21:20:43 +0200915 m->private = iter;
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200916 } else {
Steven Rostedt5072c592008-05-12 21:20:43 +0200917 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200918 }
Steven Rostedt5072c592008-05-12 21:20:43 +0200919
920 return ret;
921}
922
923int ftrace_avail_release(struct inode *inode, struct file *file)
924{
925 struct seq_file *m = (struct seq_file *)file->private_data;
926 struct ftrace_iterator *iter = m->private;
927
928 seq_release(inode, file);
929 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200930
Steven Rostedt5072c592008-05-12 21:20:43 +0200931 return 0;
932}
933
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530934static int
935ftrace_failures_open(struct inode *inode, struct file *file)
936{
937 int ret;
938 struct seq_file *m;
939 struct ftrace_iterator *iter;
940
941 ret = ftrace_avail_open(inode, file);
942 if (!ret) {
943 m = (struct seq_file *)file->private_data;
944 iter = (struct ftrace_iterator *)m->private;
945 iter->flags = FTRACE_ITER_FAILURES;
946 }
947
948 return ret;
949}
950
951
Steven Rostedt41c52c02008-05-22 11:46:33 -0400952static void ftrace_filter_reset(int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +0200953{
954 struct ftrace_page *pg;
955 struct dyn_ftrace *rec;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400956 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +0200957
Steven Rostedt52baf112009-02-14 01:15:39 -0500958 mutex_lock(&ftrace_lock);
Steven Rostedt41c52c02008-05-22 11:46:33 -0400959 if (enable)
960 ftrace_filtered = 0;
Steven Rostedt265c8312009-02-13 12:43:56 -0500961 do_for_each_ftrace_rec(pg, rec) {
962 if (rec->flags & FTRACE_FL_FAILED)
963 continue;
964 rec->flags &= ~type;
965 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -0500966 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200967}
968
Ingo Molnare309b412008-05-12 21:20:51 +0200969static int
Steven Rostedt41c52c02008-05-22 11:46:33 -0400970ftrace_regex_open(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +0200971{
972 struct ftrace_iterator *iter;
973 int ret = 0;
974
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200975 if (unlikely(ftrace_disabled))
976 return -ENODEV;
977
Steven Rostedt5072c592008-05-12 21:20:43 +0200978 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
979 if (!iter)
980 return -ENOMEM;
981
Steven Rostedt41c52c02008-05-22 11:46:33 -0400982 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200983 if ((file->f_mode & FMODE_WRITE) &&
984 !(file->f_flags & O_APPEND))
Steven Rostedt41c52c02008-05-22 11:46:33 -0400985 ftrace_filter_reset(enable);
Steven Rostedt5072c592008-05-12 21:20:43 +0200986
987 if (file->f_mode & FMODE_READ) {
988 iter->pg = ftrace_pages_start;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400989 iter->flags = enable ? FTRACE_ITER_FILTER :
990 FTRACE_ITER_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +0200991
992 ret = seq_open(file, &show_ftrace_seq_ops);
993 if (!ret) {
994 struct seq_file *m = file->private_data;
995 m->private = iter;
996 } else
997 kfree(iter);
998 } else
999 file->private_data = iter;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001000 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001001
1002 return ret;
1003}
1004
Steven Rostedt41c52c02008-05-22 11:46:33 -04001005static int
1006ftrace_filter_open(struct inode *inode, struct file *file)
1007{
1008 return ftrace_regex_open(inode, file, 1);
1009}
1010
1011static int
1012ftrace_notrace_open(struct inode *inode, struct file *file)
1013{
1014 return ftrace_regex_open(inode, file, 0);
1015}
1016
Ingo Molnare309b412008-05-12 21:20:51 +02001017static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001018ftrace_regex_read(struct file *file, char __user *ubuf,
Steven Rostedt5072c592008-05-12 21:20:43 +02001019 size_t cnt, loff_t *ppos)
1020{
1021 if (file->f_mode & FMODE_READ)
1022 return seq_read(file, ubuf, cnt, ppos);
1023 else
1024 return -EPERM;
1025}
1026
Ingo Molnare309b412008-05-12 21:20:51 +02001027static loff_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001028ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
Steven Rostedt5072c592008-05-12 21:20:43 +02001029{
1030 loff_t ret;
1031
1032 if (file->f_mode & FMODE_READ)
1033 ret = seq_lseek(file, offset, origin);
1034 else
1035 file->f_pos = ret = 1;
1036
1037 return ret;
1038}
1039
1040enum {
1041 MATCH_FULL,
1042 MATCH_FRONT_ONLY,
1043 MATCH_MIDDLE_ONLY,
1044 MATCH_END_ONLY,
1045};
1046
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001047/*
1048 * (static function - no need for kernel doc)
1049 *
1050 * Pass in a buffer containing a glob and this function will
1051 * set search to point to the search part of the buffer and
1052 * return the type of search it is (see enum above).
1053 * This does modify buff.
1054 *
1055 * Returns enum type.
1056 * search returns the pointer to use for comparison.
1057 * not returns 1 if buff started with a '!'
1058 * 0 otherwise.
1059 */
1060static int
Steven Rostedt64e7c442009-02-13 17:08:48 -05001061ftrace_setup_glob(char *buff, int len, char **search, int *not)
Steven Rostedt5072c592008-05-12 21:20:43 +02001062{
Steven Rostedt5072c592008-05-12 21:20:43 +02001063 int type = MATCH_FULL;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001064 int i;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001065
1066 if (buff[0] == '!') {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001067 *not = 1;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001068 buff++;
1069 len--;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001070 } else
1071 *not = 0;
1072
1073 *search = buff;
Steven Rostedt5072c592008-05-12 21:20:43 +02001074
1075 for (i = 0; i < len; i++) {
1076 if (buff[i] == '*') {
1077 if (!i) {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001078 *search = buff + 1;
Steven Rostedt5072c592008-05-12 21:20:43 +02001079 type = MATCH_END_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001080 } else {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001081 if (type == MATCH_END_ONLY)
Steven Rostedt5072c592008-05-12 21:20:43 +02001082 type = MATCH_MIDDLE_ONLY;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001083 else
Steven Rostedt5072c592008-05-12 21:20:43 +02001084 type = MATCH_FRONT_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001085 buff[i] = 0;
1086 break;
1087 }
1088 }
1089 }
1090
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001091 return type;
1092}
1093
Steven Rostedt64e7c442009-02-13 17:08:48 -05001094static int ftrace_match(char *str, char *regex, int len, int type)
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001095{
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001096 int matched = 0;
1097 char *ptr;
1098
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001099 switch (type) {
1100 case MATCH_FULL:
1101 if (strcmp(str, regex) == 0)
1102 matched = 1;
1103 break;
1104 case MATCH_FRONT_ONLY:
1105 if (strncmp(str, regex, len) == 0)
1106 matched = 1;
1107 break;
1108 case MATCH_MIDDLE_ONLY:
1109 if (strstr(str, regex))
1110 matched = 1;
1111 break;
1112 case MATCH_END_ONLY:
1113 ptr = strstr(str, regex);
1114 if (ptr && (ptr[len] == 0))
1115 matched = 1;
1116 break;
1117 }
1118
1119 return matched;
1120}
1121
Steven Rostedt64e7c442009-02-13 17:08:48 -05001122static int
1123ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
1124{
1125 char str[KSYM_SYMBOL_LEN];
1126
1127 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1128 return ftrace_match(str, regex, len, type);
1129}
1130
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001131static void ftrace_match_records(char *buff, int len, int enable)
1132{
1133 char *search;
1134 struct ftrace_page *pg;
1135 struct dyn_ftrace *rec;
1136 int type;
1137 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1138 unsigned search_len;
1139 int not;
1140
1141 type = ftrace_setup_glob(buff, len, &search, &not);
1142
1143 search_len = strlen(search);
1144
Steven Rostedt52baf112009-02-14 01:15:39 -05001145 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05001146 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedt5072c592008-05-12 21:20:43 +02001147
Steven Rostedt265c8312009-02-13 12:43:56 -05001148 if (rec->flags & FTRACE_FL_FAILED)
1149 continue;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001150
1151 if (ftrace_match_record(rec, search, search_len, type)) {
Steven Rostedt265c8312009-02-13 12:43:56 -05001152 if (not)
1153 rec->flags &= ~flag;
1154 else
1155 rec->flags |= flag;
1156 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001157 /*
1158 * Only enable filtering if we have a function that
1159 * is filtered on.
1160 */
1161 if (enable && (rec->flags & FTRACE_FL_FILTER))
1162 ftrace_filtered = 1;
Steven Rostedt265c8312009-02-13 12:43:56 -05001163 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001164 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001165}
1166
Steven Rostedt64e7c442009-02-13 17:08:48 -05001167static int
1168ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
1169 char *regex, int len, int type)
1170{
1171 char str[KSYM_SYMBOL_LEN];
1172 char *modname;
1173
1174 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1175
1176 if (!modname || strcmp(modname, mod))
1177 return 0;
1178
1179 /* blank search means to match all funcs in the mod */
1180 if (len)
1181 return ftrace_match(str, regex, len, type);
1182 else
1183 return 1;
1184}
1185
1186static void ftrace_match_module_records(char *buff, char *mod, int enable)
1187{
1188 char *search = buff;
1189 struct ftrace_page *pg;
1190 struct dyn_ftrace *rec;
1191 int type = MATCH_FULL;
1192 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1193 unsigned search_len = 0;
1194 int not = 0;
1195
1196 /* blank or '*' mean the same */
1197 if (strcmp(buff, "*") == 0)
1198 buff[0] = 0;
1199
1200 /* handle the case of 'dont filter this module' */
1201 if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
1202 buff[0] = 0;
1203 not = 1;
1204 }
1205
1206 if (strlen(buff)) {
1207 type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
1208 search_len = strlen(search);
1209 }
1210
Steven Rostedt52baf112009-02-14 01:15:39 -05001211 mutex_lock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001212 do_for_each_ftrace_rec(pg, rec) {
1213
1214 if (rec->flags & FTRACE_FL_FAILED)
1215 continue;
1216
1217 if (ftrace_match_module_record(rec, mod,
1218 search, search_len, type)) {
1219 if (not)
1220 rec->flags &= ~flag;
1221 else
1222 rec->flags |= flag;
1223 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001224 if (enable && (rec->flags & FTRACE_FL_FILTER))
1225 ftrace_filtered = 1;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001226
1227 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001228 mutex_unlock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001229}
1230
Steven Rostedtf6180772009-02-14 00:40:25 -05001231/*
1232 * We register the module command as a template to show others how
1233 * to register the a command as well.
1234 */
1235
1236static int
1237ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1238{
1239 char *mod;
1240
1241 /*
1242 * cmd == 'mod' because we only registered this func
1243 * for the 'mod' ftrace_func_command.
1244 * But if you register one func with multiple commands,
1245 * you can tell which command was used by the cmd
1246 * parameter.
1247 */
1248
1249 /* we must have a module name */
1250 if (!param)
1251 return -EINVAL;
1252
1253 mod = strsep(&param, ":");
1254 if (!strlen(mod))
1255 return -EINVAL;
1256
1257 ftrace_match_module_records(func, mod, enable);
1258 return 0;
1259}
1260
1261static struct ftrace_func_command ftrace_mod_cmd = {
1262 .name = "mod",
1263 .func = ftrace_mod_callback,
1264};
1265
1266static int __init ftrace_mod_cmd_init(void)
1267{
1268 return register_ftrace_command(&ftrace_mod_cmd);
1269}
1270device_initcall(ftrace_mod_cmd_init);
1271
1272static LIST_HEAD(ftrace_commands);
1273static DEFINE_MUTEX(ftrace_cmd_mutex);
1274
1275int register_ftrace_command(struct ftrace_func_command *cmd)
1276{
1277 struct ftrace_func_command *p;
1278 int ret = 0;
1279
1280 mutex_lock(&ftrace_cmd_mutex);
1281 list_for_each_entry(p, &ftrace_commands, list) {
1282 if (strcmp(cmd->name, p->name) == 0) {
1283 ret = -EBUSY;
1284 goto out_unlock;
1285 }
1286 }
1287 list_add(&cmd->list, &ftrace_commands);
1288 out_unlock:
1289 mutex_unlock(&ftrace_cmd_mutex);
1290
1291 return ret;
1292}
1293
1294int unregister_ftrace_command(struct ftrace_func_command *cmd)
1295{
1296 struct ftrace_func_command *p, *n;
1297 int ret = -ENODEV;
1298
1299 mutex_lock(&ftrace_cmd_mutex);
1300 list_for_each_entry_safe(p, n, &ftrace_commands, list) {
1301 if (strcmp(cmd->name, p->name) == 0) {
1302 ret = 0;
1303 list_del_init(&p->list);
1304 goto out_unlock;
1305 }
1306 }
1307 out_unlock:
1308 mutex_unlock(&ftrace_cmd_mutex);
1309
1310 return ret;
1311}
1312
Steven Rostedt64e7c442009-02-13 17:08:48 -05001313static int ftrace_process_regex(char *buff, int len, int enable)
1314{
Steven Rostedtf6180772009-02-14 00:40:25 -05001315 struct ftrace_func_command *p;
1316 char *func, *command, *next = buff;
1317 int ret = -EINVAL;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001318
1319 func = strsep(&next, ":");
1320
1321 if (!next) {
1322 ftrace_match_records(func, len, enable);
1323 return 0;
1324 }
1325
Steven Rostedtf6180772009-02-14 00:40:25 -05001326 /* command found */
Steven Rostedt64e7c442009-02-13 17:08:48 -05001327
1328 command = strsep(&next, ":");
1329
Steven Rostedtf6180772009-02-14 00:40:25 -05001330 mutex_lock(&ftrace_cmd_mutex);
1331 list_for_each_entry(p, &ftrace_commands, list) {
1332 if (strcmp(p->name, command) == 0) {
1333 ret = p->func(func, command, next, enable);
1334 goto out_unlock;
1335 }
Steven Rostedt64e7c442009-02-13 17:08:48 -05001336 }
Steven Rostedtf6180772009-02-14 00:40:25 -05001337 out_unlock:
1338 mutex_unlock(&ftrace_cmd_mutex);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001339
Steven Rostedtf6180772009-02-14 00:40:25 -05001340 return ret;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001341}
1342
Ingo Molnare309b412008-05-12 21:20:51 +02001343static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001344ftrace_regex_write(struct file *file, const char __user *ubuf,
1345 size_t cnt, loff_t *ppos, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001346{
1347 struct ftrace_iterator *iter;
1348 char ch;
1349 size_t read = 0;
1350 ssize_t ret;
1351
1352 if (!cnt || cnt < 0)
1353 return 0;
1354
Steven Rostedt41c52c02008-05-22 11:46:33 -04001355 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001356
1357 if (file->f_mode & FMODE_READ) {
1358 struct seq_file *m = file->private_data;
1359 iter = m->private;
1360 } else
1361 iter = file->private_data;
1362
1363 if (!*ppos) {
1364 iter->flags &= ~FTRACE_ITER_CONT;
1365 iter->buffer_idx = 0;
1366 }
1367
1368 ret = get_user(ch, ubuf++);
1369 if (ret)
1370 goto out;
1371 read++;
1372 cnt--;
1373
1374 if (!(iter->flags & ~FTRACE_ITER_CONT)) {
1375 /* skip white space */
1376 while (cnt && isspace(ch)) {
1377 ret = get_user(ch, ubuf++);
1378 if (ret)
1379 goto out;
1380 read++;
1381 cnt--;
1382 }
1383
Steven Rostedt5072c592008-05-12 21:20:43 +02001384 if (isspace(ch)) {
1385 file->f_pos += read;
1386 ret = read;
1387 goto out;
1388 }
1389
1390 iter->buffer_idx = 0;
1391 }
1392
1393 while (cnt && !isspace(ch)) {
1394 if (iter->buffer_idx < FTRACE_BUFF_MAX)
1395 iter->buffer[iter->buffer_idx++] = ch;
1396 else {
1397 ret = -EINVAL;
1398 goto out;
1399 }
1400 ret = get_user(ch, ubuf++);
1401 if (ret)
1402 goto out;
1403 read++;
1404 cnt--;
1405 }
1406
1407 if (isspace(ch)) {
1408 iter->filtered++;
1409 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001410 ret = ftrace_process_regex(iter->buffer,
1411 iter->buffer_idx, enable);
1412 if (ret)
1413 goto out;
Steven Rostedt5072c592008-05-12 21:20:43 +02001414 iter->buffer_idx = 0;
1415 } else
1416 iter->flags |= FTRACE_ITER_CONT;
1417
1418
1419 file->f_pos += read;
1420
1421 ret = read;
1422 out:
Steven Rostedt41c52c02008-05-22 11:46:33 -04001423 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001424
1425 return ret;
1426}
1427
Steven Rostedt41c52c02008-05-22 11:46:33 -04001428static ssize_t
1429ftrace_filter_write(struct file *file, const char __user *ubuf,
1430 size_t cnt, loff_t *ppos)
1431{
1432 return ftrace_regex_write(file, ubuf, cnt, ppos, 1);
1433}
1434
1435static ssize_t
1436ftrace_notrace_write(struct file *file, const char __user *ubuf,
1437 size_t cnt, loff_t *ppos)
1438{
1439 return ftrace_regex_write(file, ubuf, cnt, ppos, 0);
1440}
1441
1442static void
1443ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
1444{
1445 if (unlikely(ftrace_disabled))
1446 return;
1447
1448 mutex_lock(&ftrace_regex_lock);
1449 if (reset)
1450 ftrace_filter_reset(enable);
1451 if (buf)
Steven Rostedt7f24b312009-02-13 14:37:33 -05001452 ftrace_match_records(buf, len, enable);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001453 mutex_unlock(&ftrace_regex_lock);
1454}
1455
Steven Rostedt77a2b372008-05-12 21:20:45 +02001456/**
1457 * ftrace_set_filter - set a function to filter on in ftrace
1458 * @buf - the string that holds the function filter text.
1459 * @len - the length of the string.
1460 * @reset - non zero to reset all filters before applying this filter.
1461 *
1462 * Filters denote which functions should be enabled when tracing is enabled.
1463 * If @buf is NULL and reset is set, all functions will be enabled for tracing.
1464 */
Ingo Molnare309b412008-05-12 21:20:51 +02001465void ftrace_set_filter(unsigned char *buf, int len, int reset)
Steven Rostedt77a2b372008-05-12 21:20:45 +02001466{
Steven Rostedt41c52c02008-05-22 11:46:33 -04001467 ftrace_set_regex(buf, len, reset, 1);
1468}
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001469
Steven Rostedt41c52c02008-05-22 11:46:33 -04001470/**
1471 * ftrace_set_notrace - set a function to not trace in ftrace
1472 * @buf - the string that holds the function notrace text.
1473 * @len - the length of the string.
1474 * @reset - non zero to reset all filters before applying this filter.
1475 *
1476 * Notrace Filters denote which functions should not be enabled when tracing
1477 * is enabled. If @buf is NULL and reset is set, all functions will be enabled
1478 * for tracing.
1479 */
1480void ftrace_set_notrace(unsigned char *buf, int len, int reset)
1481{
1482 ftrace_set_regex(buf, len, reset, 0);
Steven Rostedt77a2b372008-05-12 21:20:45 +02001483}
1484
Ingo Molnare309b412008-05-12 21:20:51 +02001485static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04001486ftrace_regex_release(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001487{
1488 struct seq_file *m = (struct seq_file *)file->private_data;
1489 struct ftrace_iterator *iter;
1490
Steven Rostedt41c52c02008-05-22 11:46:33 -04001491 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001492 if (file->f_mode & FMODE_READ) {
1493 iter = m->private;
1494
1495 seq_release(inode, file);
1496 } else
1497 iter = file->private_data;
1498
1499 if (iter->buffer_idx) {
1500 iter->filtered++;
1501 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt7f24b312009-02-13 14:37:33 -05001502 ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001503 }
1504
1505 mutex_lock(&ftrace_sysctl_lock);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -04001506 mutex_lock(&ftrace_start_lock);
Steven Rostedtee02a2e2008-11-15 16:31:41 -05001507 if (ftrace_start_up && ftrace_enabled)
Steven Rostedt5072c592008-05-12 21:20:43 +02001508 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -04001509 mutex_unlock(&ftrace_start_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001510 mutex_unlock(&ftrace_sysctl_lock);
1511
1512 kfree(iter);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001513 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001514 return 0;
1515}
1516
Steven Rostedt41c52c02008-05-22 11:46:33 -04001517static int
1518ftrace_filter_release(struct inode *inode, struct file *file)
1519{
1520 return ftrace_regex_release(inode, file, 1);
1521}
1522
1523static int
1524ftrace_notrace_release(struct inode *inode, struct file *file)
1525{
1526 return ftrace_regex_release(inode, file, 0);
1527}
1528
Steven Rostedt5072c592008-05-12 21:20:43 +02001529static struct file_operations ftrace_avail_fops = {
1530 .open = ftrace_avail_open,
1531 .read = seq_read,
1532 .llseek = seq_lseek,
1533 .release = ftrace_avail_release,
1534};
1535
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301536static struct file_operations ftrace_failures_fops = {
1537 .open = ftrace_failures_open,
1538 .read = seq_read,
1539 .llseek = seq_lseek,
1540 .release = ftrace_avail_release,
1541};
1542
Steven Rostedt5072c592008-05-12 21:20:43 +02001543static struct file_operations ftrace_filter_fops = {
1544 .open = ftrace_filter_open,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001545 .read = ftrace_regex_read,
Steven Rostedt5072c592008-05-12 21:20:43 +02001546 .write = ftrace_filter_write,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001547 .llseek = ftrace_regex_lseek,
Steven Rostedt5072c592008-05-12 21:20:43 +02001548 .release = ftrace_filter_release,
1549};
1550
Steven Rostedt41c52c02008-05-22 11:46:33 -04001551static struct file_operations ftrace_notrace_fops = {
1552 .open = ftrace_notrace_open,
1553 .read = ftrace_regex_read,
1554 .write = ftrace_notrace_write,
1555 .llseek = ftrace_regex_lseek,
1556 .release = ftrace_notrace_release,
1557};
1558
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001559#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1560
1561static DEFINE_MUTEX(graph_lock);
1562
1563int ftrace_graph_count;
1564unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
1565
1566static void *
1567g_next(struct seq_file *m, void *v, loff_t *pos)
1568{
1569 unsigned long *array = m->private;
1570 int index = *pos;
1571
1572 (*pos)++;
1573
1574 if (index >= ftrace_graph_count)
1575 return NULL;
1576
1577 return &array[index];
1578}
1579
1580static void *g_start(struct seq_file *m, loff_t *pos)
1581{
1582 void *p = NULL;
1583
1584 mutex_lock(&graph_lock);
1585
1586 p = g_next(m, p, pos);
1587
1588 return p;
1589}
1590
1591static void g_stop(struct seq_file *m, void *p)
1592{
1593 mutex_unlock(&graph_lock);
1594}
1595
1596static int g_show(struct seq_file *m, void *v)
1597{
1598 unsigned long *ptr = v;
1599 char str[KSYM_SYMBOL_LEN];
1600
1601 if (!ptr)
1602 return 0;
1603
1604 kallsyms_lookup(*ptr, NULL, NULL, NULL, str);
1605
1606 seq_printf(m, "%s\n", str);
1607
1608 return 0;
1609}
1610
1611static struct seq_operations ftrace_graph_seq_ops = {
1612 .start = g_start,
1613 .next = g_next,
1614 .stop = g_stop,
1615 .show = g_show,
1616};
1617
1618static int
1619ftrace_graph_open(struct inode *inode, struct file *file)
1620{
1621 int ret = 0;
1622
1623 if (unlikely(ftrace_disabled))
1624 return -ENODEV;
1625
1626 mutex_lock(&graph_lock);
1627 if ((file->f_mode & FMODE_WRITE) &&
1628 !(file->f_flags & O_APPEND)) {
1629 ftrace_graph_count = 0;
1630 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
1631 }
1632
1633 if (file->f_mode & FMODE_READ) {
1634 ret = seq_open(file, &ftrace_graph_seq_ops);
1635 if (!ret) {
1636 struct seq_file *m = file->private_data;
1637 m->private = ftrace_graph_funcs;
1638 }
1639 } else
1640 file->private_data = ftrace_graph_funcs;
1641 mutex_unlock(&graph_lock);
1642
1643 return ret;
1644}
1645
1646static ssize_t
1647ftrace_graph_read(struct file *file, char __user *ubuf,
1648 size_t cnt, loff_t *ppos)
1649{
1650 if (file->f_mode & FMODE_READ)
1651 return seq_read(file, ubuf, cnt, ppos);
1652 else
1653 return -EPERM;
1654}
1655
1656static int
1657ftrace_set_func(unsigned long *array, int idx, char *buffer)
1658{
1659 char str[KSYM_SYMBOL_LEN];
1660 struct dyn_ftrace *rec;
1661 struct ftrace_page *pg;
1662 int found = 0;
Steven Rostedt265c8312009-02-13 12:43:56 -05001663 int j;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001664
1665 if (ftrace_disabled)
1666 return -ENODEV;
1667
Steven Rostedt52baf112009-02-14 01:15:39 -05001668 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05001669 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001670
Steven Rostedt265c8312009-02-13 12:43:56 -05001671 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
1672 continue;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001673
Steven Rostedt265c8312009-02-13 12:43:56 -05001674 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1675 if (strcmp(str, buffer) == 0) {
1676 /* Return 1 if we add it to the array */
1677 found = 1;
1678 for (j = 0; j < idx; j++)
1679 if (array[j] == rec->ip) {
1680 found = 0;
1681 break;
1682 }
1683 if (found)
1684 array[idx] = rec->ip;
1685 goto out;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001686 }
Steven Rostedt265c8312009-02-13 12:43:56 -05001687 } while_for_each_ftrace_rec();
1688 out:
Steven Rostedt52baf112009-02-14 01:15:39 -05001689 mutex_unlock(&ftrace_lock);
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001690
1691 return found ? 0 : -EINVAL;
1692}
1693
1694static ssize_t
1695ftrace_graph_write(struct file *file, const char __user *ubuf,
1696 size_t cnt, loff_t *ppos)
1697{
1698 unsigned char buffer[FTRACE_BUFF_MAX+1];
1699 unsigned long *array;
1700 size_t read = 0;
1701 ssize_t ret;
1702 int index = 0;
1703 char ch;
1704
1705 if (!cnt || cnt < 0)
1706 return 0;
1707
1708 mutex_lock(&graph_lock);
1709
1710 if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) {
1711 ret = -EBUSY;
1712 goto out;
1713 }
1714
1715 if (file->f_mode & FMODE_READ) {
1716 struct seq_file *m = file->private_data;
1717 array = m->private;
1718 } else
1719 array = file->private_data;
1720
1721 ret = get_user(ch, ubuf++);
1722 if (ret)
1723 goto out;
1724 read++;
1725 cnt--;
1726
1727 /* skip white space */
1728 while (cnt && isspace(ch)) {
1729 ret = get_user(ch, ubuf++);
1730 if (ret)
1731 goto out;
1732 read++;
1733 cnt--;
1734 }
1735
1736 if (isspace(ch)) {
1737 *ppos += read;
1738 ret = read;
1739 goto out;
1740 }
1741
1742 while (cnt && !isspace(ch)) {
1743 if (index < FTRACE_BUFF_MAX)
1744 buffer[index++] = ch;
1745 else {
1746 ret = -EINVAL;
1747 goto out;
1748 }
1749 ret = get_user(ch, ubuf++);
1750 if (ret)
1751 goto out;
1752 read++;
1753 cnt--;
1754 }
1755 buffer[index] = 0;
1756
1757 /* we allow only one at a time */
1758 ret = ftrace_set_func(array, ftrace_graph_count, buffer);
1759 if (ret)
1760 goto out;
1761
1762 ftrace_graph_count++;
1763
1764 file->f_pos += read;
1765
1766 ret = read;
1767 out:
1768 mutex_unlock(&graph_lock);
1769
1770 return ret;
1771}
1772
1773static const struct file_operations ftrace_graph_fops = {
1774 .open = ftrace_graph_open,
1775 .read = ftrace_graph_read,
1776 .write = ftrace_graph_write,
1777};
1778#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1779
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001780static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
Steven Rostedt5072c592008-05-12 21:20:43 +02001781{
Steven Rostedt5072c592008-05-12 21:20:43 +02001782 struct dentry *entry;
1783
Steven Rostedt5072c592008-05-12 21:20:43 +02001784 entry = debugfs_create_file("available_filter_functions", 0444,
1785 d_tracer, NULL, &ftrace_avail_fops);
1786 if (!entry)
1787 pr_warning("Could not create debugfs "
1788 "'available_filter_functions' entry\n");
1789
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301790 entry = debugfs_create_file("failures", 0444,
1791 d_tracer, NULL, &ftrace_failures_fops);
1792 if (!entry)
1793 pr_warning("Could not create debugfs 'failures' entry\n");
1794
Steven Rostedt5072c592008-05-12 21:20:43 +02001795 entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer,
1796 NULL, &ftrace_filter_fops);
1797 if (!entry)
1798 pr_warning("Could not create debugfs "
1799 "'set_ftrace_filter' entry\n");
Steven Rostedt41c52c02008-05-22 11:46:33 -04001800
1801 entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer,
1802 NULL, &ftrace_notrace_fops);
1803 if (!entry)
1804 pr_warning("Could not create debugfs "
1805 "'set_ftrace_notrace' entry\n");
Steven Rostedtad90c0e2008-05-27 20:48:37 -04001806
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05001807#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1808 entry = debugfs_create_file("set_graph_function", 0444, d_tracer,
1809 NULL,
1810 &ftrace_graph_fops);
1811 if (!entry)
1812 pr_warning("Could not create debugfs "
1813 "'set_graph_function' entry\n");
1814#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
1815
Steven Rostedt5072c592008-05-12 21:20:43 +02001816 return 0;
1817}
1818
Steven Rostedt31e88902008-11-14 16:21:19 -08001819static int ftrace_convert_nops(struct module *mod,
1820 unsigned long *start,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001821 unsigned long *end)
1822{
1823 unsigned long *p;
1824 unsigned long addr;
1825 unsigned long flags;
1826
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001827 mutex_lock(&ftrace_start_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001828 p = start;
1829 while (p < end) {
1830 addr = ftrace_call_adjust(*p++);
Steven Rostedt20e52272008-11-14 16:21:19 -08001831 /*
1832 * Some architecture linkers will pad between
1833 * the different mcount_loc sections of different
1834 * object files to satisfy alignments.
1835 * Skip any NULL pointers.
1836 */
1837 if (!addr)
1838 continue;
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001839 ftrace_record_ip(addr);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001840 }
1841
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001842 /* disable interrupts to prevent kstop machine */
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001843 local_irq_save(flags);
Steven Rostedt31e88902008-11-14 16:21:19 -08001844 ftrace_update_code(mod);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001845 local_irq_restore(flags);
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001846 mutex_unlock(&ftrace_start_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001847
1848 return 0;
1849}
1850
Steven Rostedt31e88902008-11-14 16:21:19 -08001851void ftrace_init_module(struct module *mod,
1852 unsigned long *start, unsigned long *end)
Steven Rostedt90d595f2008-08-14 15:45:09 -04001853{
Steven Rostedt00fd61a2008-08-15 21:40:04 -04001854 if (ftrace_disabled || start == end)
Steven Rostedtfed19392008-08-14 22:47:19 -04001855 return;
Steven Rostedt31e88902008-11-14 16:21:19 -08001856 ftrace_convert_nops(mod, start, end);
Steven Rostedt90d595f2008-08-14 15:45:09 -04001857}
1858
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001859extern unsigned long __start_mcount_loc[];
1860extern unsigned long __stop_mcount_loc[];
1861
1862void __init ftrace_init(void)
1863{
1864 unsigned long count, addr, flags;
1865 int ret;
1866
1867 /* Keep the ftrace pointer to the stub */
1868 addr = (unsigned long)ftrace_stub;
1869
1870 local_irq_save(flags);
1871 ftrace_dyn_arch_init(&addr);
1872 local_irq_restore(flags);
1873
1874 /* ftrace_dyn_arch_init places the return code in addr */
1875 if (addr)
1876 goto failed;
1877
1878 count = __stop_mcount_loc - __start_mcount_loc;
1879
1880 ret = ftrace_dyn_table_alloc(count);
1881 if (ret)
1882 goto failed;
1883
1884 last_ftrace_enabled = ftrace_enabled = 1;
1885
Steven Rostedt31e88902008-11-14 16:21:19 -08001886 ret = ftrace_convert_nops(NULL,
1887 __start_mcount_loc,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001888 __stop_mcount_loc);
1889
1890 return;
1891 failed:
1892 ftrace_disabled = 1;
1893}
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001894
Steven Rostedt3d083392008-05-12 21:20:42 +02001895#else
Frederic Weisbecker0b6e4d52008-10-28 20:17:38 +01001896
1897static int __init ftrace_nodyn_init(void)
1898{
1899 ftrace_enabled = 1;
1900 return 0;
1901}
1902device_initcall(ftrace_nodyn_init);
1903
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001904static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
1905static inline void ftrace_startup_enable(int command) { }
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05001906/* Keep as macros so we do not need to define the commands */
1907# define ftrace_startup(command) do { } while (0)
1908# define ftrace_shutdown(command) do { } while (0)
Ingo Molnarc7aafc52008-05-12 21:20:45 +02001909# define ftrace_startup_sysctl() do { } while (0)
1910# define ftrace_shutdown_sysctl() do { } while (0)
Steven Rostedt3d083392008-05-12 21:20:42 +02001911#endif /* CONFIG_DYNAMIC_FTRACE */
1912
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001913static ssize_t
1914ftrace_pid_read(struct file *file, char __user *ubuf,
1915 size_t cnt, loff_t *ppos)
1916{
1917 char buf[64];
1918 int r;
1919
Steven Rostedte32d8952008-12-04 00:26:41 -05001920 if (ftrace_pid_trace == ftrace_swapper_pid)
1921 r = sprintf(buf, "swapper tasks\n");
1922 else if (ftrace_pid_trace)
Steven Rostedt978f3a42008-12-04 00:26:40 -05001923 r = sprintf(buf, "%u\n", pid_nr(ftrace_pid_trace));
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001924 else
1925 r = sprintf(buf, "no pid\n");
1926
1927 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1928}
1929
Steven Rostedte32d8952008-12-04 00:26:41 -05001930static void clear_ftrace_swapper(void)
1931{
1932 struct task_struct *p;
1933 int cpu;
1934
1935 get_online_cpus();
1936 for_each_online_cpu(cpu) {
1937 p = idle_task(cpu);
1938 clear_tsk_trace_trace(p);
1939 }
1940 put_online_cpus();
1941}
1942
1943static void set_ftrace_swapper(void)
1944{
1945 struct task_struct *p;
1946 int cpu;
1947
1948 get_online_cpus();
1949 for_each_online_cpu(cpu) {
1950 p = idle_task(cpu);
1951 set_tsk_trace_trace(p);
1952 }
1953 put_online_cpus();
1954}
1955
1956static void clear_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05001957{
1958 struct task_struct *p;
1959
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01001960 rcu_read_lock();
Steven Rostedte32d8952008-12-04 00:26:41 -05001961 do_each_pid_task(pid, PIDTYPE_PID, p) {
Steven Rostedt978f3a42008-12-04 00:26:40 -05001962 clear_tsk_trace_trace(p);
Steven Rostedte32d8952008-12-04 00:26:41 -05001963 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01001964 rcu_read_unlock();
1965
Steven Rostedte32d8952008-12-04 00:26:41 -05001966 put_pid(pid);
Steven Rostedt978f3a42008-12-04 00:26:40 -05001967}
1968
Steven Rostedte32d8952008-12-04 00:26:41 -05001969static void set_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05001970{
1971 struct task_struct *p;
1972
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01001973 rcu_read_lock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05001974 do_each_pid_task(pid, PIDTYPE_PID, p) {
1975 set_tsk_trace_trace(p);
1976 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01001977 rcu_read_unlock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05001978}
1979
Steven Rostedte32d8952008-12-04 00:26:41 -05001980static void clear_ftrace_pid_task(struct pid **pid)
1981{
1982 if (*pid == ftrace_swapper_pid)
1983 clear_ftrace_swapper();
1984 else
1985 clear_ftrace_pid(*pid);
1986
1987 *pid = NULL;
1988}
1989
1990static void set_ftrace_pid_task(struct pid *pid)
1991{
1992 if (pid == ftrace_swapper_pid)
1993 set_ftrace_swapper();
1994 else
1995 set_ftrace_pid(pid);
1996}
1997
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001998static ssize_t
1999ftrace_pid_write(struct file *filp, const char __user *ubuf,
2000 size_t cnt, loff_t *ppos)
2001{
Steven Rostedt978f3a42008-12-04 00:26:40 -05002002 struct pid *pid;
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002003 char buf[64];
2004 long val;
2005 int ret;
2006
2007 if (cnt >= sizeof(buf))
2008 return -EINVAL;
2009
2010 if (copy_from_user(&buf, ubuf, cnt))
2011 return -EFAULT;
2012
2013 buf[cnt] = 0;
2014
2015 ret = strict_strtol(buf, 10, &val);
2016 if (ret < 0)
2017 return ret;
2018
2019 mutex_lock(&ftrace_start_lock);
Steven Rostedt978f3a42008-12-04 00:26:40 -05002020 if (val < 0) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002021 /* disable pid tracing */
Steven Rostedt978f3a42008-12-04 00:26:40 -05002022 if (!ftrace_pid_trace)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002023 goto out;
Steven Rostedt978f3a42008-12-04 00:26:40 -05002024
2025 clear_ftrace_pid_task(&ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002026
2027 } else {
Steven Rostedte32d8952008-12-04 00:26:41 -05002028 /* swapper task is special */
2029 if (!val) {
2030 pid = ftrace_swapper_pid;
2031 if (pid == ftrace_pid_trace)
2032 goto out;
2033 } else {
2034 pid = find_get_pid(val);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002035
Steven Rostedte32d8952008-12-04 00:26:41 -05002036 if (pid == ftrace_pid_trace) {
2037 put_pid(pid);
2038 goto out;
2039 }
Steven Rostedt978f3a42008-12-04 00:26:40 -05002040 }
2041
2042 if (ftrace_pid_trace)
2043 clear_ftrace_pid_task(&ftrace_pid_trace);
2044
2045 if (!pid)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002046 goto out;
2047
Steven Rostedt978f3a42008-12-04 00:26:40 -05002048 ftrace_pid_trace = pid;
Steven Rostedt0ef8cde2008-12-03 15:36:58 -05002049
Steven Rostedt978f3a42008-12-04 00:26:40 -05002050 set_ftrace_pid_task(ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002051 }
2052
2053 /* update the function call */
2054 ftrace_update_pid_func();
2055 ftrace_startup_enable(0);
2056
2057 out:
2058 mutex_unlock(&ftrace_start_lock);
2059
2060 return cnt;
2061}
2062
2063static struct file_operations ftrace_pid_fops = {
2064 .read = ftrace_pid_read,
2065 .write = ftrace_pid_write,
2066};
2067
2068static __init int ftrace_init_debugfs(void)
2069{
2070 struct dentry *d_tracer;
2071 struct dentry *entry;
2072
2073 d_tracer = tracing_init_dentry();
2074 if (!d_tracer)
2075 return 0;
2076
2077 ftrace_init_dyn_debugfs(d_tracer);
2078
2079 entry = debugfs_create_file("set_ftrace_pid", 0644, d_tracer,
2080 NULL, &ftrace_pid_fops);
2081 if (!entry)
2082 pr_warning("Could not create debugfs "
2083 "'set_ftrace_pid' entry\n");
2084 return 0;
2085}
2086
2087fs_initcall(ftrace_init_debugfs);
2088
Steven Rostedt3d083392008-05-12 21:20:42 +02002089/**
Steven Rostedt81adbdc2008-10-23 09:33:02 -04002090 * ftrace_kill - kill ftrace
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002091 *
2092 * This function should be used by panic code. It stops ftrace
2093 * but in a not so nice way. If you need to simply kill ftrace
2094 * from a non-atomic section, use ftrace_kill.
2095 */
Steven Rostedt81adbdc2008-10-23 09:33:02 -04002096void ftrace_kill(void)
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002097{
2098 ftrace_disabled = 1;
2099 ftrace_enabled = 0;
Steven Rostedta2bb6a32008-07-10 20:58:15 -04002100 clear_ftrace_function();
2101}
2102
2103/**
Steven Rostedt3d083392008-05-12 21:20:42 +02002104 * register_ftrace_function - register a function for profiling
2105 * @ops - ops structure that holds the function for profiling.
2106 *
2107 * Register a function to be called by all functions in the
2108 * kernel.
2109 *
2110 * Note: @ops->func and all the functions it calls must be labeled
2111 * with "notrace", otherwise it will go into a
2112 * recursive loop.
2113 */
2114int register_ftrace_function(struct ftrace_ops *ops)
2115{
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002116 int ret;
2117
Steven Rostedt4eebcc82008-05-12 21:20:48 +02002118 if (unlikely(ftrace_disabled))
2119 return -1;
2120
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002121 mutex_lock(&ftrace_sysctl_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002122
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002123 ret = __register_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002124 ftrace_startup(0);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002125
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002126 mutex_unlock(&ftrace_sysctl_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002127 return ret;
Steven Rostedt3d083392008-05-12 21:20:42 +02002128}
2129
2130/**
Uwe Kleine-Koenig32632922009-01-12 23:35:50 +01002131 * unregister_ftrace_function - unregister a function for profiling.
Steven Rostedt3d083392008-05-12 21:20:42 +02002132 * @ops - ops structure that holds the function to unregister
2133 *
2134 * Unregister a function that was added to be called by ftrace profiling.
2135 */
2136int unregister_ftrace_function(struct ftrace_ops *ops)
2137{
2138 int ret;
2139
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002140 mutex_lock(&ftrace_sysctl_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02002141 ret = __unregister_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002142 ftrace_shutdown(0);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002143 mutex_unlock(&ftrace_sysctl_lock);
2144
2145 return ret;
2146}
2147
Ingo Molnare309b412008-05-12 21:20:51 +02002148int
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002149ftrace_enable_sysctl(struct ctl_table *table, int write,
Steven Rostedt5072c592008-05-12 21:20:43 +02002150 struct file *file, void __user *buffer, size_t *lenp,
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002151 loff_t *ppos)
2152{
2153 int ret;
2154
Steven Rostedt4eebcc82008-05-12 21:20:48 +02002155 if (unlikely(ftrace_disabled))
2156 return -ENODEV;
2157
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002158 mutex_lock(&ftrace_sysctl_lock);
2159
Steven Rostedt5072c592008-05-12 21:20:43 +02002160 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02002161
2162 if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
2163 goto out;
2164
2165 last_ftrace_enabled = ftrace_enabled;
2166
2167 if (ftrace_enabled) {
2168
2169 ftrace_startup_sysctl();
2170
2171 /* we are starting ftrace again */
2172 if (ftrace_list != &ftrace_list_end) {
2173 if (ftrace_list->next == &ftrace_list_end)
2174 ftrace_trace_function = ftrace_list->func;
2175 else
2176 ftrace_trace_function = ftrace_list_func;
2177 }
2178
2179 } else {
2180 /* stopping ftrace calls (just send to ftrace_stub) */
2181 ftrace_trace_function = ftrace_stub;
2182
2183 ftrace_shutdown_sysctl();
2184 }
2185
2186 out:
2187 mutex_unlock(&ftrace_sysctl_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02002188 return ret;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02002189}
Ingo Molnarf17845e2008-10-24 12:47:10 +02002190
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002191#ifdef CONFIG_FUNCTION_GRAPH_TRACER
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002192
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002193static atomic_t ftrace_graph_active;
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002194static struct notifier_block ftrace_suspend_notifier;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002195
Steven Rostedte49dc192008-12-02 23:50:05 -05002196int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
2197{
2198 return 0;
2199}
2200
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002201/* The callbacks that hook a function */
2202trace_func_graph_ret_t ftrace_graph_return =
2203 (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05002204trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002205
2206/* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */
2207static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
2208{
2209 int i;
2210 int ret = 0;
2211 unsigned long flags;
2212 int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
2213 struct task_struct *g, *t;
2214
2215 for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) {
2216 ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH
2217 * sizeof(struct ftrace_ret_stack),
2218 GFP_KERNEL);
2219 if (!ret_stack_list[i]) {
2220 start = 0;
2221 end = i;
2222 ret = -ENOMEM;
2223 goto free;
2224 }
2225 }
2226
2227 read_lock_irqsave(&tasklist_lock, flags);
2228 do_each_thread(g, t) {
2229 if (start == end) {
2230 ret = -EAGAIN;
2231 goto unlock;
2232 }
2233
2234 if (t->ret_stack == NULL) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002235 t->curr_ret_stack = -1;
Frederic Weisbecker48d68b22008-12-02 00:20:39 +01002236 /* Make sure IRQs see the -1 first: */
2237 barrier();
2238 t->ret_stack = ret_stack_list[start++];
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01002239 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002240 atomic_set(&t->trace_overrun, 0);
2241 }
2242 } while_each_thread(g, t);
2243
2244unlock:
2245 read_unlock_irqrestore(&tasklist_lock, flags);
2246free:
2247 for (i = start; i < end; i++)
2248 kfree(ret_stack_list[i]);
2249 return ret;
2250}
2251
2252/* Allocate a return stack for each task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002253static int start_graph_tracing(void)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002254{
2255 struct ftrace_ret_stack **ret_stack_list;
2256 int ret;
2257
2258 ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE *
2259 sizeof(struct ftrace_ret_stack *),
2260 GFP_KERNEL);
2261
2262 if (!ret_stack_list)
2263 return -ENOMEM;
2264
2265 do {
2266 ret = alloc_retstack_tasklist(ret_stack_list);
2267 } while (ret == -EAGAIN);
2268
2269 kfree(ret_stack_list);
2270 return ret;
2271}
2272
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002273/*
2274 * Hibernation protection.
2275 * The state of the current task is too much unstable during
2276 * suspend/restore to disk. We want to protect against that.
2277 */
2278static int
2279ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
2280 void *unused)
2281{
2282 switch (state) {
2283 case PM_HIBERNATION_PREPARE:
2284 pause_graph_tracing();
2285 break;
2286
2287 case PM_POST_HIBERNATION:
2288 unpause_graph_tracing();
2289 break;
2290 }
2291 return NOTIFY_DONE;
2292}
2293
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002294int register_ftrace_graph(trace_func_graph_ret_t retfunc,
2295 trace_func_graph_ent_t entryfunc)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002296{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002297 int ret = 0;
2298
2299 mutex_lock(&ftrace_sysctl_lock);
2300
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002301 ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
2302 register_pm_notifier(&ftrace_suspend_notifier);
2303
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002304 atomic_inc(&ftrace_graph_active);
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002305 ret = start_graph_tracing();
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002306 if (ret) {
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002307 atomic_dec(&ftrace_graph_active);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002308 goto out;
2309 }
Steven Rostedte53a6312008-11-26 00:16:25 -05002310
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002311 ftrace_graph_return = retfunc;
2312 ftrace_graph_entry = entryfunc;
Steven Rostedte53a6312008-11-26 00:16:25 -05002313
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002314 ftrace_startup(FTRACE_START_FUNC_RET);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002315
2316out:
2317 mutex_unlock(&ftrace_sysctl_lock);
2318 return ret;
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002319}
2320
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002321void unregister_ftrace_graph(void)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002322{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002323 mutex_lock(&ftrace_sysctl_lock);
2324
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002325 atomic_dec(&ftrace_graph_active);
2326 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05002327 ftrace_graph_entry = ftrace_graph_entry_stub;
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002328 ftrace_shutdown(FTRACE_STOP_FUNC_RET);
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08002329 unregister_pm_notifier(&ftrace_suspend_notifier);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01002330
2331 mutex_unlock(&ftrace_sysctl_lock);
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002332}
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002333
2334/* Allocate a return stack for newly created task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002335void ftrace_graph_init_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002336{
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01002337 if (atomic_read(&ftrace_graph_active)) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002338 t->ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
2339 * sizeof(struct ftrace_ret_stack),
2340 GFP_KERNEL);
2341 if (!t->ret_stack)
2342 return;
2343 t->curr_ret_stack = -1;
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01002344 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002345 atomic_set(&t->trace_overrun, 0);
2346 } else
2347 t->ret_stack = NULL;
2348}
2349
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01002350void ftrace_graph_exit_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002351{
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01002352 struct ftrace_ret_stack *ret_stack = t->ret_stack;
2353
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002354 t->ret_stack = NULL;
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01002355 /* NULL must become visible to IRQs before we free it: */
2356 barrier();
2357
2358 kfree(ret_stack);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01002359}
Steven Rostedt14a866c2008-12-02 23:50:02 -05002360
2361void ftrace_graph_stop(void)
2362{
2363 ftrace_stop();
2364}
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01002365#endif
2366