blob: c7f4a4be05dc0f96c35fec5163c23f7761d081fd [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
Steven Rostedt8aef2d22009-03-24 01:10:15 -040032#include <trace/sched.h>
33
Abhishek Sagar395a59d2008-06-21 23:47:27 +053034#include <asm/ftrace.h>
35
Steven Rostedt0706f1c2009-03-23 23:12:58 -040036#include "trace_output.h"
Steven Rostedtbac429f2009-03-20 12:50:56 -040037#include "trace_stat.h"
Steven Rostedt3d083392008-05-12 21:20:42 +020038
Steven Rostedt69128962008-10-23 09:33:03 -040039#define FTRACE_WARN_ON(cond) \
40 do { \
41 if (WARN_ON(cond)) \
42 ftrace_kill(); \
43 } while (0)
44
45#define FTRACE_WARN_ON_ONCE(cond) \
46 do { \
47 if (WARN_ON_ONCE(cond)) \
48 ftrace_kill(); \
49 } while (0)
50
Steven Rostedt8fc0c702009-02-16 15:28:00 -050051/* hash bits for specific function selection */
52#define FTRACE_HASH_BITS 7
53#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
54
Steven Rostedt4eebcc82008-05-12 21:20:48 +020055/* ftrace_enabled is a method to turn ftrace on or off */
56int ftrace_enabled __read_mostly;
Steven Rostedtd61f82d2008-05-12 21:20:43 +020057static int last_ftrace_enabled;
Steven Rostedtb0fc4942008-05-12 21:20:43 +020058
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050059/* Quick disabling of function tracer. */
60int function_trace_stop;
61
Steven Rostedt4eebcc82008-05-12 21:20:48 +020062/*
63 * ftrace_disabled is set when an anomaly is discovered.
64 * ftrace_disabled is much stronger than ftrace_enabled.
65 */
66static int ftrace_disabled __read_mostly;
67
Steven Rostedt52baf112009-02-14 01:15:39 -050068static DEFINE_MUTEX(ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +020069
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020070static struct ftrace_ops ftrace_list_end __read_mostly =
71{
Steven Rostedtfb9fb012009-03-25 13:26:41 -040072 .func = ftrace_stub,
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020073};
74
75static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
76ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -050077ftrace_func_t __ftrace_trace_function __read_mostly = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -050078ftrace_func_t ftrace_pid_function __read_mostly = ftrace_stub;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020079
Ingo Molnarf2252932008-05-22 10:37:48 +020080static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020081{
82 struct ftrace_ops *op = ftrace_list;
83
84 /* in case someone actually ports this to alpha! */
85 read_barrier_depends();
86
87 while (op != &ftrace_list_end) {
88 /* silly alpha */
89 read_barrier_depends();
90 op->func(ip, parent_ip);
91 op = op->next;
92 };
93}
94
Steven Rostedtdf4fc312008-11-26 00:16:23 -050095static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip)
96{
Steven Rostedt0ef8cde2008-12-03 15:36:58 -050097 if (!test_tsk_trace_trace(current))
Steven Rostedtdf4fc312008-11-26 00:16:23 -050098 return;
99
100 ftrace_pid_function(ip, parent_ip);
101}
102
103static void set_ftrace_pid_function(ftrace_func_t func)
104{
105 /* do not set ftrace_pid_function to itself! */
106 if (func != ftrace_pid_func)
107 ftrace_pid_function = func;
108}
109
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200110/**
Steven Rostedt3d083392008-05-12 21:20:42 +0200111 * clear_ftrace_function - reset the ftrace function
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200112 *
Steven Rostedt3d083392008-05-12 21:20:42 +0200113 * This NULLs the ftrace function and in essence stops
114 * tracing. There may be lag
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200115 */
Steven Rostedt3d083392008-05-12 21:20:42 +0200116void clear_ftrace_function(void)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200117{
Steven Rostedt3d083392008-05-12 21:20:42 +0200118 ftrace_trace_function = ftrace_stub;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500119 __ftrace_trace_function = ftrace_stub;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500120 ftrace_pid_function = ftrace_stub;
Steven Rostedt3d083392008-05-12 21:20:42 +0200121}
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200122
Steven Rostedt60a7ecf2008-11-05 16:05:44 -0500123#ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
124/*
125 * For those archs that do not test ftrace_trace_stop in their
126 * mcount call site, we need to do it from C.
127 */
128static void ftrace_test_stop_func(unsigned long ip, unsigned long parent_ip)
129{
130 if (function_trace_stop)
131 return;
132
133 __ftrace_trace_function(ip, parent_ip);
134}
135#endif
136
Ingo Molnare309b412008-05-12 21:20:51 +0200137static int __register_ftrace_function(struct ftrace_ops *ops)
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
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200174 return 0;
175}
176
Ingo Molnare309b412008-05-12 21:20:51 +0200177static int __unregister_ftrace_function(struct ftrace_ops *ops)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200178{
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200179 struct ftrace_ops **p;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200180
181 /*
Steven Rostedt3d083392008-05-12 21:20:42 +0200182 * If we are removing the last function, then simply point
183 * to the ftrace_stub.
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200184 */
185 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
186 ftrace_trace_function = ftrace_stub;
187 ftrace_list = &ftrace_list_end;
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500188 return 0;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200189 }
190
191 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
192 if (*p == ops)
193 break;
194
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500195 if (*p != ops)
196 return -1;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200197
198 *p = (*p)->next;
199
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200200 if (ftrace_enabled) {
201 /* If we only have one func left, then call that directly */
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500202 if (ftrace_list->next == &ftrace_list_end) {
203 ftrace_func_t func = ftrace_list->func;
204
Steven Rostedt978f3a42008-12-04 00:26:40 -0500205 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500206 set_ftrace_pid_function(func);
207 func = ftrace_pid_func;
208 }
209#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
210 ftrace_trace_function = func;
211#else
212 __ftrace_trace_function = func;
213#endif
214 }
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200215 }
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200216
Steven Rostedte6ea44e2009-02-14 01:42:44 -0500217 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +0200218}
219
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500220static void ftrace_update_pid_func(void)
221{
222 ftrace_func_t func;
223
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500224 if (ftrace_trace_function == ftrace_stub)
KOSAKI Motohiro10dd3eb2009-03-06 15:29:04 +0900225 return;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500226
227 func = ftrace_trace_function;
228
Steven Rostedt978f3a42008-12-04 00:26:40 -0500229 if (ftrace_pid_trace) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500230 set_ftrace_pid_function(func);
231 func = ftrace_pid_func;
232 } else {
Liming Wang66eafeb2008-12-02 10:33:08 +0800233 if (func == ftrace_pid_func)
234 func = ftrace_pid_function;
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500235 }
236
237#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
238 ftrace_trace_function = func;
239#else
240 __ftrace_trace_function = func;
241#endif
Steven Rostedtdf4fc312008-11-26 00:16:23 -0500242}
243
Steven Rostedt493762f2009-03-23 17:12:36 -0400244#ifdef CONFIG_FUNCTION_PROFILER
245struct ftrace_profile {
246 struct hlist_node node;
247 unsigned long ip;
248 unsigned long counter;
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400249#ifdef CONFIG_FUNCTION_GRAPH_TRACER
250 unsigned long long time;
251#endif
Steven Rostedt493762f2009-03-23 17:12:36 -0400252};
253
254struct ftrace_profile_page {
255 struct ftrace_profile_page *next;
256 unsigned long index;
257 struct ftrace_profile records[];
258};
259
Steven Rostedtcafb1682009-03-24 20:50:39 -0400260struct ftrace_profile_stat {
261 atomic_t disabled;
262 struct hlist_head *hash;
263 struct ftrace_profile_page *pages;
264 struct ftrace_profile_page *start;
265 struct tracer_stat stat;
266};
267
Steven Rostedt493762f2009-03-23 17:12:36 -0400268#define PROFILE_RECORDS_SIZE \
269 (PAGE_SIZE - offsetof(struct ftrace_profile_page, records))
270
271#define PROFILES_PER_PAGE \
272 (PROFILE_RECORDS_SIZE / sizeof(struct ftrace_profile))
273
Steven Rostedtfb9fb012009-03-25 13:26:41 -0400274static int ftrace_profile_bits __read_mostly;
275static int ftrace_profile_enabled __read_mostly;
276
277/* ftrace_profile_lock - synchronize the enable and disable of the profiler */
Steven Rostedt493762f2009-03-23 17:12:36 -0400278static DEFINE_MUTEX(ftrace_profile_lock);
279
Steven Rostedtcafb1682009-03-24 20:50:39 -0400280static DEFINE_PER_CPU(struct ftrace_profile_stat, ftrace_profile_stats);
Steven Rostedt493762f2009-03-23 17:12:36 -0400281
282#define FTRACE_PROFILE_HASH_SIZE 1024 /* must be power of 2 */
283
Steven Rostedt493762f2009-03-23 17:12:36 -0400284static void *
285function_stat_next(void *v, int idx)
286{
287 struct ftrace_profile *rec = v;
288 struct ftrace_profile_page *pg;
289
290 pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK);
291
292 again:
293 rec++;
294 if ((void *)rec >= (void *)&pg->records[pg->index]) {
295 pg = pg->next;
296 if (!pg)
297 return NULL;
298 rec = &pg->records[0];
299 if (!rec->counter)
300 goto again;
301 }
302
303 return rec;
304}
305
306static void *function_stat_start(struct tracer_stat *trace)
307{
Steven Rostedtcafb1682009-03-24 20:50:39 -0400308 struct ftrace_profile_stat *stat =
309 container_of(trace, struct ftrace_profile_stat, stat);
310
311 if (!stat || !stat->start)
312 return NULL;
313
314 return function_stat_next(&stat->start->records[0], 0);
Steven Rostedt493762f2009-03-23 17:12:36 -0400315}
316
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400317#ifdef CONFIG_FUNCTION_GRAPH_TRACER
318/* function graph compares on total time */
319static int function_stat_cmp(void *p1, void *p2)
320{
321 struct ftrace_profile *a = p1;
322 struct ftrace_profile *b = p2;
323
324 if (a->time < b->time)
325 return -1;
326 if (a->time > b->time)
327 return 1;
328 else
329 return 0;
330}
331#else
332/* not function graph compares against hits */
Steven Rostedt493762f2009-03-23 17:12:36 -0400333static int function_stat_cmp(void *p1, void *p2)
334{
335 struct ftrace_profile *a = p1;
336 struct ftrace_profile *b = p2;
337
338 if (a->counter < b->counter)
339 return -1;
340 if (a->counter > b->counter)
341 return 1;
342 else
343 return 0;
344}
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400345#endif
Steven Rostedt493762f2009-03-23 17:12:36 -0400346
347static int function_stat_headers(struct seq_file *m)
348{
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400349#ifdef CONFIG_FUNCTION_GRAPH_TRACER
Steven Rostedt34886c82009-03-25 21:00:47 -0400350 seq_printf(m, " Function "
351 "Hit Time Avg\n"
352 " -------- "
353 "--- ---- ---\n");
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400354#else
Steven Rostedt493762f2009-03-23 17:12:36 -0400355 seq_printf(m, " Function Hit\n"
356 " -------- ---\n");
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400357#endif
Steven Rostedt493762f2009-03-23 17:12:36 -0400358 return 0;
359}
360
361static int function_stat_show(struct seq_file *m, void *v)
362{
363 struct ftrace_profile *rec = v;
364 char str[KSYM_SYMBOL_LEN];
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400365#ifdef CONFIG_FUNCTION_GRAPH_TRACER
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400366 static DEFINE_MUTEX(mutex);
Steven Rostedt34886c82009-03-25 21:00:47 -0400367 static struct trace_seq s;
368 unsigned long long avg;
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400369#endif
Steven Rostedt493762f2009-03-23 17:12:36 -0400370
371 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400372 seq_printf(m, " %-30.30s %10lu", str, rec->counter);
Steven Rostedt493762f2009-03-23 17:12:36 -0400373
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400374#ifdef CONFIG_FUNCTION_GRAPH_TRACER
375 seq_printf(m, " ");
Steven Rostedt34886c82009-03-25 21:00:47 -0400376 avg = rec->time;
377 do_div(avg, rec->counter);
378
379 mutex_lock(&mutex);
380 trace_seq_init(&s);
381 trace_print_graph_duration(rec->time, &s);
382 trace_seq_puts(&s, " ");
383 trace_print_graph_duration(avg, &s);
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400384 trace_print_seq(m, &s);
385 mutex_unlock(&mutex);
386#endif
387 seq_putc(m, '\n');
388
Steven Rostedt493762f2009-03-23 17:12:36 -0400389 return 0;
390}
391
Steven Rostedtcafb1682009-03-24 20:50:39 -0400392static void ftrace_profile_reset(struct ftrace_profile_stat *stat)
Steven Rostedt493762f2009-03-23 17:12:36 -0400393{
394 struct ftrace_profile_page *pg;
395
Steven Rostedtcafb1682009-03-24 20:50:39 -0400396 pg = stat->pages = stat->start;
Steven Rostedt493762f2009-03-23 17:12:36 -0400397
398 while (pg) {
399 memset(pg->records, 0, PROFILE_RECORDS_SIZE);
400 pg->index = 0;
401 pg = pg->next;
402 }
403
Steven Rostedtcafb1682009-03-24 20:50:39 -0400404 memset(stat->hash, 0,
Steven Rostedt493762f2009-03-23 17:12:36 -0400405 FTRACE_PROFILE_HASH_SIZE * sizeof(struct hlist_head));
406}
407
Steven Rostedtcafb1682009-03-24 20:50:39 -0400408int ftrace_profile_pages_init(struct ftrace_profile_stat *stat)
Steven Rostedt493762f2009-03-23 17:12:36 -0400409{
410 struct ftrace_profile_page *pg;
Steven Rostedt318e0a72009-03-25 20:06:34 -0400411 int functions;
412 int pages;
Steven Rostedt493762f2009-03-23 17:12:36 -0400413 int i;
414
415 /* If we already allocated, do nothing */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400416 if (stat->pages)
Steven Rostedt493762f2009-03-23 17:12:36 -0400417 return 0;
418
Steven Rostedtcafb1682009-03-24 20:50:39 -0400419 stat->pages = (void *)get_zeroed_page(GFP_KERNEL);
420 if (!stat->pages)
Steven Rostedt493762f2009-03-23 17:12:36 -0400421 return -ENOMEM;
422
Steven Rostedt318e0a72009-03-25 20:06:34 -0400423#ifdef CONFIG_DYNAMIC_FTRACE
424 functions = ftrace_update_tot_cnt;
425#else
426 /*
427 * We do not know the number of functions that exist because
428 * dynamic tracing is what counts them. With past experience
429 * we have around 20K functions. That should be more than enough.
430 * It is highly unlikely we will execute every function in
431 * the kernel.
432 */
433 functions = 20000;
434#endif
435
Steven Rostedtcafb1682009-03-24 20:50:39 -0400436 pg = stat->start = stat->pages;
Steven Rostedt493762f2009-03-23 17:12:36 -0400437
Steven Rostedt318e0a72009-03-25 20:06:34 -0400438 pages = DIV_ROUND_UP(functions, PROFILES_PER_PAGE);
439
440 for (i = 0; i < pages; i++) {
Steven Rostedt493762f2009-03-23 17:12:36 -0400441 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
Steven Rostedt493762f2009-03-23 17:12:36 -0400442 if (!pg->next)
Steven Rostedt318e0a72009-03-25 20:06:34 -0400443 goto out_free;
Steven Rostedt493762f2009-03-23 17:12:36 -0400444 pg = pg->next;
445 }
446
447 return 0;
Steven Rostedt318e0a72009-03-25 20:06:34 -0400448
449 out_free:
450 pg = stat->start;
451 while (pg) {
452 unsigned long tmp = (unsigned long)pg;
453
454 pg = pg->next;
455 free_page(tmp);
456 }
457
458 free_page((unsigned long)stat->pages);
459 stat->pages = NULL;
460 stat->start = NULL;
461
462 return -ENOMEM;
Steven Rostedt493762f2009-03-23 17:12:36 -0400463}
464
Steven Rostedtcafb1682009-03-24 20:50:39 -0400465static int ftrace_profile_init_cpu(int cpu)
Steven Rostedt493762f2009-03-23 17:12:36 -0400466{
Steven Rostedtcafb1682009-03-24 20:50:39 -0400467 struct ftrace_profile_stat *stat;
Steven Rostedt493762f2009-03-23 17:12:36 -0400468 int size;
469
Steven Rostedtcafb1682009-03-24 20:50:39 -0400470 stat = &per_cpu(ftrace_profile_stats, cpu);
471
472 if (stat->hash) {
Steven Rostedt493762f2009-03-23 17:12:36 -0400473 /* If the profile is already created, simply reset it */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400474 ftrace_profile_reset(stat);
Steven Rostedt493762f2009-03-23 17:12:36 -0400475 return 0;
476 }
477
478 /*
479 * We are profiling all functions, but usually only a few thousand
480 * functions are hit. We'll make a hash of 1024 items.
481 */
482 size = FTRACE_PROFILE_HASH_SIZE;
483
Steven Rostedtcafb1682009-03-24 20:50:39 -0400484 stat->hash = kzalloc(sizeof(struct hlist_head) * size, GFP_KERNEL);
Steven Rostedt493762f2009-03-23 17:12:36 -0400485
Steven Rostedtcafb1682009-03-24 20:50:39 -0400486 if (!stat->hash)
Steven Rostedt493762f2009-03-23 17:12:36 -0400487 return -ENOMEM;
488
Steven Rostedtcafb1682009-03-24 20:50:39 -0400489 if (!ftrace_profile_bits) {
490 size--;
Steven Rostedt493762f2009-03-23 17:12:36 -0400491
Steven Rostedtcafb1682009-03-24 20:50:39 -0400492 for (; size; size >>= 1)
493 ftrace_profile_bits++;
494 }
Steven Rostedt493762f2009-03-23 17:12:36 -0400495
Steven Rostedt318e0a72009-03-25 20:06:34 -0400496 /* Preallocate the function profiling pages */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400497 if (ftrace_profile_pages_init(stat) < 0) {
498 kfree(stat->hash);
499 stat->hash = NULL;
Steven Rostedt493762f2009-03-23 17:12:36 -0400500 return -ENOMEM;
501 }
502
503 return 0;
504}
505
Steven Rostedtcafb1682009-03-24 20:50:39 -0400506static int ftrace_profile_init(void)
507{
508 int cpu;
509 int ret = 0;
510
511 for_each_online_cpu(cpu) {
512 ret = ftrace_profile_init_cpu(cpu);
513 if (ret)
514 break;
515 }
516
517 return ret;
518}
519
Steven Rostedt493762f2009-03-23 17:12:36 -0400520/* interrupts must be disabled */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400521static struct ftrace_profile *
522ftrace_find_profiled_func(struct ftrace_profile_stat *stat, unsigned long ip)
Steven Rostedt493762f2009-03-23 17:12:36 -0400523{
524 struct ftrace_profile *rec;
525 struct hlist_head *hhd;
526 struct hlist_node *n;
527 unsigned long key;
528
529 key = hash_long(ip, ftrace_profile_bits);
Steven Rostedtcafb1682009-03-24 20:50:39 -0400530 hhd = &stat->hash[key];
Steven Rostedt493762f2009-03-23 17:12:36 -0400531
532 if (hlist_empty(hhd))
533 return NULL;
534
535 hlist_for_each_entry_rcu(rec, n, hhd, node) {
536 if (rec->ip == ip)
537 return rec;
538 }
539
540 return NULL;
541}
542
Steven Rostedtcafb1682009-03-24 20:50:39 -0400543static void ftrace_add_profile(struct ftrace_profile_stat *stat,
544 struct ftrace_profile *rec)
Steven Rostedt493762f2009-03-23 17:12:36 -0400545{
546 unsigned long key;
547
548 key = hash_long(rec->ip, ftrace_profile_bits);
Steven Rostedtcafb1682009-03-24 20:50:39 -0400549 hlist_add_head_rcu(&rec->node, &stat->hash[key]);
Steven Rostedt493762f2009-03-23 17:12:36 -0400550}
551
Steven Rostedt318e0a72009-03-25 20:06:34 -0400552/*
553 * The memory is already allocated, this simply finds a new record to use.
554 */
Steven Rostedt493762f2009-03-23 17:12:36 -0400555static struct ftrace_profile *
Steven Rostedt318e0a72009-03-25 20:06:34 -0400556ftrace_profile_alloc(struct ftrace_profile_stat *stat, unsigned long ip)
Steven Rostedt493762f2009-03-23 17:12:36 -0400557{
558 struct ftrace_profile *rec = NULL;
559
Steven Rostedt318e0a72009-03-25 20:06:34 -0400560 /* prevent recursion (from NMIs) */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400561 if (atomic_inc_return(&stat->disabled) != 1)
Steven Rostedt493762f2009-03-23 17:12:36 -0400562 goto out;
563
Steven Rostedt493762f2009-03-23 17:12:36 -0400564 /*
Steven Rostedt318e0a72009-03-25 20:06:34 -0400565 * Try to find the function again since an NMI
566 * could have added it
Steven Rostedt493762f2009-03-23 17:12:36 -0400567 */
Steven Rostedtcafb1682009-03-24 20:50:39 -0400568 rec = ftrace_find_profiled_func(stat, ip);
Steven Rostedt493762f2009-03-23 17:12:36 -0400569 if (rec)
Steven Rostedtcafb1682009-03-24 20:50:39 -0400570 goto out;
Steven Rostedt493762f2009-03-23 17:12:36 -0400571
Steven Rostedtcafb1682009-03-24 20:50:39 -0400572 if (stat->pages->index == PROFILES_PER_PAGE) {
573 if (!stat->pages->next)
574 goto out;
575 stat->pages = stat->pages->next;
Steven Rostedt493762f2009-03-23 17:12:36 -0400576 }
577
Steven Rostedtcafb1682009-03-24 20:50:39 -0400578 rec = &stat->pages->records[stat->pages->index++];
Steven Rostedt493762f2009-03-23 17:12:36 -0400579 rec->ip = ip;
Steven Rostedtcafb1682009-03-24 20:50:39 -0400580 ftrace_add_profile(stat, rec);
Steven Rostedt493762f2009-03-23 17:12:36 -0400581
Steven Rostedt493762f2009-03-23 17:12:36 -0400582 out:
Steven Rostedtcafb1682009-03-24 20:50:39 -0400583 atomic_dec(&stat->disabled);
Steven Rostedt493762f2009-03-23 17:12:36 -0400584
585 return rec;
586}
587
Steven Rostedt493762f2009-03-23 17:12:36 -0400588static void
589function_profile_call(unsigned long ip, unsigned long parent_ip)
590{
Steven Rostedtcafb1682009-03-24 20:50:39 -0400591 struct ftrace_profile_stat *stat;
Steven Rostedt493762f2009-03-23 17:12:36 -0400592 struct ftrace_profile *rec;
593 unsigned long flags;
Steven Rostedt493762f2009-03-23 17:12:36 -0400594
595 if (!ftrace_profile_enabled)
596 return;
597
Steven Rostedt493762f2009-03-23 17:12:36 -0400598 local_irq_save(flags);
Steven Rostedtcafb1682009-03-24 20:50:39 -0400599
600 stat = &__get_cpu_var(ftrace_profile_stats);
601 if (!stat->hash)
602 goto out;
603
604 rec = ftrace_find_profiled_func(stat, ip);
Steven Rostedt493762f2009-03-23 17:12:36 -0400605 if (!rec) {
Steven Rostedt318e0a72009-03-25 20:06:34 -0400606 rec = ftrace_profile_alloc(stat, ip);
Steven Rostedt493762f2009-03-23 17:12:36 -0400607 if (!rec)
608 goto out;
609 }
610
611 rec->counter++;
612 out:
613 local_irq_restore(flags);
614}
615
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400616#ifdef CONFIG_FUNCTION_GRAPH_TRACER
617static int profile_graph_entry(struct ftrace_graph_ent *trace)
618{
619 function_profile_call(trace->func, 0);
620 return 1;
621}
622
623static void profile_graph_return(struct ftrace_graph_ret *trace)
624{
Steven Rostedtcafb1682009-03-24 20:50:39 -0400625 struct ftrace_profile_stat *stat;
Steven Rostedta2a16d62009-03-24 23:17:58 -0400626 unsigned long long calltime;
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400627 struct ftrace_profile *rec;
Steven Rostedtcafb1682009-03-24 20:50:39 -0400628 unsigned long flags;
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400629
630 local_irq_save(flags);
Steven Rostedtcafb1682009-03-24 20:50:39 -0400631 stat = &__get_cpu_var(ftrace_profile_stats);
632 if (!stat->hash)
633 goto out;
634
Steven Rostedta2a16d62009-03-24 23:17:58 -0400635 calltime = trace->rettime - trace->calltime;
636
637 if (!(trace_flags & TRACE_ITER_GRAPH_TIME)) {
638 int index;
639
640 index = trace->depth;
641
642 /* Append this call time to the parent time to subtract */
643 if (index)
644 current->ret_stack[index - 1].subtime += calltime;
645
646 if (current->ret_stack[index].subtime < calltime)
647 calltime -= current->ret_stack[index].subtime;
648 else
649 calltime = 0;
650 }
651
Steven Rostedtcafb1682009-03-24 20:50:39 -0400652 rec = ftrace_find_profiled_func(stat, trace->func);
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400653 if (rec)
Steven Rostedta2a16d62009-03-24 23:17:58 -0400654 rec->time += calltime;
655
Steven Rostedtcafb1682009-03-24 20:50:39 -0400656 out:
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400657 local_irq_restore(flags);
658}
659
660static int register_ftrace_profiler(void)
661{
662 return register_ftrace_graph(&profile_graph_return,
663 &profile_graph_entry);
664}
665
666static void unregister_ftrace_profiler(void)
667{
668 unregister_ftrace_graph();
669}
670#else
Steven Rostedt493762f2009-03-23 17:12:36 -0400671static struct ftrace_ops ftrace_profile_ops __read_mostly =
672{
Steven Rostedtfb9fb012009-03-25 13:26:41 -0400673 .func = function_profile_call,
Steven Rostedt493762f2009-03-23 17:12:36 -0400674};
675
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400676static int register_ftrace_profiler(void)
677{
678 return register_ftrace_function(&ftrace_profile_ops);
679}
680
681static void unregister_ftrace_profiler(void)
682{
683 unregister_ftrace_function(&ftrace_profile_ops);
684}
685#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
686
Steven Rostedt493762f2009-03-23 17:12:36 -0400687static ssize_t
688ftrace_profile_write(struct file *filp, const char __user *ubuf,
689 size_t cnt, loff_t *ppos)
690{
691 unsigned long val;
Steven Rostedtfb9fb012009-03-25 13:26:41 -0400692 char buf[64]; /* big enough to hold a number */
Steven Rostedt493762f2009-03-23 17:12:36 -0400693 int ret;
694
695 if (cnt >= sizeof(buf))
696 return -EINVAL;
697
698 if (copy_from_user(&buf, ubuf, cnt))
699 return -EFAULT;
700
701 buf[cnt] = 0;
702
703 ret = strict_strtoul(buf, 10, &val);
704 if (ret < 0)
705 return ret;
706
707 val = !!val;
708
709 mutex_lock(&ftrace_profile_lock);
710 if (ftrace_profile_enabled ^ val) {
711 if (val) {
712 ret = ftrace_profile_init();
713 if (ret < 0) {
714 cnt = ret;
715 goto out;
716 }
717
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400718 ret = register_ftrace_profiler();
719 if (ret < 0) {
720 cnt = ret;
721 goto out;
722 }
Steven Rostedt493762f2009-03-23 17:12:36 -0400723 ftrace_profile_enabled = 1;
724 } else {
725 ftrace_profile_enabled = 0;
Steven Rostedt0706f1c2009-03-23 23:12:58 -0400726 unregister_ftrace_profiler();
Steven Rostedt493762f2009-03-23 17:12:36 -0400727 }
728 }
729 out:
730 mutex_unlock(&ftrace_profile_lock);
731
732 filp->f_pos += cnt;
733
734 return cnt;
735}
736
737static ssize_t
738ftrace_profile_read(struct file *filp, char __user *ubuf,
739 size_t cnt, loff_t *ppos)
740{
Steven Rostedtfb9fb012009-03-25 13:26:41 -0400741 char buf[64]; /* big enough to hold a number */
Steven Rostedt493762f2009-03-23 17:12:36 -0400742 int r;
743
744 r = sprintf(buf, "%u\n", ftrace_profile_enabled);
745 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
746}
747
748static const struct file_operations ftrace_profile_fops = {
749 .open = tracing_open_generic,
750 .read = ftrace_profile_read,
751 .write = ftrace_profile_write,
752};
753
Steven Rostedtcafb1682009-03-24 20:50:39 -0400754/* used to initialize the real stat files */
755static struct tracer_stat function_stats __initdata = {
Steven Rostedtfb9fb012009-03-25 13:26:41 -0400756 .name = "functions",
757 .stat_start = function_stat_start,
758 .stat_next = function_stat_next,
759 .stat_cmp = function_stat_cmp,
760 .stat_headers = function_stat_headers,
761 .stat_show = function_stat_show
Steven Rostedtcafb1682009-03-24 20:50:39 -0400762};
763
Steven Rostedt493762f2009-03-23 17:12:36 -0400764static void ftrace_profile_debugfs(struct dentry *d_tracer)
765{
Steven Rostedtcafb1682009-03-24 20:50:39 -0400766 struct ftrace_profile_stat *stat;
Steven Rostedt493762f2009-03-23 17:12:36 -0400767 struct dentry *entry;
Steven Rostedtcafb1682009-03-24 20:50:39 -0400768 char *name;
Steven Rostedt493762f2009-03-23 17:12:36 -0400769 int ret;
Steven Rostedtcafb1682009-03-24 20:50:39 -0400770 int cpu;
Steven Rostedt493762f2009-03-23 17:12:36 -0400771
Steven Rostedtcafb1682009-03-24 20:50:39 -0400772 for_each_possible_cpu(cpu) {
773 stat = &per_cpu(ftrace_profile_stats, cpu);
774
775 /* allocate enough for function name + cpu number */
776 name = kmalloc(32, GFP_KERNEL);
777 if (!name) {
778 /*
779 * The files created are permanent, if something happens
780 * we still do not free memory.
781 */
782 kfree(stat);
783 WARN(1,
784 "Could not allocate stat file for cpu %d\n",
785 cpu);
786 return;
787 }
788 stat->stat = function_stats;
789 snprintf(name, 32, "function%d", cpu);
790 stat->stat.name = name;
791 ret = register_stat_tracer(&stat->stat);
792 if (ret) {
793 WARN(1,
794 "Could not register function stat for cpu %d\n",
795 cpu);
796 kfree(name);
797 return;
798 }
Steven Rostedt493762f2009-03-23 17:12:36 -0400799 }
800
801 entry = debugfs_create_file("function_profile_enabled", 0644,
802 d_tracer, NULL, &ftrace_profile_fops);
803 if (!entry)
804 pr_warning("Could not create debugfs "
805 "'function_profile_enabled' entry\n");
806}
807
808#else /* CONFIG_FUNCTION_PROFILER */
809static void ftrace_profile_debugfs(struct dentry *d_tracer)
810{
811}
812#endif /* CONFIG_FUNCTION_PROFILER */
813
Ingo Molnar73d3fd92009-02-17 11:48:18 +0100814/* set when tracing only a pid */
815struct pid *ftrace_pid_trace;
816static struct pid * const ftrace_swapper_pid = &init_struct_pid;
817
Steven Rostedt3d083392008-05-12 21:20:42 +0200818#ifdef CONFIG_DYNAMIC_FTRACE
Ingo Molnar73d3fd92009-02-17 11:48:18 +0100819
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400820#ifndef CONFIG_FTRACE_MCOUNT_RECORD
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400821# error Dynamic ftrace depends on MCOUNT_RECORD
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400822#endif
823
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500824static struct hlist_head ftrace_func_hash[FTRACE_FUNC_HASHSIZE] __read_mostly;
825
Steven Rostedtb6887d72009-02-17 12:32:04 -0500826struct ftrace_func_probe {
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500827 struct hlist_node node;
Steven Rostedtb6887d72009-02-17 12:32:04 -0500828 struct ftrace_probe_ops *ops;
Steven Rostedt8fc0c702009-02-16 15:28:00 -0500829 unsigned long flags;
830 unsigned long ip;
831 void *data;
832 struct rcu_head rcu;
833};
834
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200835enum {
836 FTRACE_ENABLE_CALLS = (1 << 0),
837 FTRACE_DISABLE_CALLS = (1 << 1),
838 FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
839 FTRACE_ENABLE_MCOUNT = (1 << 3),
840 FTRACE_DISABLE_MCOUNT = (1 << 4),
Steven Rostedt5a45cfe2008-11-26 00:16:24 -0500841 FTRACE_START_FUNC_RET = (1 << 5),
842 FTRACE_STOP_FUNC_RET = (1 << 6),
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200843};
844
Steven Rostedt5072c592008-05-12 21:20:43 +0200845static int ftrace_filtered;
846
Lai Jiangshane94142a2009-03-13 17:51:27 +0800847static struct dyn_ftrace *ftrace_new_addrs;
Steven Rostedt3d083392008-05-12 21:20:42 +0200848
Steven Rostedt41c52c02008-05-22 11:46:33 -0400849static DEFINE_MUTEX(ftrace_regex_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200850
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200851struct ftrace_page {
852 struct ftrace_page *next;
Steven Rostedt431aa3f2009-01-06 12:43:01 -0500853 int index;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200854 struct dyn_ftrace records[];
David Milleraa5e5ce2008-05-13 22:06:56 -0700855};
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200856
857#define ENTRIES_PER_PAGE \
858 ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
859
860/* estimate from running different kernels */
861#define NR_TO_INIT 10000
862
863static struct ftrace_page *ftrace_pages_start;
864static struct ftrace_page *ftrace_pages;
865
Steven Rostedt37ad5082008-05-12 21:20:48 +0200866static struct dyn_ftrace *ftrace_free_records;
867
Steven Rostedt265c8312009-02-13 12:43:56 -0500868/*
869 * This is a double for. Do not use 'break' to break out of the loop,
870 * you must use a goto.
871 */
872#define do_for_each_ftrace_rec(pg, rec) \
873 for (pg = ftrace_pages_start; pg; pg = pg->next) { \
874 int _____i; \
875 for (_____i = 0; _____i < pg->index; _____i++) { \
876 rec = &pg->records[_____i];
877
878#define while_for_each_ftrace_rec() \
879 } \
880 }
Abhishek Sagarecea6562008-06-21 23:47:53 +0530881
882#ifdef CONFIG_KPROBES
Ingo Molnarf17845e2008-10-24 12:47:10 +0200883
884static int frozen_record_count;
885
Abhishek Sagarecea6562008-06-21 23:47:53 +0530886static inline void freeze_record(struct dyn_ftrace *rec)
887{
888 if (!(rec->flags & FTRACE_FL_FROZEN)) {
889 rec->flags |= FTRACE_FL_FROZEN;
890 frozen_record_count++;
891 }
892}
893
894static inline void unfreeze_record(struct dyn_ftrace *rec)
895{
896 if (rec->flags & FTRACE_FL_FROZEN) {
897 rec->flags &= ~FTRACE_FL_FROZEN;
898 frozen_record_count--;
899 }
900}
901
902static inline int record_frozen(struct dyn_ftrace *rec)
903{
904 return rec->flags & FTRACE_FL_FROZEN;
905}
906#else
907# define freeze_record(rec) ({ 0; })
908# define unfreeze_record(rec) ({ 0; })
909# define record_frozen(rec) ({ 0; })
910#endif /* CONFIG_KPROBES */
911
Ingo Molnare309b412008-05-12 21:20:51 +0200912static void ftrace_free_rec(struct dyn_ftrace *rec)
Steven Rostedt37ad5082008-05-12 21:20:48 +0200913{
Lai Jiangshanee000b72009-03-24 13:38:06 +0800914 rec->freelist = ftrace_free_records;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200915 ftrace_free_records = rec;
916 rec->flags |= FTRACE_FL_FREE;
917}
918
Steven Rostedtfed19392008-08-14 22:47:19 -0400919void ftrace_release(void *start, unsigned long size)
920{
921 struct dyn_ftrace *rec;
922 struct ftrace_page *pg;
923 unsigned long s = (unsigned long)start;
924 unsigned long e = s + size;
Steven Rostedtfed19392008-08-14 22:47:19 -0400925
Steven Rostedt00fd61a2008-08-15 21:40:04 -0400926 if (ftrace_disabled || !start)
Steven Rostedtfed19392008-08-14 22:47:19 -0400927 return;
928
Steven Rostedt52baf112009-02-14 01:15:39 -0500929 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -0500930 do_for_each_ftrace_rec(pg, rec) {
Zhaoleib00f0b62009-03-13 17:14:01 +0800931 if ((rec->ip >= s) && (rec->ip < e) &&
Steven Rostedt493762f2009-03-23 17:12:36 -0400932 !(rec->flags & FTRACE_FL_FREE))
Steven Rostedt265c8312009-02-13 12:43:56 -0500933 ftrace_free_rec(rec);
934 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -0500935 mutex_unlock(&ftrace_lock);
Steven Rostedtfed19392008-08-14 22:47:19 -0400936}
937
Ingo Molnare309b412008-05-12 21:20:51 +0200938static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200939{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200940 struct dyn_ftrace *rec;
941
942 /* First check for freed records */
943 if (ftrace_free_records) {
944 rec = ftrace_free_records;
945
Steven Rostedt37ad5082008-05-12 21:20:48 +0200946 if (unlikely(!(rec->flags & FTRACE_FL_FREE))) {
Steven Rostedt69128962008-10-23 09:33:03 -0400947 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt37ad5082008-05-12 21:20:48 +0200948 ftrace_free_records = NULL;
949 return NULL;
950 }
951
Lai Jiangshanee000b72009-03-24 13:38:06 +0800952 ftrace_free_records = rec->freelist;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200953 memset(rec, 0, sizeof(*rec));
954 return rec;
955 }
956
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200957 if (ftrace_pages->index == ENTRIES_PER_PAGE) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400958 if (!ftrace_pages->next) {
959 /* allocate another page */
960 ftrace_pages->next =
961 (void *)get_zeroed_page(GFP_KERNEL);
962 if (!ftrace_pages->next)
963 return NULL;
964 }
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200965 ftrace_pages = ftrace_pages->next;
966 }
967
968 return &ftrace_pages->records[ftrace_pages->index++];
969}
970
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400971static struct dyn_ftrace *
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200972ftrace_record_ip(unsigned long ip)
Steven Rostedt3d083392008-05-12 21:20:42 +0200973{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400974 struct dyn_ftrace *rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200975
Steven Rostedtf3c7ac42008-11-14 16:21:19 -0800976 if (ftrace_disabled)
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400977 return NULL;
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200978
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400979 rec = ftrace_alloc_dyn_node(ip);
980 if (!rec)
981 return NULL;
Steven Rostedt3d083392008-05-12 21:20:42 +0200982
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400983 rec->ip = ip;
Lai Jiangshanee000b72009-03-24 13:38:06 +0800984 rec->newlist = ftrace_new_addrs;
Lai Jiangshane94142a2009-03-13 17:51:27 +0800985 ftrace_new_addrs = rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200986
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400987 return rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200988}
989
Steven Rostedt05736a42008-09-22 14:55:47 -0700990static void print_ip_ins(const char *fmt, unsigned char *p)
991{
992 int i;
993
994 printk(KERN_CONT "%s", fmt);
995
996 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
997 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
998}
999
Steven Rostedt31e88902008-11-14 16:21:19 -08001000static void ftrace_bug(int failed, unsigned long ip)
Steven Rostedtb17e8a32008-11-14 16:21:19 -08001001{
1002 switch (failed) {
1003 case -EFAULT:
1004 FTRACE_WARN_ON_ONCE(1);
1005 pr_info("ftrace faulted on modifying ");
1006 print_ip_sym(ip);
1007 break;
1008 case -EINVAL:
1009 FTRACE_WARN_ON_ONCE(1);
1010 pr_info("ftrace failed to modify ");
1011 print_ip_sym(ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -08001012 print_ip_ins(" actual: ", (unsigned char *)ip);
Steven Rostedtb17e8a32008-11-14 16:21:19 -08001013 printk(KERN_CONT "\n");
1014 break;
1015 case -EPERM:
1016 FTRACE_WARN_ON_ONCE(1);
1017 pr_info("ftrace faulted on writing ");
1018 print_ip_sym(ip);
1019 break;
1020 default:
1021 FTRACE_WARN_ON_ONCE(1);
1022 pr_info("ftrace faulted on unknown error ");
1023 print_ip_sym(ip);
1024 }
1025}
1026
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001027
Abhishek Sagar492a7ea2008-05-25 00:10:04 +05301028static int
Steven Rostedt31e88902008-11-14 16:21:19 -08001029__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001030{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01001031 unsigned long ftrace_addr;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001032 unsigned long ip, fl;
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01001033
Shaohua Lif0001202009-01-09 11:29:42 +08001034 ftrace_addr = (unsigned long)FTRACE_ADDR;
Steven Rostedt5072c592008-05-12 21:20:43 +02001035
1036 ip = rec->ip;
1037
Steven Rostedt982c3502008-11-15 16:31:41 -05001038 /*
1039 * If this record is not to be traced and
1040 * it is not enabled then do nothing.
1041 *
1042 * If this record is not to be traced and
Wenji Huang57794a92009-02-06 17:33:27 +08001043 * it is enabled then disable it.
Steven Rostedt982c3502008-11-15 16:31:41 -05001044 *
1045 */
1046 if (rec->flags & FTRACE_FL_NOTRACE) {
1047 if (rec->flags & FTRACE_FL_ENABLED)
1048 rec->flags &= ~FTRACE_FL_ENABLED;
1049 else
Steven Rostedt5072c592008-05-12 21:20:43 +02001050 return 0;
1051
Steven Rostedt982c3502008-11-15 16:31:41 -05001052 } else if (ftrace_filtered && enable) {
Steven Rostedt5072c592008-05-12 21:20:43 +02001053 /*
Steven Rostedt982c3502008-11-15 16:31:41 -05001054 * Filtering is on:
Steven Rostedt5072c592008-05-12 21:20:43 +02001055 */
Steven Rostedt982c3502008-11-15 16:31:41 -05001056
1057 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED);
1058
1059 /* Record is filtered and enabled, do nothing */
1060 if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
1061 return 0;
1062
Wenji Huang57794a92009-02-06 17:33:27 +08001063 /* Record is not filtered or enabled, do nothing */
Steven Rostedt982c3502008-11-15 16:31:41 -05001064 if (!fl)
1065 return 0;
1066
1067 /* Record is not filtered but enabled, disable it */
1068 if (fl == FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +02001069 rec->flags &= ~FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -05001070 else
1071 /* Otherwise record is filtered but not enabled, enable it */
Steven Rostedt5072c592008-05-12 21:20:43 +02001072 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt5072c592008-05-12 21:20:43 +02001073 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -05001074 /* Disable or not filtered */
Steven Rostedt5072c592008-05-12 21:20:43 +02001075
1076 if (enable) {
Steven Rostedt982c3502008-11-15 16:31:41 -05001077 /* if record is enabled, do nothing */
Steven Rostedt41c52c02008-05-22 11:46:33 -04001078 if (rec->flags & FTRACE_FL_ENABLED)
Steven Rostedt5072c592008-05-12 21:20:43 +02001079 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -05001080
Steven Rostedt41c52c02008-05-22 11:46:33 -04001081 rec->flags |= FTRACE_FL_ENABLED;
Steven Rostedt982c3502008-11-15 16:31:41 -05001082
Steven Rostedt5072c592008-05-12 21:20:43 +02001083 } else {
Steven Rostedt982c3502008-11-15 16:31:41 -05001084
Wenji Huang57794a92009-02-06 17:33:27 +08001085 /* if record is not enabled, do nothing */
Steven Rostedt5072c592008-05-12 21:20:43 +02001086 if (!(rec->flags & FTRACE_FL_ENABLED))
1087 return 0;
Steven Rostedt982c3502008-11-15 16:31:41 -05001088
Steven Rostedt5072c592008-05-12 21:20:43 +02001089 rec->flags &= ~FTRACE_FL_ENABLED;
1090 }
1091 }
1092
Steven Rostedt982c3502008-11-15 16:31:41 -05001093 if (rec->flags & FTRACE_FL_ENABLED)
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01001094 return ftrace_make_call(rec, ftrace_addr);
Steven Rostedt31e88902008-11-14 16:21:19 -08001095 else
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01001096 return ftrace_make_nop(NULL, rec, ftrace_addr);
Steven Rostedt5072c592008-05-12 21:20:43 +02001097}
1098
1099static void ftrace_replace_code(int enable)
1100{
Steven Rostedt37ad5082008-05-12 21:20:48 +02001101 struct dyn_ftrace *rec;
1102 struct ftrace_page *pg;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001103 int failed;
Steven Rostedt37ad5082008-05-12 21:20:48 +02001104
Steven Rostedt265c8312009-02-13 12:43:56 -05001105 do_for_each_ftrace_rec(pg, rec) {
1106 /*
Zhaoleifa9d13c2009-03-13 17:16:34 +08001107 * Skip over free records, records that have
1108 * failed and not converted.
Steven Rostedt265c8312009-02-13 12:43:56 -05001109 */
1110 if (rec->flags & FTRACE_FL_FREE ||
Zhaoleifa9d13c2009-03-13 17:16:34 +08001111 rec->flags & FTRACE_FL_FAILED ||
Frederic Weisbecker03303542009-03-16 22:41:00 +01001112 !(rec->flags & FTRACE_FL_CONVERTED))
Steven Rostedt265c8312009-02-13 12:43:56 -05001113 continue;
Steven Rostedt5072c592008-05-12 21:20:43 +02001114
Steven Rostedt265c8312009-02-13 12:43:56 -05001115 /* ignore updates to this record's mcount site */
1116 if (get_kprobe((void *)rec->ip)) {
1117 freeze_record(rec);
1118 continue;
1119 } else {
1120 unfreeze_record(rec);
Steven Rostedt5072c592008-05-12 21:20:43 +02001121 }
Steven Rostedt265c8312009-02-13 12:43:56 -05001122
1123 failed = __ftrace_replace_code(rec, enable);
Zhaoleifa9d13c2009-03-13 17:16:34 +08001124 if (failed) {
Steven Rostedt265c8312009-02-13 12:43:56 -05001125 rec->flags |= FTRACE_FL_FAILED;
1126 if ((system_state == SYSTEM_BOOTING) ||
1127 !core_kernel_text(rec->ip)) {
1128 ftrace_free_rec(rec);
Steven Rostedt43772452009-02-19 13:41:27 -05001129 } else {
Steven Rostedt265c8312009-02-13 12:43:56 -05001130 ftrace_bug(failed, rec->ip);
Steven Rostedt43772452009-02-19 13:41:27 -05001131 /* Stop processing */
1132 return;
1133 }
Steven Rostedt265c8312009-02-13 12:43:56 -05001134 }
1135 } while_for_each_ftrace_rec();
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001136}
1137
Ingo Molnare309b412008-05-12 21:20:51 +02001138static int
Steven Rostedt31e88902008-11-14 16:21:19 -08001139ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001140{
1141 unsigned long ip;
Steven Rostedt593eb8a2008-10-23 09:32:59 -04001142 int ret;
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001143
1144 ip = rec->ip;
1145
Shaohua Li25aac9d2009-01-09 11:29:40 +08001146 ret = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
Steven Rostedt593eb8a2008-10-23 09:32:59 -04001147 if (ret) {
Steven Rostedt31e88902008-11-14 16:21:19 -08001148 ftrace_bug(ret, ip);
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001149 rec->flags |= FTRACE_FL_FAILED;
Abhishek Sagar492a7ea2008-05-25 00:10:04 +05301150 return 0;
Steven Rostedt37ad5082008-05-12 21:20:48 +02001151 }
Abhishek Sagar492a7ea2008-05-25 00:10:04 +05301152 return 1;
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001153}
1154
Steven Rostedt000ab692009-02-17 13:35:06 -05001155/*
1156 * archs can override this function if they must do something
1157 * before the modifying code is performed.
1158 */
1159int __weak ftrace_arch_code_modify_prepare(void)
1160{
1161 return 0;
1162}
1163
1164/*
1165 * archs can override this function if they must do something
1166 * after the modifying code is performed.
1167 */
1168int __weak ftrace_arch_code_modify_post_process(void)
1169{
1170 return 0;
1171}
1172
Ingo Molnare309b412008-05-12 21:20:51 +02001173static int __ftrace_modify_code(void *data)
Steven Rostedt3d083392008-05-12 21:20:42 +02001174{
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001175 int *command = data;
1176
Steven Rostedta3583242008-11-11 15:01:42 -05001177 if (*command & FTRACE_ENABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001178 ftrace_replace_code(1);
Steven Rostedta3583242008-11-11 15:01:42 -05001179 else if (*command & FTRACE_DISABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001180 ftrace_replace_code(0);
1181
1182 if (*command & FTRACE_UPDATE_TRACE_FUNC)
1183 ftrace_update_ftrace_func(ftrace_trace_function);
1184
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05001185 if (*command & FTRACE_START_FUNC_RET)
1186 ftrace_enable_ftrace_graph_caller();
1187 else if (*command & FTRACE_STOP_FUNC_RET)
1188 ftrace_disable_ftrace_graph_caller();
1189
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001190 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +02001191}
1192
Ingo Molnare309b412008-05-12 21:20:51 +02001193static void ftrace_run_update_code(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +02001194{
Steven Rostedt000ab692009-02-17 13:35:06 -05001195 int ret;
1196
1197 ret = ftrace_arch_code_modify_prepare();
1198 FTRACE_WARN_ON(ret);
1199 if (ret)
1200 return;
1201
Rusty Russell784e2d72008-07-28 12:16:31 -05001202 stop_machine(__ftrace_modify_code, &command, NULL);
Steven Rostedt000ab692009-02-17 13:35:06 -05001203
1204 ret = ftrace_arch_code_modify_post_process();
1205 FTRACE_WARN_ON(ret);
Steven Rostedt3d083392008-05-12 21:20:42 +02001206}
1207
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001208static ftrace_func_t saved_ftrace_func;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -05001209static int ftrace_start_up;
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001210
1211static void ftrace_startup_enable(int command)
1212{
1213 if (saved_ftrace_func != ftrace_trace_function) {
1214 saved_ftrace_func = ftrace_trace_function;
1215 command |= FTRACE_UPDATE_TRACE_FUNC;
1216 }
1217
1218 if (!command || !ftrace_enabled)
1219 return;
1220
1221 ftrace_run_update_code(command);
1222}
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001223
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05001224static void ftrace_startup(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +02001225{
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001226 if (unlikely(ftrace_disabled))
1227 return;
1228
Steven Rostedt60a7ecf2008-11-05 16:05:44 -05001229 ftrace_start_up++;
Steven Rostedt982c3502008-11-15 16:31:41 -05001230 command |= FTRACE_ENABLE_CALLS;
Steven Rostedt3d083392008-05-12 21:20:42 +02001231
Steven Rostedtdf4fc312008-11-26 00:16:23 -05001232 ftrace_startup_enable(command);
Steven Rostedt3d083392008-05-12 21:20:42 +02001233}
1234
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05001235static void ftrace_shutdown(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +02001236{
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001237 if (unlikely(ftrace_disabled))
1238 return;
1239
Steven Rostedt60a7ecf2008-11-05 16:05:44 -05001240 ftrace_start_up--;
1241 if (!ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001242 command |= FTRACE_DISABLE_CALLS;
1243
1244 if (saved_ftrace_func != ftrace_trace_function) {
1245 saved_ftrace_func = ftrace_trace_function;
1246 command |= FTRACE_UPDATE_TRACE_FUNC;
1247 }
1248
1249 if (!command || !ftrace_enabled)
Steven Rostedte6ea44e2009-02-14 01:42:44 -05001250 return;
Steven Rostedt3d083392008-05-12 21:20:42 +02001251
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001252 ftrace_run_update_code(command);
Steven Rostedt3d083392008-05-12 21:20:42 +02001253}
1254
Ingo Molnare309b412008-05-12 21:20:51 +02001255static void ftrace_startup_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001256{
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001257 int command = FTRACE_ENABLE_MCOUNT;
1258
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001259 if (unlikely(ftrace_disabled))
1260 return;
1261
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001262 /* Force update next time */
1263 saved_ftrace_func = NULL;
Steven Rostedt60a7ecf2008-11-05 16:05:44 -05001264 /* ftrace_start_up is true if we want ftrace running */
1265 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001266 command |= FTRACE_ENABLE_CALLS;
1267
1268 ftrace_run_update_code(command);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001269}
1270
Ingo Molnare309b412008-05-12 21:20:51 +02001271static void ftrace_shutdown_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001272{
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001273 int command = FTRACE_DISABLE_MCOUNT;
1274
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001275 if (unlikely(ftrace_disabled))
1276 return;
1277
Steven Rostedt60a7ecf2008-11-05 16:05:44 -05001278 /* ftrace_start_up is true if ftrace is running */
1279 if (ftrace_start_up)
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001280 command |= FTRACE_DISABLE_CALLS;
1281
1282 ftrace_run_update_code(command);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001283}
1284
Steven Rostedt3d083392008-05-12 21:20:42 +02001285static cycle_t ftrace_update_time;
1286static unsigned long ftrace_update_cnt;
1287unsigned long ftrace_update_tot_cnt;
1288
Steven Rostedt31e88902008-11-14 16:21:19 -08001289static int ftrace_update_code(struct module *mod)
Steven Rostedt3d083392008-05-12 21:20:42 +02001290{
Lai Jiangshane94142a2009-03-13 17:51:27 +08001291 struct dyn_ftrace *p;
Abhishek Sagarf22f9a82008-06-21 23:50:29 +05301292 cycle_t start, stop;
Steven Rostedt3d083392008-05-12 21:20:42 +02001293
Ingo Molnar750ed1a2008-05-12 21:20:46 +02001294 start = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +02001295 ftrace_update_cnt = 0;
1296
Lai Jiangshane94142a2009-03-13 17:51:27 +08001297 while (ftrace_new_addrs) {
Abhishek Sagarf22f9a82008-06-21 23:50:29 +05301298
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001299 /* If something went wrong, bail without enabling anything */
1300 if (unlikely(ftrace_disabled))
1301 return -1;
Steven Rostedt3d083392008-05-12 21:20:42 +02001302
Lai Jiangshane94142a2009-03-13 17:51:27 +08001303 p = ftrace_new_addrs;
Lai Jiangshanee000b72009-03-24 13:38:06 +08001304 ftrace_new_addrs = p->newlist;
Lai Jiangshane94142a2009-03-13 17:51:27 +08001305 p->flags = 0L;
Abhishek Sagar0eb96702008-06-01 21:47:30 +05301306
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001307 /* convert record (i.e, patch mcount-call with NOP) */
Steven Rostedt31e88902008-11-14 16:21:19 -08001308 if (ftrace_code_disable(mod, p)) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001309 p->flags |= FTRACE_FL_CONVERTED;
1310 ftrace_update_cnt++;
1311 } else
1312 ftrace_free_rec(p);
Steven Rostedt3d083392008-05-12 21:20:42 +02001313 }
1314
Ingo Molnar750ed1a2008-05-12 21:20:46 +02001315 stop = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +02001316 ftrace_update_time = stop - start;
1317 ftrace_update_tot_cnt += ftrace_update_cnt;
1318
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02001319 return 0;
1320}
1321
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001322static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001323{
1324 struct ftrace_page *pg;
1325 int cnt;
1326 int i;
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001327
1328 /* allocate a few pages */
1329 ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
1330 if (!ftrace_pages_start)
1331 return -1;
1332
1333 /*
1334 * Allocate a few more pages.
1335 *
1336 * TODO: have some parser search vmlinux before
1337 * final linking to find all calls to ftrace.
1338 * Then we can:
1339 * a) know how many pages to allocate.
1340 * and/or
1341 * b) set up the table then.
1342 *
1343 * The dynamic code is still necessary for
1344 * modules.
1345 */
1346
1347 pg = ftrace_pages = ftrace_pages_start;
1348
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001349 cnt = num_to_init / ENTRIES_PER_PAGE;
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001350 pr_info("ftrace: allocating %ld entries in %d pages\n",
walimis5821e1b2008-11-15 15:19:06 +08001351 num_to_init, cnt + 1);
Steven Rostedt3c1720f2008-05-12 21:20:43 +02001352
1353 for (i = 0; i < cnt; i++) {
1354 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
1355
1356 /* If we fail, we'll try later anyway */
1357 if (!pg->next)
1358 break;
1359
1360 pg = pg->next;
1361 }
1362
1363 return 0;
1364}
1365
Steven Rostedt5072c592008-05-12 21:20:43 +02001366enum {
1367 FTRACE_ITER_FILTER = (1 << 0),
1368 FTRACE_ITER_CONT = (1 << 1),
Steven Rostedt41c52c02008-05-22 11:46:33 -04001369 FTRACE_ITER_NOTRACE = (1 << 2),
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301370 FTRACE_ITER_FAILURES = (1 << 3),
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001371 FTRACE_ITER_PRINTALL = (1 << 4),
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001372 FTRACE_ITER_HASH = (1 << 5),
Steven Rostedt5072c592008-05-12 21:20:43 +02001373};
1374
1375#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
1376
1377struct ftrace_iterator {
Steven Rostedt5072c592008-05-12 21:20:43 +02001378 struct ftrace_page *pg;
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001379 int hidx;
Steven Rostedt431aa3f2009-01-06 12:43:01 -05001380 int idx;
Steven Rostedt5072c592008-05-12 21:20:43 +02001381 unsigned flags;
1382 unsigned char buffer[FTRACE_BUFF_MAX+1];
1383 unsigned buffer_idx;
1384 unsigned filtered;
1385};
1386
Ingo Molnare309b412008-05-12 21:20:51 +02001387static void *
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001388t_hash_next(struct seq_file *m, void *v, loff_t *pos)
1389{
1390 struct ftrace_iterator *iter = m->private;
1391 struct hlist_node *hnd = v;
1392 struct hlist_head *hhd;
1393
1394 WARN_ON(!(iter->flags & FTRACE_ITER_HASH));
1395
1396 (*pos)++;
1397
1398 retry:
1399 if (iter->hidx >= FTRACE_FUNC_HASHSIZE)
1400 return NULL;
1401
1402 hhd = &ftrace_func_hash[iter->hidx];
1403
1404 if (hlist_empty(hhd)) {
1405 iter->hidx++;
1406 hnd = NULL;
1407 goto retry;
1408 }
1409
1410 if (!hnd)
1411 hnd = hhd->first;
1412 else {
1413 hnd = hnd->next;
1414 if (!hnd) {
1415 iter->hidx++;
1416 goto retry;
1417 }
1418 }
1419
1420 return hnd;
1421}
1422
1423static void *t_hash_start(struct seq_file *m, loff_t *pos)
1424{
1425 struct ftrace_iterator *iter = m->private;
1426 void *p = NULL;
1427
1428 iter->flags |= FTRACE_ITER_HASH;
1429
1430 return t_hash_next(m, p, pos);
1431}
1432
1433static int t_hash_show(struct seq_file *m, void *v)
1434{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001435 struct ftrace_func_probe *rec;
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001436 struct hlist_node *hnd = v;
1437 char str[KSYM_SYMBOL_LEN];
1438
Steven Rostedtb6887d72009-02-17 12:32:04 -05001439 rec = hlist_entry(hnd, struct ftrace_func_probe, node);
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001440
Steven Rostedt809dcf22009-02-16 23:06:01 -05001441 if (rec->ops->print)
1442 return rec->ops->print(m, rec->ip, rec->ops, rec->data);
1443
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001444 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1445 seq_printf(m, "%s:", str);
1446
1447 kallsyms_lookup((unsigned long)rec->ops->func, NULL, NULL, NULL, str);
1448 seq_printf(m, "%s", str);
1449
1450 if (rec->data)
1451 seq_printf(m, ":%p", rec->data);
1452 seq_putc(m, '\n');
1453
1454 return 0;
1455}
1456
1457static void *
Steven Rostedt5072c592008-05-12 21:20:43 +02001458t_next(struct seq_file *m, void *v, loff_t *pos)
1459{
1460 struct ftrace_iterator *iter = m->private;
1461 struct dyn_ftrace *rec = NULL;
1462
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001463 if (iter->flags & FTRACE_ITER_HASH)
1464 return t_hash_next(m, v, pos);
1465
Steven Rostedt5072c592008-05-12 21:20:43 +02001466 (*pos)++;
1467
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001468 if (iter->flags & FTRACE_ITER_PRINTALL)
1469 return NULL;
1470
Steven Rostedt5072c592008-05-12 21:20:43 +02001471 retry:
1472 if (iter->idx >= iter->pg->index) {
1473 if (iter->pg->next) {
1474 iter->pg = iter->pg->next;
1475 iter->idx = 0;
1476 goto retry;
Liming Wang50cdaf02008-11-28 12:13:21 +08001477 } else {
1478 iter->idx = -1;
Steven Rostedt5072c592008-05-12 21:20:43 +02001479 }
1480 } else {
1481 rec = &iter->pg->records[iter->idx++];
Steven Rostedta9fdda32008-08-14 22:47:17 -04001482 if ((rec->flags & FTRACE_FL_FREE) ||
1483
1484 (!(iter->flags & FTRACE_ITER_FAILURES) &&
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301485 (rec->flags & FTRACE_FL_FAILED)) ||
1486
1487 ((iter->flags & FTRACE_ITER_FAILURES) &&
Steven Rostedta9fdda32008-08-14 22:47:17 -04001488 !(rec->flags & FTRACE_FL_FAILED)) ||
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301489
Steven Rostedt0183fb12008-11-07 22:36:02 -05001490 ((iter->flags & FTRACE_ITER_FILTER) &&
1491 !(rec->flags & FTRACE_FL_FILTER)) ||
1492
Steven Rostedt41c52c02008-05-22 11:46:33 -04001493 ((iter->flags & FTRACE_ITER_NOTRACE) &&
1494 !(rec->flags & FTRACE_FL_NOTRACE))) {
Steven Rostedt5072c592008-05-12 21:20:43 +02001495 rec = NULL;
1496 goto retry;
1497 }
1498 }
1499
Steven Rostedt5072c592008-05-12 21:20:43 +02001500 return rec;
1501}
1502
1503static void *t_start(struct seq_file *m, loff_t *pos)
1504{
1505 struct ftrace_iterator *iter = m->private;
1506 void *p = NULL;
Steven Rostedt5072c592008-05-12 21:20:43 +02001507
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001508 mutex_lock(&ftrace_lock);
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001509 /*
1510 * For set_ftrace_filter reading, if we have the filter
1511 * off, we can short cut and just print out that all
1512 * functions are enabled.
1513 */
1514 if (iter->flags & FTRACE_ITER_FILTER && !ftrace_filtered) {
1515 if (*pos > 0)
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001516 return t_hash_start(m, pos);
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001517 iter->flags |= FTRACE_ITER_PRINTALL;
1518 (*pos)++;
1519 return iter;
1520 }
1521
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001522 if (iter->flags & FTRACE_ITER_HASH)
1523 return t_hash_start(m, pos);
1524
Liming Wang50cdaf02008-11-28 12:13:21 +08001525 if (*pos > 0) {
1526 if (iter->idx < 0)
1527 return p;
1528 (*pos)--;
1529 iter->idx--;
1530 }
walimis5821e1b2008-11-15 15:19:06 +08001531
Liming Wang50cdaf02008-11-28 12:13:21 +08001532 p = t_next(m, p, pos);
Steven Rostedt5072c592008-05-12 21:20:43 +02001533
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001534 if (!p)
1535 return t_hash_start(m, pos);
1536
Steven Rostedt5072c592008-05-12 21:20:43 +02001537 return p;
1538}
1539
1540static void t_stop(struct seq_file *m, void *p)
1541{
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001542 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001543}
1544
1545static int t_show(struct seq_file *m, void *v)
1546{
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001547 struct ftrace_iterator *iter = m->private;
Steven Rostedt5072c592008-05-12 21:20:43 +02001548 struct dyn_ftrace *rec = v;
1549 char str[KSYM_SYMBOL_LEN];
1550
Steven Rostedt8fc0c702009-02-16 15:28:00 -05001551 if (iter->flags & FTRACE_ITER_HASH)
1552 return t_hash_show(m, v);
1553
Steven Rostedt0c75a3e2009-02-16 11:21:52 -05001554 if (iter->flags & FTRACE_ITER_PRINTALL) {
1555 seq_printf(m, "#### all functions enabled ####\n");
1556 return 0;
1557 }
1558
Steven Rostedt5072c592008-05-12 21:20:43 +02001559 if (!rec)
1560 return 0;
1561
1562 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1563
Liming Wang50cdaf02008-11-28 12:13:21 +08001564 seq_printf(m, "%s\n", str);
Steven Rostedt5072c592008-05-12 21:20:43 +02001565
1566 return 0;
1567}
1568
1569static struct seq_operations show_ftrace_seq_ops = {
1570 .start = t_start,
1571 .next = t_next,
1572 .stop = t_stop,
1573 .show = t_show,
1574};
1575
Ingo Molnare309b412008-05-12 21:20:51 +02001576static int
Steven Rostedt5072c592008-05-12 21:20:43 +02001577ftrace_avail_open(struct inode *inode, struct file *file)
1578{
1579 struct ftrace_iterator *iter;
1580 int ret;
1581
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001582 if (unlikely(ftrace_disabled))
1583 return -ENODEV;
1584
Steven Rostedt5072c592008-05-12 21:20:43 +02001585 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
1586 if (!iter)
1587 return -ENOMEM;
1588
1589 iter->pg = ftrace_pages_start;
Steven Rostedt5072c592008-05-12 21:20:43 +02001590
1591 ret = seq_open(file, &show_ftrace_seq_ops);
1592 if (!ret) {
1593 struct seq_file *m = file->private_data;
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001594
Steven Rostedt5072c592008-05-12 21:20:43 +02001595 m->private = iter;
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001596 } else {
Steven Rostedt5072c592008-05-12 21:20:43 +02001597 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001598 }
Steven Rostedt5072c592008-05-12 21:20:43 +02001599
1600 return ret;
1601}
1602
1603int ftrace_avail_release(struct inode *inode, struct file *file)
1604{
1605 struct seq_file *m = (struct seq_file *)file->private_data;
1606 struct ftrace_iterator *iter = m->private;
1607
1608 seq_release(inode, file);
1609 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +02001610
Steven Rostedt5072c592008-05-12 21:20:43 +02001611 return 0;
1612}
1613
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301614static int
1615ftrace_failures_open(struct inode *inode, struct file *file)
1616{
1617 int ret;
1618 struct seq_file *m;
1619 struct ftrace_iterator *iter;
1620
1621 ret = ftrace_avail_open(inode, file);
1622 if (!ret) {
1623 m = (struct seq_file *)file->private_data;
1624 iter = (struct ftrace_iterator *)m->private;
1625 iter->flags = FTRACE_ITER_FAILURES;
1626 }
1627
1628 return ret;
1629}
1630
1631
Steven Rostedt41c52c02008-05-22 11:46:33 -04001632static void ftrace_filter_reset(int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001633{
1634 struct ftrace_page *pg;
1635 struct dyn_ftrace *rec;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001636 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +02001637
Steven Rostedt52baf112009-02-14 01:15:39 -05001638 mutex_lock(&ftrace_lock);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001639 if (enable)
1640 ftrace_filtered = 0;
Steven Rostedt265c8312009-02-13 12:43:56 -05001641 do_for_each_ftrace_rec(pg, rec) {
1642 if (rec->flags & FTRACE_FL_FAILED)
1643 continue;
1644 rec->flags &= ~type;
1645 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001646 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001647}
1648
Ingo Molnare309b412008-05-12 21:20:51 +02001649static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04001650ftrace_regex_open(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001651{
1652 struct ftrace_iterator *iter;
1653 int ret = 0;
1654
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001655 if (unlikely(ftrace_disabled))
1656 return -ENODEV;
1657
Steven Rostedt5072c592008-05-12 21:20:43 +02001658 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
1659 if (!iter)
1660 return -ENOMEM;
1661
Steven Rostedt41c52c02008-05-22 11:46:33 -04001662 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001663 if ((file->f_mode & FMODE_WRITE) &&
1664 !(file->f_flags & O_APPEND))
Steven Rostedt41c52c02008-05-22 11:46:33 -04001665 ftrace_filter_reset(enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001666
1667 if (file->f_mode & FMODE_READ) {
1668 iter->pg = ftrace_pages_start;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001669 iter->flags = enable ? FTRACE_ITER_FILTER :
1670 FTRACE_ITER_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +02001671
1672 ret = seq_open(file, &show_ftrace_seq_ops);
1673 if (!ret) {
1674 struct seq_file *m = file->private_data;
1675 m->private = iter;
1676 } else
1677 kfree(iter);
1678 } else
1679 file->private_data = iter;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001680 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001681
1682 return ret;
1683}
1684
Steven Rostedt41c52c02008-05-22 11:46:33 -04001685static int
1686ftrace_filter_open(struct inode *inode, struct file *file)
1687{
1688 return ftrace_regex_open(inode, file, 1);
1689}
1690
1691static int
1692ftrace_notrace_open(struct inode *inode, struct file *file)
1693{
1694 return ftrace_regex_open(inode, file, 0);
1695}
1696
Ingo Molnare309b412008-05-12 21:20:51 +02001697static loff_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001698ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
Steven Rostedt5072c592008-05-12 21:20:43 +02001699{
1700 loff_t ret;
1701
1702 if (file->f_mode & FMODE_READ)
1703 ret = seq_lseek(file, offset, origin);
1704 else
1705 file->f_pos = ret = 1;
1706
1707 return ret;
1708}
1709
1710enum {
1711 MATCH_FULL,
1712 MATCH_FRONT_ONLY,
1713 MATCH_MIDDLE_ONLY,
1714 MATCH_END_ONLY,
1715};
1716
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001717/*
1718 * (static function - no need for kernel doc)
1719 *
1720 * Pass in a buffer containing a glob and this function will
1721 * set search to point to the search part of the buffer and
1722 * return the type of search it is (see enum above).
1723 * This does modify buff.
1724 *
1725 * Returns enum type.
1726 * search returns the pointer to use for comparison.
1727 * not returns 1 if buff started with a '!'
1728 * 0 otherwise.
1729 */
1730static int
Steven Rostedt64e7c442009-02-13 17:08:48 -05001731ftrace_setup_glob(char *buff, int len, char **search, int *not)
Steven Rostedt5072c592008-05-12 21:20:43 +02001732{
Steven Rostedt5072c592008-05-12 21:20:43 +02001733 int type = MATCH_FULL;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001734 int i;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001735
1736 if (buff[0] == '!') {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001737 *not = 1;
Steven Rostedtea3a6d62008-12-17 15:05:36 -05001738 buff++;
1739 len--;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001740 } else
1741 *not = 0;
1742
1743 *search = buff;
Steven Rostedt5072c592008-05-12 21:20:43 +02001744
1745 for (i = 0; i < len; i++) {
1746 if (buff[i] == '*') {
1747 if (!i) {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001748 *search = buff + 1;
Steven Rostedt5072c592008-05-12 21:20:43 +02001749 type = MATCH_END_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001750 } else {
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001751 if (type == MATCH_END_ONLY)
Steven Rostedt5072c592008-05-12 21:20:43 +02001752 type = MATCH_MIDDLE_ONLY;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001753 else
Steven Rostedt5072c592008-05-12 21:20:43 +02001754 type = MATCH_FRONT_ONLY;
Steven Rostedt5072c592008-05-12 21:20:43 +02001755 buff[i] = 0;
1756 break;
1757 }
1758 }
1759 }
1760
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001761 return type;
1762}
1763
Steven Rostedt64e7c442009-02-13 17:08:48 -05001764static int ftrace_match(char *str, char *regex, int len, int type)
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001765{
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001766 int matched = 0;
1767 char *ptr;
1768
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001769 switch (type) {
1770 case MATCH_FULL:
1771 if (strcmp(str, regex) == 0)
1772 matched = 1;
1773 break;
1774 case MATCH_FRONT_ONLY:
1775 if (strncmp(str, regex, len) == 0)
1776 matched = 1;
1777 break;
1778 case MATCH_MIDDLE_ONLY:
1779 if (strstr(str, regex))
1780 matched = 1;
1781 break;
1782 case MATCH_END_ONLY:
1783 ptr = strstr(str, regex);
1784 if (ptr && (ptr[len] == 0))
1785 matched = 1;
1786 break;
1787 }
1788
1789 return matched;
1790}
1791
Steven Rostedt64e7c442009-02-13 17:08:48 -05001792static int
1793ftrace_match_record(struct dyn_ftrace *rec, char *regex, int len, int type)
1794{
1795 char str[KSYM_SYMBOL_LEN];
1796
1797 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
1798 return ftrace_match(str, regex, len, type);
1799}
1800
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001801static void ftrace_match_records(char *buff, int len, int enable)
1802{
Steven Rostedt6a24a242009-02-17 11:20:26 -05001803 unsigned int search_len;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001804 struct ftrace_page *pg;
1805 struct dyn_ftrace *rec;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001806 unsigned long flag;
1807 char *search;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001808 int type;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001809 int not;
1810
Steven Rostedt6a24a242009-02-17 11:20:26 -05001811 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001812 type = ftrace_setup_glob(buff, len, &search, &not);
1813
1814 search_len = strlen(search);
1815
Steven Rostedt52baf112009-02-14 01:15:39 -05001816 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05001817 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedt5072c592008-05-12 21:20:43 +02001818
Steven Rostedt265c8312009-02-13 12:43:56 -05001819 if (rec->flags & FTRACE_FL_FAILED)
1820 continue;
Steven Rostedt9f4801e2009-02-13 15:56:43 -05001821
1822 if (ftrace_match_record(rec, search, search_len, type)) {
Steven Rostedt265c8312009-02-13 12:43:56 -05001823 if (not)
1824 rec->flags &= ~flag;
1825 else
1826 rec->flags |= flag;
1827 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001828 /*
1829 * Only enable filtering if we have a function that
1830 * is filtered on.
1831 */
1832 if (enable && (rec->flags & FTRACE_FL_FILTER))
1833 ftrace_filtered = 1;
Steven Rostedt265c8312009-02-13 12:43:56 -05001834 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001835 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001836}
1837
Steven Rostedt64e7c442009-02-13 17:08:48 -05001838static int
1839ftrace_match_module_record(struct dyn_ftrace *rec, char *mod,
1840 char *regex, int len, int type)
1841{
1842 char str[KSYM_SYMBOL_LEN];
1843 char *modname;
1844
1845 kallsyms_lookup(rec->ip, NULL, NULL, &modname, str);
1846
1847 if (!modname || strcmp(modname, mod))
1848 return 0;
1849
1850 /* blank search means to match all funcs in the mod */
1851 if (len)
1852 return ftrace_match(str, regex, len, type);
1853 else
1854 return 1;
1855}
1856
1857static void ftrace_match_module_records(char *buff, char *mod, int enable)
1858{
Steven Rostedt6a24a242009-02-17 11:20:26 -05001859 unsigned search_len = 0;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001860 struct ftrace_page *pg;
1861 struct dyn_ftrace *rec;
1862 int type = MATCH_FULL;
Steven Rostedt6a24a242009-02-17 11:20:26 -05001863 char *search = buff;
1864 unsigned long flag;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001865 int not = 0;
1866
Steven Rostedt6a24a242009-02-17 11:20:26 -05001867 flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
1868
Steven Rostedt64e7c442009-02-13 17:08:48 -05001869 /* blank or '*' mean the same */
1870 if (strcmp(buff, "*") == 0)
1871 buff[0] = 0;
1872
1873 /* handle the case of 'dont filter this module' */
1874 if (strcmp(buff, "!") == 0 || strcmp(buff, "!*") == 0) {
1875 buff[0] = 0;
1876 not = 1;
1877 }
1878
1879 if (strlen(buff)) {
1880 type = ftrace_setup_glob(buff, strlen(buff), &search, &not);
1881 search_len = strlen(search);
1882 }
1883
Steven Rostedt52baf112009-02-14 01:15:39 -05001884 mutex_lock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001885 do_for_each_ftrace_rec(pg, rec) {
1886
1887 if (rec->flags & FTRACE_FL_FAILED)
1888 continue;
1889
1890 if (ftrace_match_module_record(rec, mod,
1891 search, search_len, type)) {
1892 if (not)
1893 rec->flags &= ~flag;
1894 else
1895 rec->flags |= flag;
1896 }
Steven Rostedte68746a2009-02-13 20:53:42 -05001897 if (enable && (rec->flags & FTRACE_FL_FILTER))
1898 ftrace_filtered = 1;
Steven Rostedt64e7c442009-02-13 17:08:48 -05001899
1900 } while_for_each_ftrace_rec();
Steven Rostedt52baf112009-02-14 01:15:39 -05001901 mutex_unlock(&ftrace_lock);
Steven Rostedt64e7c442009-02-13 17:08:48 -05001902}
1903
Steven Rostedtf6180772009-02-14 00:40:25 -05001904/*
1905 * We register the module command as a template to show others how
1906 * to register the a command as well.
1907 */
1908
1909static int
1910ftrace_mod_callback(char *func, char *cmd, char *param, int enable)
1911{
1912 char *mod;
1913
1914 /*
1915 * cmd == 'mod' because we only registered this func
1916 * for the 'mod' ftrace_func_command.
1917 * But if you register one func with multiple commands,
1918 * you can tell which command was used by the cmd
1919 * parameter.
1920 */
1921
1922 /* we must have a module name */
1923 if (!param)
1924 return -EINVAL;
1925
1926 mod = strsep(&param, ":");
1927 if (!strlen(mod))
1928 return -EINVAL;
1929
1930 ftrace_match_module_records(func, mod, enable);
1931 return 0;
1932}
1933
1934static struct ftrace_func_command ftrace_mod_cmd = {
1935 .name = "mod",
1936 .func = ftrace_mod_callback,
1937};
1938
1939static int __init ftrace_mod_cmd_init(void)
1940{
1941 return register_ftrace_command(&ftrace_mod_cmd);
1942}
1943device_initcall(ftrace_mod_cmd_init);
1944
Steven Rostedt59df055f2009-02-14 15:29:06 -05001945static void
Steven Rostedtb6887d72009-02-17 12:32:04 -05001946function_trace_probe_call(unsigned long ip, unsigned long parent_ip)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001947{
Steven Rostedtb6887d72009-02-17 12:32:04 -05001948 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001949 struct hlist_head *hhd;
1950 struct hlist_node *n;
1951 unsigned long key;
1952 int resched;
1953
1954 key = hash_long(ip, FTRACE_HASH_BITS);
1955
1956 hhd = &ftrace_func_hash[key];
1957
1958 if (hlist_empty(hhd))
1959 return;
1960
1961 /*
1962 * Disable preemption for these calls to prevent a RCU grace
1963 * period. This syncs the hash iteration and freeing of items
1964 * on the hash. rcu_read_lock is too dangerous here.
1965 */
1966 resched = ftrace_preempt_disable();
1967 hlist_for_each_entry_rcu(entry, n, hhd, node) {
1968 if (entry->ip == ip)
1969 entry->ops->func(ip, parent_ip, &entry->data);
1970 }
1971 ftrace_preempt_enable(resched);
1972}
1973
Steven Rostedtb6887d72009-02-17 12:32:04 -05001974static struct ftrace_ops trace_probe_ops __read_mostly =
Steven Rostedt59df055f2009-02-14 15:29:06 -05001975{
Steven Rostedtfb9fb012009-03-25 13:26:41 -04001976 .func = function_trace_probe_call,
Steven Rostedt59df055f2009-02-14 15:29:06 -05001977};
1978
Steven Rostedtb6887d72009-02-17 12:32:04 -05001979static int ftrace_probe_registered;
Steven Rostedt59df055f2009-02-14 15:29:06 -05001980
Steven Rostedtb6887d72009-02-17 12:32:04 -05001981static void __enable_ftrace_function_probe(void)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001982{
1983 int i;
1984
Steven Rostedtb6887d72009-02-17 12:32:04 -05001985 if (ftrace_probe_registered)
Steven Rostedt59df055f2009-02-14 15:29:06 -05001986 return;
1987
1988 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
1989 struct hlist_head *hhd = &ftrace_func_hash[i];
1990 if (hhd->first)
1991 break;
1992 }
1993 /* Nothing registered? */
1994 if (i == FTRACE_FUNC_HASHSIZE)
1995 return;
1996
Steven Rostedtb6887d72009-02-17 12:32:04 -05001997 __register_ftrace_function(&trace_probe_ops);
Steven Rostedt59df055f2009-02-14 15:29:06 -05001998 ftrace_startup(0);
Steven Rostedtb6887d72009-02-17 12:32:04 -05001999 ftrace_probe_registered = 1;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002000}
2001
Steven Rostedtb6887d72009-02-17 12:32:04 -05002002static void __disable_ftrace_function_probe(void)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002003{
2004 int i;
2005
Steven Rostedtb6887d72009-02-17 12:32:04 -05002006 if (!ftrace_probe_registered)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002007 return;
2008
2009 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
2010 struct hlist_head *hhd = &ftrace_func_hash[i];
2011 if (hhd->first)
2012 return;
2013 }
2014
2015 /* no more funcs left */
Steven Rostedtb6887d72009-02-17 12:32:04 -05002016 __unregister_ftrace_function(&trace_probe_ops);
Steven Rostedt59df055f2009-02-14 15:29:06 -05002017 ftrace_shutdown(0);
Steven Rostedtb6887d72009-02-17 12:32:04 -05002018 ftrace_probe_registered = 0;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002019}
2020
2021
2022static void ftrace_free_entry_rcu(struct rcu_head *rhp)
2023{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002024 struct ftrace_func_probe *entry =
2025 container_of(rhp, struct ftrace_func_probe, rcu);
Steven Rostedt59df055f2009-02-14 15:29:06 -05002026
2027 if (entry->ops->free)
2028 entry->ops->free(&entry->data);
2029 kfree(entry);
2030}
2031
2032
2033int
Steven Rostedtb6887d72009-02-17 12:32:04 -05002034register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05002035 void *data)
2036{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002037 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002038 struct ftrace_page *pg;
2039 struct dyn_ftrace *rec;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002040 int type, len, not;
Steven Rostedt6a24a242009-02-17 11:20:26 -05002041 unsigned long key;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002042 int count = 0;
2043 char *search;
2044
2045 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
2046 len = strlen(search);
2047
Steven Rostedtb6887d72009-02-17 12:32:04 -05002048 /* we do not support '!' for function probes */
Steven Rostedt59df055f2009-02-14 15:29:06 -05002049 if (WARN_ON(not))
2050 return -EINVAL;
2051
2052 mutex_lock(&ftrace_lock);
2053 do_for_each_ftrace_rec(pg, rec) {
2054
2055 if (rec->flags & FTRACE_FL_FAILED)
2056 continue;
2057
2058 if (!ftrace_match_record(rec, search, len, type))
2059 continue;
2060
2061 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
2062 if (!entry) {
Steven Rostedtb6887d72009-02-17 12:32:04 -05002063 /* If we did not process any, then return error */
Steven Rostedt59df055f2009-02-14 15:29:06 -05002064 if (!count)
2065 count = -ENOMEM;
2066 goto out_unlock;
2067 }
2068
2069 count++;
2070
2071 entry->data = data;
2072
2073 /*
2074 * The caller might want to do something special
2075 * for each function we find. We call the callback
2076 * to give the caller an opportunity to do so.
2077 */
2078 if (ops->callback) {
2079 if (ops->callback(rec->ip, &entry->data) < 0) {
2080 /* caller does not like this func */
2081 kfree(entry);
2082 continue;
2083 }
2084 }
2085
2086 entry->ops = ops;
2087 entry->ip = rec->ip;
2088
2089 key = hash_long(entry->ip, FTRACE_HASH_BITS);
2090 hlist_add_head_rcu(&entry->node, &ftrace_func_hash[key]);
2091
2092 } while_for_each_ftrace_rec();
Steven Rostedtb6887d72009-02-17 12:32:04 -05002093 __enable_ftrace_function_probe();
Steven Rostedt59df055f2009-02-14 15:29:06 -05002094
2095 out_unlock:
2096 mutex_unlock(&ftrace_lock);
2097
2098 return count;
2099}
2100
2101enum {
Steven Rostedtb6887d72009-02-17 12:32:04 -05002102 PROBE_TEST_FUNC = 1,
2103 PROBE_TEST_DATA = 2
Steven Rostedt59df055f2009-02-14 15:29:06 -05002104};
2105
2106static void
Steven Rostedtb6887d72009-02-17 12:32:04 -05002107__unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05002108 void *data, int flags)
2109{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002110 struct ftrace_func_probe *entry;
Steven Rostedt59df055f2009-02-14 15:29:06 -05002111 struct hlist_node *n, *tmp;
2112 char str[KSYM_SYMBOL_LEN];
2113 int type = MATCH_FULL;
2114 int i, len = 0;
2115 char *search;
2116
2117 if (glob && (strcmp(glob, "*") || !strlen(glob)))
2118 glob = NULL;
2119 else {
2120 int not;
2121
2122 type = ftrace_setup_glob(glob, strlen(glob), &search, &not);
2123 len = strlen(search);
2124
Steven Rostedtb6887d72009-02-17 12:32:04 -05002125 /* we do not support '!' for function probes */
Steven Rostedt59df055f2009-02-14 15:29:06 -05002126 if (WARN_ON(not))
2127 return;
2128 }
2129
2130 mutex_lock(&ftrace_lock);
2131 for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) {
2132 struct hlist_head *hhd = &ftrace_func_hash[i];
2133
2134 hlist_for_each_entry_safe(entry, n, tmp, hhd, node) {
2135
2136 /* break up if statements for readability */
Steven Rostedtb6887d72009-02-17 12:32:04 -05002137 if ((flags & PROBE_TEST_FUNC) && entry->ops != ops)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002138 continue;
2139
Steven Rostedtb6887d72009-02-17 12:32:04 -05002140 if ((flags & PROBE_TEST_DATA) && entry->data != data)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002141 continue;
2142
2143 /* do this last, since it is the most expensive */
2144 if (glob) {
2145 kallsyms_lookup(entry->ip, NULL, NULL,
2146 NULL, str);
2147 if (!ftrace_match(str, glob, len, type))
2148 continue;
2149 }
2150
2151 hlist_del(&entry->node);
2152 call_rcu(&entry->rcu, ftrace_free_entry_rcu);
2153 }
2154 }
Steven Rostedtb6887d72009-02-17 12:32:04 -05002155 __disable_ftrace_function_probe();
Steven Rostedt59df055f2009-02-14 15:29:06 -05002156 mutex_unlock(&ftrace_lock);
2157}
2158
2159void
Steven Rostedtb6887d72009-02-17 12:32:04 -05002160unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
Steven Rostedt59df055f2009-02-14 15:29:06 -05002161 void *data)
2162{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002163 __unregister_ftrace_function_probe(glob, ops, data,
2164 PROBE_TEST_FUNC | PROBE_TEST_DATA);
Steven Rostedt59df055f2009-02-14 15:29:06 -05002165}
2166
2167void
Steven Rostedtb6887d72009-02-17 12:32:04 -05002168unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002169{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002170 __unregister_ftrace_function_probe(glob, ops, NULL, PROBE_TEST_FUNC);
Steven Rostedt59df055f2009-02-14 15:29:06 -05002171}
2172
Steven Rostedtb6887d72009-02-17 12:32:04 -05002173void unregister_ftrace_function_probe_all(char *glob)
Steven Rostedt59df055f2009-02-14 15:29:06 -05002174{
Steven Rostedtb6887d72009-02-17 12:32:04 -05002175 __unregister_ftrace_function_probe(glob, NULL, NULL, 0);
Steven Rostedt59df055f2009-02-14 15:29:06 -05002176}
2177
Steven Rostedtf6180772009-02-14 00:40:25 -05002178static LIST_HEAD(ftrace_commands);
2179static DEFINE_MUTEX(ftrace_cmd_mutex);
2180
2181int register_ftrace_command(struct ftrace_func_command *cmd)
2182{
2183 struct ftrace_func_command *p;
2184 int ret = 0;
2185
2186 mutex_lock(&ftrace_cmd_mutex);
2187 list_for_each_entry(p, &ftrace_commands, list) {
2188 if (strcmp(cmd->name, p->name) == 0) {
2189 ret = -EBUSY;
2190 goto out_unlock;
2191 }
2192 }
2193 list_add(&cmd->list, &ftrace_commands);
2194 out_unlock:
2195 mutex_unlock(&ftrace_cmd_mutex);
2196
2197 return ret;
2198}
2199
2200int unregister_ftrace_command(struct ftrace_func_command *cmd)
2201{
2202 struct ftrace_func_command *p, *n;
2203 int ret = -ENODEV;
2204
2205 mutex_lock(&ftrace_cmd_mutex);
2206 list_for_each_entry_safe(p, n, &ftrace_commands, list) {
2207 if (strcmp(cmd->name, p->name) == 0) {
2208 ret = 0;
2209 list_del_init(&p->list);
2210 goto out_unlock;
2211 }
2212 }
2213 out_unlock:
2214 mutex_unlock(&ftrace_cmd_mutex);
2215
2216 return ret;
2217}
2218
Steven Rostedt64e7c442009-02-13 17:08:48 -05002219static int ftrace_process_regex(char *buff, int len, int enable)
2220{
Steven Rostedtf6180772009-02-14 00:40:25 -05002221 char *func, *command, *next = buff;
Steven Rostedt6a24a242009-02-17 11:20:26 -05002222 struct ftrace_func_command *p;
Steven Rostedtf6180772009-02-14 00:40:25 -05002223 int ret = -EINVAL;
Steven Rostedt64e7c442009-02-13 17:08:48 -05002224
2225 func = strsep(&next, ":");
2226
2227 if (!next) {
2228 ftrace_match_records(func, len, enable);
2229 return 0;
2230 }
2231
Steven Rostedtf6180772009-02-14 00:40:25 -05002232 /* command found */
Steven Rostedt64e7c442009-02-13 17:08:48 -05002233
2234 command = strsep(&next, ":");
2235
Steven Rostedtf6180772009-02-14 00:40:25 -05002236 mutex_lock(&ftrace_cmd_mutex);
2237 list_for_each_entry(p, &ftrace_commands, list) {
2238 if (strcmp(p->name, command) == 0) {
2239 ret = p->func(func, command, next, enable);
2240 goto out_unlock;
2241 }
Steven Rostedt64e7c442009-02-13 17:08:48 -05002242 }
Steven Rostedtf6180772009-02-14 00:40:25 -05002243 out_unlock:
2244 mutex_unlock(&ftrace_cmd_mutex);
Steven Rostedt64e7c442009-02-13 17:08:48 -05002245
Steven Rostedtf6180772009-02-14 00:40:25 -05002246 return ret;
Steven Rostedt64e7c442009-02-13 17:08:48 -05002247}
2248
Ingo Molnare309b412008-05-12 21:20:51 +02002249static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04002250ftrace_regex_write(struct file *file, const char __user *ubuf,
2251 size_t cnt, loff_t *ppos, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02002252{
2253 struct ftrace_iterator *iter;
2254 char ch;
2255 size_t read = 0;
2256 ssize_t ret;
2257
2258 if (!cnt || cnt < 0)
2259 return 0;
2260
Steven Rostedt41c52c02008-05-22 11:46:33 -04002261 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02002262
2263 if (file->f_mode & FMODE_READ) {
2264 struct seq_file *m = file->private_data;
2265 iter = m->private;
2266 } else
2267 iter = file->private_data;
2268
2269 if (!*ppos) {
2270 iter->flags &= ~FTRACE_ITER_CONT;
2271 iter->buffer_idx = 0;
2272 }
2273
2274 ret = get_user(ch, ubuf++);
2275 if (ret)
2276 goto out;
2277 read++;
2278 cnt--;
2279
2280 if (!(iter->flags & ~FTRACE_ITER_CONT)) {
2281 /* skip white space */
2282 while (cnt && isspace(ch)) {
2283 ret = get_user(ch, ubuf++);
2284 if (ret)
2285 goto out;
2286 read++;
2287 cnt--;
2288 }
2289
Steven Rostedt5072c592008-05-12 21:20:43 +02002290 if (isspace(ch)) {
2291 file->f_pos += read;
2292 ret = read;
2293 goto out;
2294 }
2295
2296 iter->buffer_idx = 0;
2297 }
2298
2299 while (cnt && !isspace(ch)) {
2300 if (iter->buffer_idx < FTRACE_BUFF_MAX)
2301 iter->buffer[iter->buffer_idx++] = ch;
2302 else {
2303 ret = -EINVAL;
2304 goto out;
2305 }
2306 ret = get_user(ch, ubuf++);
2307 if (ret)
2308 goto out;
2309 read++;
2310 cnt--;
2311 }
2312
2313 if (isspace(ch)) {
2314 iter->filtered++;
2315 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt64e7c442009-02-13 17:08:48 -05002316 ret = ftrace_process_regex(iter->buffer,
2317 iter->buffer_idx, enable);
2318 if (ret)
2319 goto out;
Steven Rostedt5072c592008-05-12 21:20:43 +02002320 iter->buffer_idx = 0;
2321 } else
2322 iter->flags |= FTRACE_ITER_CONT;
2323
2324
2325 file->f_pos += read;
2326
2327 ret = read;
2328 out:
Steven Rostedt41c52c02008-05-22 11:46:33 -04002329 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02002330
2331 return ret;
2332}
2333
Steven Rostedt41c52c02008-05-22 11:46:33 -04002334static ssize_t
2335ftrace_filter_write(struct file *file, const char __user *ubuf,
2336 size_t cnt, loff_t *ppos)
2337{
2338 return ftrace_regex_write(file, ubuf, cnt, ppos, 1);
2339}
2340
2341static ssize_t
2342ftrace_notrace_write(struct file *file, const char __user *ubuf,
2343 size_t cnt, loff_t *ppos)
2344{
2345 return ftrace_regex_write(file, ubuf, cnt, ppos, 0);
2346}
2347
2348static void
2349ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
2350{
2351 if (unlikely(ftrace_disabled))
2352 return;
2353
2354 mutex_lock(&ftrace_regex_lock);
2355 if (reset)
2356 ftrace_filter_reset(enable);
2357 if (buf)
Steven Rostedt7f24b312009-02-13 14:37:33 -05002358 ftrace_match_records(buf, len, enable);
Steven Rostedt41c52c02008-05-22 11:46:33 -04002359 mutex_unlock(&ftrace_regex_lock);
2360}
2361
Steven Rostedt77a2b372008-05-12 21:20:45 +02002362/**
2363 * ftrace_set_filter - set a function to filter on in ftrace
2364 * @buf - the string that holds the function filter text.
2365 * @len - the length of the string.
2366 * @reset - non zero to reset all filters before applying this filter.
2367 *
2368 * Filters denote which functions should be enabled when tracing is enabled.
2369 * If @buf is NULL and reset is set, all functions will be enabled for tracing.
2370 */
Ingo Molnare309b412008-05-12 21:20:51 +02002371void ftrace_set_filter(unsigned char *buf, int len, int reset)
Steven Rostedt77a2b372008-05-12 21:20:45 +02002372{
Steven Rostedt41c52c02008-05-22 11:46:33 -04002373 ftrace_set_regex(buf, len, reset, 1);
2374}
Steven Rostedt4eebcc82008-05-12 21:20:48 +02002375
Steven Rostedt41c52c02008-05-22 11:46:33 -04002376/**
2377 * ftrace_set_notrace - set a function to not trace in ftrace
2378 * @buf - the string that holds the function notrace text.
2379 * @len - the length of the string.
2380 * @reset - non zero to reset all filters before applying this filter.
2381 *
2382 * Notrace Filters denote which functions should not be enabled when tracing
2383 * is enabled. If @buf is NULL and reset is set, all functions will be enabled
2384 * for tracing.
2385 */
2386void ftrace_set_notrace(unsigned char *buf, int len, int reset)
2387{
2388 ftrace_set_regex(buf, len, reset, 0);
Steven Rostedt77a2b372008-05-12 21:20:45 +02002389}
2390
Ingo Molnare309b412008-05-12 21:20:51 +02002391static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04002392ftrace_regex_release(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02002393{
2394 struct seq_file *m = (struct seq_file *)file->private_data;
2395 struct ftrace_iterator *iter;
2396
Steven Rostedt41c52c02008-05-22 11:46:33 -04002397 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02002398 if (file->f_mode & FMODE_READ) {
2399 iter = m->private;
2400
2401 seq_release(inode, file);
2402 } else
2403 iter = file->private_data;
2404
2405 if (iter->buffer_idx) {
2406 iter->filtered++;
2407 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt7f24b312009-02-13 14:37:33 -05002408 ftrace_match_records(iter->buffer, iter->buffer_idx, enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02002409 }
2410
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002411 mutex_lock(&ftrace_lock);
Steven Rostedtee02a2e2008-11-15 16:31:41 -05002412 if (ftrace_start_up && ftrace_enabled)
Steven Rostedt5072c592008-05-12 21:20:43 +02002413 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002414 mutex_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02002415
2416 kfree(iter);
Steven Rostedt41c52c02008-05-22 11:46:33 -04002417 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02002418 return 0;
2419}
2420
Steven Rostedt41c52c02008-05-22 11:46:33 -04002421static int
2422ftrace_filter_release(struct inode *inode, struct file *file)
2423{
2424 return ftrace_regex_release(inode, file, 1);
2425}
2426
2427static int
2428ftrace_notrace_release(struct inode *inode, struct file *file)
2429{
2430 return ftrace_regex_release(inode, file, 0);
2431}
2432
Steven Rostedt5e2336a02009-03-05 21:44:55 -05002433static const struct file_operations ftrace_avail_fops = {
Steven Rostedt5072c592008-05-12 21:20:43 +02002434 .open = ftrace_avail_open,
2435 .read = seq_read,
2436 .llseek = seq_lseek,
2437 .release = ftrace_avail_release,
2438};
2439
Steven Rostedt5e2336a02009-03-05 21:44:55 -05002440static const struct file_operations ftrace_failures_fops = {
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05302441 .open = ftrace_failures_open,
2442 .read = seq_read,
2443 .llseek = seq_lseek,
2444 .release = ftrace_avail_release,
2445};
2446
Steven Rostedt5e2336a02009-03-05 21:44:55 -05002447static const struct file_operations ftrace_filter_fops = {
Steven Rostedt5072c592008-05-12 21:20:43 +02002448 .open = ftrace_filter_open,
Lai Jiangshan850a80c2009-03-13 17:47:23 +08002449 .read = seq_read,
Steven Rostedt5072c592008-05-12 21:20:43 +02002450 .write = ftrace_filter_write,
Steven Rostedt41c52c02008-05-22 11:46:33 -04002451 .llseek = ftrace_regex_lseek,
Steven Rostedt5072c592008-05-12 21:20:43 +02002452 .release = ftrace_filter_release,
2453};
2454
Steven Rostedt5e2336a02009-03-05 21:44:55 -05002455static const struct file_operations ftrace_notrace_fops = {
Steven Rostedt41c52c02008-05-22 11:46:33 -04002456 .open = ftrace_notrace_open,
Lai Jiangshan850a80c2009-03-13 17:47:23 +08002457 .read = seq_read,
Steven Rostedt41c52c02008-05-22 11:46:33 -04002458 .write = ftrace_notrace_write,
2459 .llseek = ftrace_regex_lseek,
2460 .release = ftrace_notrace_release,
2461};
2462
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002463#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2464
2465static DEFINE_MUTEX(graph_lock);
2466
2467int ftrace_graph_count;
2468unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
2469
2470static void *
2471g_next(struct seq_file *m, void *v, loff_t *pos)
2472{
2473 unsigned long *array = m->private;
2474 int index = *pos;
2475
2476 (*pos)++;
2477
2478 if (index >= ftrace_graph_count)
2479 return NULL;
2480
2481 return &array[index];
2482}
2483
2484static void *g_start(struct seq_file *m, loff_t *pos)
2485{
2486 void *p = NULL;
2487
2488 mutex_lock(&graph_lock);
2489
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002490 /* Nothing, tell g_show to print all functions are enabled */
2491 if (!ftrace_graph_count && !*pos)
2492 return (void *)1;
2493
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002494 p = g_next(m, p, pos);
2495
2496 return p;
2497}
2498
2499static void g_stop(struct seq_file *m, void *p)
2500{
2501 mutex_unlock(&graph_lock);
2502}
2503
2504static int g_show(struct seq_file *m, void *v)
2505{
2506 unsigned long *ptr = v;
2507 char str[KSYM_SYMBOL_LEN];
2508
2509 if (!ptr)
2510 return 0;
2511
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002512 if (ptr == (unsigned long *)1) {
2513 seq_printf(m, "#### all functions enabled ####\n");
2514 return 0;
2515 }
2516
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002517 kallsyms_lookup(*ptr, NULL, NULL, NULL, str);
2518
2519 seq_printf(m, "%s\n", str);
2520
2521 return 0;
2522}
2523
2524static struct seq_operations ftrace_graph_seq_ops = {
2525 .start = g_start,
2526 .next = g_next,
2527 .stop = g_stop,
2528 .show = g_show,
2529};
2530
2531static int
2532ftrace_graph_open(struct inode *inode, struct file *file)
2533{
2534 int ret = 0;
2535
2536 if (unlikely(ftrace_disabled))
2537 return -ENODEV;
2538
2539 mutex_lock(&graph_lock);
2540 if ((file->f_mode & FMODE_WRITE) &&
2541 !(file->f_flags & O_APPEND)) {
2542 ftrace_graph_count = 0;
2543 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
2544 }
2545
2546 if (file->f_mode & FMODE_READ) {
2547 ret = seq_open(file, &ftrace_graph_seq_ops);
2548 if (!ret) {
2549 struct seq_file *m = file->private_data;
2550 m->private = ftrace_graph_funcs;
2551 }
2552 } else
2553 file->private_data = ftrace_graph_funcs;
2554 mutex_unlock(&graph_lock);
2555
2556 return ret;
2557}
2558
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002559static int
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002560ftrace_set_func(unsigned long *array, int *idx, char *buffer)
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002561{
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002562 struct dyn_ftrace *rec;
2563 struct ftrace_page *pg;
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002564 int search_len;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002565 int found = 0;
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002566 int type, not;
2567 char *search;
2568 bool exists;
2569 int i;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002570
2571 if (ftrace_disabled)
2572 return -ENODEV;
2573
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002574 /* decode regex */
2575 type = ftrace_setup_glob(buffer, strlen(buffer), &search, &not);
2576 if (not)
2577 return -EINVAL;
2578
2579 search_len = strlen(search);
2580
Steven Rostedt52baf112009-02-14 01:15:39 -05002581 mutex_lock(&ftrace_lock);
Steven Rostedt265c8312009-02-13 12:43:56 -05002582 do_for_each_ftrace_rec(pg, rec) {
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002583
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002584 if (*idx >= FTRACE_GRAPH_MAX_FUNCS)
2585 break;
2586
Steven Rostedt265c8312009-02-13 12:43:56 -05002587 if (rec->flags & (FTRACE_FL_FAILED | FTRACE_FL_FREE))
2588 continue;
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002589
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002590 if (ftrace_match_record(rec, search, search_len, type)) {
2591 /* ensure it is not already in the array */
2592 exists = false;
2593 for (i = 0; i < *idx; i++)
2594 if (array[i] == rec->ip) {
2595 exists = true;
Steven Rostedt265c8312009-02-13 12:43:56 -05002596 break;
2597 }
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002598 if (!exists) {
2599 array[(*idx)++] = rec->ip;
2600 found = 1;
2601 }
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002602 }
Steven Rostedt265c8312009-02-13 12:43:56 -05002603 } while_for_each_ftrace_rec();
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002604
Steven Rostedt52baf112009-02-14 01:15:39 -05002605 mutex_unlock(&ftrace_lock);
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002606
2607 return found ? 0 : -EINVAL;
2608}
2609
2610static ssize_t
2611ftrace_graph_write(struct file *file, const char __user *ubuf,
2612 size_t cnt, loff_t *ppos)
2613{
2614 unsigned char buffer[FTRACE_BUFF_MAX+1];
2615 unsigned long *array;
2616 size_t read = 0;
2617 ssize_t ret;
2618 int index = 0;
2619 char ch;
2620
2621 if (!cnt || cnt < 0)
2622 return 0;
2623
2624 mutex_lock(&graph_lock);
2625
2626 if (ftrace_graph_count >= FTRACE_GRAPH_MAX_FUNCS) {
2627 ret = -EBUSY;
2628 goto out;
2629 }
2630
2631 if (file->f_mode & FMODE_READ) {
2632 struct seq_file *m = file->private_data;
2633 array = m->private;
2634 } else
2635 array = file->private_data;
2636
2637 ret = get_user(ch, ubuf++);
2638 if (ret)
2639 goto out;
2640 read++;
2641 cnt--;
2642
2643 /* skip white space */
2644 while (cnt && isspace(ch)) {
2645 ret = get_user(ch, ubuf++);
2646 if (ret)
2647 goto out;
2648 read++;
2649 cnt--;
2650 }
2651
2652 if (isspace(ch)) {
2653 *ppos += read;
2654 ret = read;
2655 goto out;
2656 }
2657
2658 while (cnt && !isspace(ch)) {
2659 if (index < FTRACE_BUFF_MAX)
2660 buffer[index++] = ch;
2661 else {
2662 ret = -EINVAL;
2663 goto out;
2664 }
2665 ret = get_user(ch, ubuf++);
2666 if (ret)
2667 goto out;
2668 read++;
2669 cnt--;
2670 }
2671 buffer[index] = 0;
2672
Frederic Weisbeckerf9349a82009-02-19 21:13:12 +01002673 /* we allow only one expression at a time */
2674 ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002675 if (ret)
2676 goto out;
2677
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002678 file->f_pos += read;
2679
2680 ret = read;
2681 out:
2682 mutex_unlock(&graph_lock);
2683
2684 return ret;
2685}
2686
2687static const struct file_operations ftrace_graph_fops = {
2688 .open = ftrace_graph_open,
Lai Jiangshan850a80c2009-03-13 17:47:23 +08002689 .read = seq_read,
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002690 .write = ftrace_graph_write,
2691};
2692#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2693
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002694static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
Steven Rostedt5072c592008-05-12 21:20:43 +02002695{
Steven Rostedt5072c592008-05-12 21:20:43 +02002696 struct dentry *entry;
2697
Steven Rostedt5072c592008-05-12 21:20:43 +02002698 entry = debugfs_create_file("available_filter_functions", 0444,
2699 d_tracer, NULL, &ftrace_avail_fops);
2700 if (!entry)
2701 pr_warning("Could not create debugfs "
2702 "'available_filter_functions' entry\n");
2703
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05302704 entry = debugfs_create_file("failures", 0444,
2705 d_tracer, NULL, &ftrace_failures_fops);
2706 if (!entry)
2707 pr_warning("Could not create debugfs 'failures' entry\n");
2708
Steven Rostedt5072c592008-05-12 21:20:43 +02002709 entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer,
2710 NULL, &ftrace_filter_fops);
2711 if (!entry)
2712 pr_warning("Could not create debugfs "
2713 "'set_ftrace_filter' entry\n");
Steven Rostedt41c52c02008-05-22 11:46:33 -04002714
2715 entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer,
2716 NULL, &ftrace_notrace_fops);
2717 if (!entry)
2718 pr_warning("Could not create debugfs "
2719 "'set_ftrace_notrace' entry\n");
Steven Rostedtad90c0e2008-05-27 20:48:37 -04002720
Steven Rostedtea4e2bc2008-12-03 15:36:57 -05002721#ifdef CONFIG_FUNCTION_GRAPH_TRACER
2722 entry = debugfs_create_file("set_graph_function", 0444, d_tracer,
2723 NULL,
2724 &ftrace_graph_fops);
2725 if (!entry)
2726 pr_warning("Could not create debugfs "
2727 "'set_graph_function' entry\n");
2728#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
2729
Steven Rostedt5072c592008-05-12 21:20:43 +02002730 return 0;
2731}
2732
Steven Rostedt31e88902008-11-14 16:21:19 -08002733static int ftrace_convert_nops(struct module *mod,
2734 unsigned long *start,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002735 unsigned long *end)
2736{
2737 unsigned long *p;
2738 unsigned long addr;
2739 unsigned long flags;
2740
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002741 mutex_lock(&ftrace_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002742 p = start;
2743 while (p < end) {
2744 addr = ftrace_call_adjust(*p++);
Steven Rostedt20e52272008-11-14 16:21:19 -08002745 /*
2746 * Some architecture linkers will pad between
2747 * the different mcount_loc sections of different
2748 * object files to satisfy alignments.
2749 * Skip any NULL pointers.
2750 */
2751 if (!addr)
2752 continue;
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002753 ftrace_record_ip(addr);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002754 }
2755
Steven Rostedt08f5ac902008-10-23 09:33:07 -04002756 /* disable interrupts to prevent kstop machine */
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002757 local_irq_save(flags);
Steven Rostedt31e88902008-11-14 16:21:19 -08002758 ftrace_update_code(mod);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002759 local_irq_restore(flags);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002760 mutex_unlock(&ftrace_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002761
2762 return 0;
2763}
2764
Steven Rostedt31e88902008-11-14 16:21:19 -08002765void ftrace_init_module(struct module *mod,
2766 unsigned long *start, unsigned long *end)
Steven Rostedt90d595f2008-08-14 15:45:09 -04002767{
Steven Rostedt00fd61a2008-08-15 21:40:04 -04002768 if (ftrace_disabled || start == end)
Steven Rostedtfed19392008-08-14 22:47:19 -04002769 return;
Steven Rostedt31e88902008-11-14 16:21:19 -08002770 ftrace_convert_nops(mod, start, end);
Steven Rostedt90d595f2008-08-14 15:45:09 -04002771}
2772
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002773extern unsigned long __start_mcount_loc[];
2774extern unsigned long __stop_mcount_loc[];
2775
2776void __init ftrace_init(void)
2777{
2778 unsigned long count, addr, flags;
2779 int ret;
2780
2781 /* Keep the ftrace pointer to the stub */
2782 addr = (unsigned long)ftrace_stub;
2783
2784 local_irq_save(flags);
2785 ftrace_dyn_arch_init(&addr);
2786 local_irq_restore(flags);
2787
2788 /* ftrace_dyn_arch_init places the return code in addr */
2789 if (addr)
2790 goto failed;
2791
2792 count = __stop_mcount_loc - __start_mcount_loc;
2793
2794 ret = ftrace_dyn_table_alloc(count);
2795 if (ret)
2796 goto failed;
2797
2798 last_ftrace_enabled = ftrace_enabled = 1;
2799
Steven Rostedt31e88902008-11-14 16:21:19 -08002800 ret = ftrace_convert_nops(NULL,
2801 __start_mcount_loc,
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002802 __stop_mcount_loc);
2803
2804 return;
2805 failed:
2806 ftrace_disabled = 1;
2807}
Steven Rostedt68bf21a2008-08-14 15:45:08 -04002808
Steven Rostedt3d083392008-05-12 21:20:42 +02002809#else
Frederic Weisbecker0b6e4d52008-10-28 20:17:38 +01002810
2811static int __init ftrace_nodyn_init(void)
2812{
2813 ftrace_enabled = 1;
2814 return 0;
2815}
2816device_initcall(ftrace_nodyn_init);
2817
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002818static inline int ftrace_init_dyn_debugfs(struct dentry *d_tracer) { return 0; }
2819static inline void ftrace_startup_enable(int command) { }
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05002820/* Keep as macros so we do not need to define the commands */
2821# define ftrace_startup(command) do { } while (0)
2822# define ftrace_shutdown(command) do { } while (0)
Ingo Molnarc7aafc52008-05-12 21:20:45 +02002823# define ftrace_startup_sysctl() do { } while (0)
2824# define ftrace_shutdown_sysctl() do { } while (0)
Steven Rostedt3d083392008-05-12 21:20:42 +02002825#endif /* CONFIG_DYNAMIC_FTRACE */
2826
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002827static ssize_t
2828ftrace_pid_read(struct file *file, char __user *ubuf,
2829 size_t cnt, loff_t *ppos)
2830{
2831 char buf[64];
2832 int r;
2833
Steven Rostedte32d8952008-12-04 00:26:41 -05002834 if (ftrace_pid_trace == ftrace_swapper_pid)
2835 r = sprintf(buf, "swapper tasks\n");
2836 else if (ftrace_pid_trace)
Lai Jiangshancc59c9e2009-03-24 11:03:01 +08002837 r = sprintf(buf, "%u\n", pid_vnr(ftrace_pid_trace));
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002838 else
2839 r = sprintf(buf, "no pid\n");
2840
2841 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2842}
2843
Steven Rostedte32d8952008-12-04 00:26:41 -05002844static void clear_ftrace_swapper(void)
2845{
2846 struct task_struct *p;
2847 int cpu;
2848
2849 get_online_cpus();
2850 for_each_online_cpu(cpu) {
2851 p = idle_task(cpu);
2852 clear_tsk_trace_trace(p);
2853 }
2854 put_online_cpus();
2855}
2856
2857static void set_ftrace_swapper(void)
2858{
2859 struct task_struct *p;
2860 int cpu;
2861
2862 get_online_cpus();
2863 for_each_online_cpu(cpu) {
2864 p = idle_task(cpu);
2865 set_tsk_trace_trace(p);
2866 }
2867 put_online_cpus();
2868}
2869
2870static void clear_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05002871{
2872 struct task_struct *p;
2873
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002874 rcu_read_lock();
Steven Rostedte32d8952008-12-04 00:26:41 -05002875 do_each_pid_task(pid, PIDTYPE_PID, p) {
Steven Rostedt978f3a42008-12-04 00:26:40 -05002876 clear_tsk_trace_trace(p);
Steven Rostedte32d8952008-12-04 00:26:41 -05002877 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002878 rcu_read_unlock();
2879
Steven Rostedte32d8952008-12-04 00:26:41 -05002880 put_pid(pid);
Steven Rostedt978f3a42008-12-04 00:26:40 -05002881}
2882
Steven Rostedte32d8952008-12-04 00:26:41 -05002883static void set_ftrace_pid(struct pid *pid)
Steven Rostedt978f3a42008-12-04 00:26:40 -05002884{
2885 struct task_struct *p;
2886
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002887 rcu_read_lock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05002888 do_each_pid_task(pid, PIDTYPE_PID, p) {
2889 set_tsk_trace_trace(p);
2890 } while_each_pid_task(pid, PIDTYPE_PID, p);
Oleg Nesterov229c4ef2009-02-03 20:39:04 +01002891 rcu_read_unlock();
Steven Rostedt978f3a42008-12-04 00:26:40 -05002892}
2893
Steven Rostedte32d8952008-12-04 00:26:41 -05002894static void clear_ftrace_pid_task(struct pid **pid)
2895{
2896 if (*pid == ftrace_swapper_pid)
2897 clear_ftrace_swapper();
2898 else
2899 clear_ftrace_pid(*pid);
2900
2901 *pid = NULL;
2902}
2903
2904static void set_ftrace_pid_task(struct pid *pid)
2905{
2906 if (pid == ftrace_swapper_pid)
2907 set_ftrace_swapper();
2908 else
2909 set_ftrace_pid(pid);
2910}
2911
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002912static ssize_t
2913ftrace_pid_write(struct file *filp, const char __user *ubuf,
2914 size_t cnt, loff_t *ppos)
2915{
Steven Rostedt978f3a42008-12-04 00:26:40 -05002916 struct pid *pid;
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002917 char buf[64];
2918 long val;
2919 int ret;
2920
2921 if (cnt >= sizeof(buf))
2922 return -EINVAL;
2923
2924 if (copy_from_user(&buf, ubuf, cnt))
2925 return -EFAULT;
2926
2927 buf[cnt] = 0;
2928
2929 ret = strict_strtol(buf, 10, &val);
2930 if (ret < 0)
2931 return ret;
2932
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002933 mutex_lock(&ftrace_lock);
Steven Rostedt978f3a42008-12-04 00:26:40 -05002934 if (val < 0) {
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002935 /* disable pid tracing */
Steven Rostedt978f3a42008-12-04 00:26:40 -05002936 if (!ftrace_pid_trace)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002937 goto out;
Steven Rostedt978f3a42008-12-04 00:26:40 -05002938
2939 clear_ftrace_pid_task(&ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002940
2941 } else {
Steven Rostedte32d8952008-12-04 00:26:41 -05002942 /* swapper task is special */
2943 if (!val) {
2944 pid = ftrace_swapper_pid;
2945 if (pid == ftrace_pid_trace)
2946 goto out;
2947 } else {
2948 pid = find_get_pid(val);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002949
Steven Rostedte32d8952008-12-04 00:26:41 -05002950 if (pid == ftrace_pid_trace) {
2951 put_pid(pid);
2952 goto out;
2953 }
Steven Rostedt978f3a42008-12-04 00:26:40 -05002954 }
2955
2956 if (ftrace_pid_trace)
2957 clear_ftrace_pid_task(&ftrace_pid_trace);
2958
2959 if (!pid)
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002960 goto out;
2961
Steven Rostedt978f3a42008-12-04 00:26:40 -05002962 ftrace_pid_trace = pid;
Steven Rostedt0ef8cde2008-12-03 15:36:58 -05002963
Steven Rostedt978f3a42008-12-04 00:26:40 -05002964 set_ftrace_pid_task(ftrace_pid_trace);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002965 }
2966
2967 /* update the function call */
2968 ftrace_update_pid_func();
2969 ftrace_startup_enable(0);
2970
2971 out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05002972 mutex_unlock(&ftrace_lock);
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002973
2974 return cnt;
2975}
2976
Steven Rostedt5e2336a02009-03-05 21:44:55 -05002977static const struct file_operations ftrace_pid_fops = {
Steven Rostedtdf4fc312008-11-26 00:16:23 -05002978 .read = ftrace_pid_read,
2979 .write = ftrace_pid_write,
2980};
2981
2982static __init int ftrace_init_debugfs(void)
2983{
2984 struct dentry *d_tracer;
2985 struct dentry *entry;
2986
2987 d_tracer = tracing_init_dentry();
2988 if (!d_tracer)
2989 return 0;
2990
2991 ftrace_init_dyn_debugfs(d_tracer);
2992
2993 entry = debugfs_create_file("set_ftrace_pid", 0644, d_tracer,
2994 NULL, &ftrace_pid_fops);
2995 if (!entry)
2996 pr_warning("Could not create debugfs "
2997 "'set_ftrace_pid' entry\n");
Steven Rostedt493762f2009-03-23 17:12:36 -04002998
2999 ftrace_profile_debugfs(d_tracer);
3000
Steven Rostedtdf4fc312008-11-26 00:16:23 -05003001 return 0;
3002}
Steven Rostedtdf4fc312008-11-26 00:16:23 -05003003fs_initcall(ftrace_init_debugfs);
3004
Steven Rostedt3d083392008-05-12 21:20:42 +02003005/**
Steven Rostedt81adbdc2008-10-23 09:33:02 -04003006 * ftrace_kill - kill ftrace
Steven Rostedta2bb6a32008-07-10 20:58:15 -04003007 *
3008 * This function should be used by panic code. It stops ftrace
3009 * but in a not so nice way. If you need to simply kill ftrace
3010 * from a non-atomic section, use ftrace_kill.
3011 */
Steven Rostedt81adbdc2008-10-23 09:33:02 -04003012void ftrace_kill(void)
Steven Rostedta2bb6a32008-07-10 20:58:15 -04003013{
3014 ftrace_disabled = 1;
3015 ftrace_enabled = 0;
Steven Rostedta2bb6a32008-07-10 20:58:15 -04003016 clear_ftrace_function();
3017}
3018
3019/**
Steven Rostedt3d083392008-05-12 21:20:42 +02003020 * register_ftrace_function - register a function for profiling
3021 * @ops - ops structure that holds the function for profiling.
3022 *
3023 * Register a function to be called by all functions in the
3024 * kernel.
3025 *
3026 * Note: @ops->func and all the functions it calls must be labeled
3027 * with "notrace", otherwise it will go into a
3028 * recursive loop.
3029 */
3030int register_ftrace_function(struct ftrace_ops *ops)
3031{
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003032 int ret;
3033
Steven Rostedt4eebcc82008-05-12 21:20:48 +02003034 if (unlikely(ftrace_disabled))
3035 return -1;
3036
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003037 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003038
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003039 ret = __register_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05003040 ftrace_startup(0);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003041
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003042 mutex_unlock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003043 return ret;
Steven Rostedt3d083392008-05-12 21:20:42 +02003044}
3045
3046/**
Uwe Kleine-Koenig32632922009-01-12 23:35:50 +01003047 * unregister_ftrace_function - unregister a function for profiling.
Steven Rostedt3d083392008-05-12 21:20:42 +02003048 * @ops - ops structure that holds the function to unregister
3049 *
3050 * Unregister a function that was added to be called by ftrace profiling.
3051 */
3052int unregister_ftrace_function(struct ftrace_ops *ops)
3053{
3054 int ret;
3055
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003056 mutex_lock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02003057 ret = __unregister_ftrace_function(ops);
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05003058 ftrace_shutdown(0);
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003059 mutex_unlock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003060
3061 return ret;
3062}
3063
Ingo Molnare309b412008-05-12 21:20:51 +02003064int
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003065ftrace_enable_sysctl(struct ctl_table *table, int write,
Steven Rostedt5072c592008-05-12 21:20:43 +02003066 struct file *file, void __user *buffer, size_t *lenp,
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003067 loff_t *ppos)
3068{
3069 int ret;
3070
Steven Rostedt4eebcc82008-05-12 21:20:48 +02003071 if (unlikely(ftrace_disabled))
3072 return -ENODEV;
3073
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003074 mutex_lock(&ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003075
Steven Rostedt5072c592008-05-12 21:20:43 +02003076 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02003077
3078 if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
3079 goto out;
3080
3081 last_ftrace_enabled = ftrace_enabled;
3082
3083 if (ftrace_enabled) {
3084
3085 ftrace_startup_sysctl();
3086
3087 /* we are starting ftrace again */
3088 if (ftrace_list != &ftrace_list_end) {
3089 if (ftrace_list->next == &ftrace_list_end)
3090 ftrace_trace_function = ftrace_list->func;
3091 else
3092 ftrace_trace_function = ftrace_list_func;
3093 }
3094
3095 } else {
3096 /* stopping ftrace calls (just send to ftrace_stub) */
3097 ftrace_trace_function = ftrace_stub;
3098
3099 ftrace_shutdown_sysctl();
3100 }
3101
3102 out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003103 mutex_unlock(&ftrace_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02003104 return ret;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02003105}
Ingo Molnarf17845e2008-10-24 12:47:10 +02003106
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003107#ifdef CONFIG_FUNCTION_GRAPH_TRACER
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003108
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003109static atomic_t ftrace_graph_active;
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08003110static struct notifier_block ftrace_suspend_notifier;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003111
Steven Rostedte49dc192008-12-02 23:50:05 -05003112int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
3113{
3114 return 0;
3115}
3116
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003117/* The callbacks that hook a function */
3118trace_func_graph_ret_t ftrace_graph_return =
3119 (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05003120trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003121
3122/* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */
3123static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list)
3124{
3125 int i;
3126 int ret = 0;
3127 unsigned long flags;
3128 int start = 0, end = FTRACE_RETSTACK_ALLOC_SIZE;
3129 struct task_struct *g, *t;
3130
3131 for (i = 0; i < FTRACE_RETSTACK_ALLOC_SIZE; i++) {
3132 ret_stack_list[i] = kmalloc(FTRACE_RETFUNC_DEPTH
3133 * sizeof(struct ftrace_ret_stack),
3134 GFP_KERNEL);
3135 if (!ret_stack_list[i]) {
3136 start = 0;
3137 end = i;
3138 ret = -ENOMEM;
3139 goto free;
3140 }
3141 }
3142
3143 read_lock_irqsave(&tasklist_lock, flags);
3144 do_each_thread(g, t) {
3145 if (start == end) {
3146 ret = -EAGAIN;
3147 goto unlock;
3148 }
3149
3150 if (t->ret_stack == NULL) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003151 t->curr_ret_stack = -1;
Frederic Weisbecker48d68b22008-12-02 00:20:39 +01003152 /* Make sure IRQs see the -1 first: */
3153 barrier();
3154 t->ret_stack = ret_stack_list[start++];
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01003155 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003156 atomic_set(&t->trace_overrun, 0);
3157 }
3158 } while_each_thread(g, t);
3159
3160unlock:
3161 read_unlock_irqrestore(&tasklist_lock, flags);
3162free:
3163 for (i = start; i < end; i++)
3164 kfree(ret_stack_list[i]);
3165 return ret;
3166}
3167
Steven Rostedt8aef2d22009-03-24 01:10:15 -04003168static void
3169ftrace_graph_probe_sched_switch(struct rq *__rq, struct task_struct *prev,
3170 struct task_struct *next)
3171{
3172 unsigned long long timestamp;
3173 int index;
3174
Steven Rostedtbe6f1642009-03-24 11:06:24 -04003175 /*
3176 * Does the user want to count the time a function was asleep.
3177 * If so, do not update the time stamps.
3178 */
3179 if (trace_flags & TRACE_ITER_SLEEP_TIME)
3180 return;
3181
Steven Rostedt8aef2d22009-03-24 01:10:15 -04003182 timestamp = trace_clock_local();
3183
3184 prev->ftrace_timestamp = timestamp;
3185
3186 /* only process tasks that we timestamped */
3187 if (!next->ftrace_timestamp)
3188 return;
3189
3190 /*
3191 * Update all the counters in next to make up for the
3192 * time next was sleeping.
3193 */
3194 timestamp -= next->ftrace_timestamp;
3195
3196 for (index = next->curr_ret_stack; index >= 0; index--)
3197 next->ret_stack[index].calltime += timestamp;
3198}
3199
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003200/* Allocate a return stack for each task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003201static int start_graph_tracing(void)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003202{
3203 struct ftrace_ret_stack **ret_stack_list;
Frederic Weisbecker5b058bc2009-02-17 18:35:34 +01003204 int ret, cpu;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003205
3206 ret_stack_list = kmalloc(FTRACE_RETSTACK_ALLOC_SIZE *
3207 sizeof(struct ftrace_ret_stack *),
3208 GFP_KERNEL);
3209
3210 if (!ret_stack_list)
3211 return -ENOMEM;
3212
Frederic Weisbecker5b058bc2009-02-17 18:35:34 +01003213 /* The cpu_boot init_task->ret_stack will never be freed */
3214 for_each_online_cpu(cpu)
3215 ftrace_graph_init_task(idle_task(cpu));
3216
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003217 do {
3218 ret = alloc_retstack_tasklist(ret_stack_list);
3219 } while (ret == -EAGAIN);
3220
Steven Rostedt8aef2d22009-03-24 01:10:15 -04003221 if (!ret) {
3222 ret = register_trace_sched_switch(ftrace_graph_probe_sched_switch);
3223 if (ret)
3224 pr_info("ftrace_graph: Couldn't activate tracepoint"
3225 " probe to kernel_sched_switch\n");
3226 }
3227
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003228 kfree(ret_stack_list);
3229 return ret;
3230}
3231
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08003232/*
3233 * Hibernation protection.
3234 * The state of the current task is too much unstable during
3235 * suspend/restore to disk. We want to protect against that.
3236 */
3237static int
3238ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
3239 void *unused)
3240{
3241 switch (state) {
3242 case PM_HIBERNATION_PREPARE:
3243 pause_graph_tracing();
3244 break;
3245
3246 case PM_POST_HIBERNATION:
3247 unpause_graph_tracing();
3248 break;
3249 }
3250 return NOTIFY_DONE;
3251}
3252
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003253int register_ftrace_graph(trace_func_graph_ret_t retfunc,
3254 trace_func_graph_ent_t entryfunc)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01003255{
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003256 int ret = 0;
3257
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003258 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003259
Steven Rostedt05ce5812009-03-24 00:18:31 -04003260 /* we currently allow only one tracer registered at a time */
3261 if (atomic_read(&ftrace_graph_active)) {
3262 ret = -EBUSY;
3263 goto out;
3264 }
3265
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08003266 ftrace_suspend_notifier.notifier_call = ftrace_suspend_notifier_call;
3267 register_pm_notifier(&ftrace_suspend_notifier);
3268
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003269 atomic_inc(&ftrace_graph_active);
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003270 ret = start_graph_tracing();
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003271 if (ret) {
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003272 atomic_dec(&ftrace_graph_active);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003273 goto out;
3274 }
Steven Rostedte53a6312008-11-26 00:16:25 -05003275
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003276 ftrace_graph_return = retfunc;
3277 ftrace_graph_entry = entryfunc;
Steven Rostedte53a6312008-11-26 00:16:25 -05003278
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05003279 ftrace_startup(FTRACE_START_FUNC_RET);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003280
3281out:
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003282 mutex_unlock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003283 return ret;
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01003284}
3285
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003286void unregister_ftrace_graph(void)
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01003287{
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003288 mutex_lock(&ftrace_lock);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003289
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003290 atomic_dec(&ftrace_graph_active);
Steven Rostedt8aef2d22009-03-24 01:10:15 -04003291 unregister_trace_sched_switch(ftrace_graph_probe_sched_switch);
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003292 ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub;
Steven Rostedte49dc192008-12-02 23:50:05 -05003293 ftrace_graph_entry = ftrace_graph_entry_stub;
Steven Rostedt5a45cfe2008-11-26 00:16:24 -05003294 ftrace_shutdown(FTRACE_STOP_FUNC_RET);
Frederic Weisbecker4a2b8dd2009-01-14 13:33:27 -08003295 unregister_pm_notifier(&ftrace_suspend_notifier);
Frederic Weisbeckere7d37372008-11-16 06:02:06 +01003296
Steven Rostedte6ea44e2009-02-14 01:42:44 -05003297 mutex_unlock(&ftrace_lock);
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01003298}
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003299
3300/* Allocate a return stack for newly created task */
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003301void ftrace_graph_init_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003302{
Frederic Weisbecker287b6e62008-11-26 00:57:25 +01003303 if (atomic_read(&ftrace_graph_active)) {
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003304 t->ret_stack = kmalloc(FTRACE_RETFUNC_DEPTH
3305 * sizeof(struct ftrace_ret_stack),
3306 GFP_KERNEL);
3307 if (!t->ret_stack)
3308 return;
3309 t->curr_ret_stack = -1;
Frederic Weisbecker380c4b12008-12-06 03:43:41 +01003310 atomic_set(&t->tracing_graph_pause, 0);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003311 atomic_set(&t->trace_overrun, 0);
Steven Rostedt8aef2d22009-03-24 01:10:15 -04003312 t->ftrace_timestamp = 0;
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003313 } else
3314 t->ret_stack = NULL;
3315}
3316
Frederic Weisbeckerfb526072008-11-25 21:07:04 +01003317void ftrace_graph_exit_task(struct task_struct *t)
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003318{
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01003319 struct ftrace_ret_stack *ret_stack = t->ret_stack;
3320
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003321 t->ret_stack = NULL;
Frederic Weisbeckereae849c2008-11-23 17:33:12 +01003322 /* NULL must become visible to IRQs before we free it: */
3323 barrier();
3324
3325 kfree(ret_stack);
Frederic Weisbeckerf201ae22008-11-23 06:22:56 +01003326}
Steven Rostedt14a866c2008-12-02 23:50:02 -05003327
3328void ftrace_graph_stop(void)
3329{
3330 ftrace_stop();
3331}
Frederic Weisbecker15e6cb32008-11-11 07:14:25 +01003332#endif
3333