blob: 14fa52297b2857a25aa8aece74f5d34f948dea47 [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>
20#include <linux/debugfs.h>
Steven Rostedt3d083392008-05-12 21:20:42 +020021#include <linux/hardirq.h>
Ingo Molnar2d8b8202008-02-23 16:55:50 +010022#include <linux/kthread.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020023#include <linux/uaccess.h>
Abhishek Sagarf22f9a82008-06-21 23:50:29 +053024#include <linux/kprobes.h>
Ingo Molnar2d8b8202008-02-23 16:55:50 +010025#include <linux/ftrace.h>
Steven Rostedtb0fc4942008-05-12 21:20:43 +020026#include <linux/sysctl.h>
Steven Rostedt5072c592008-05-12 21:20:43 +020027#include <linux/ctype.h>
Steven Rostedt3d083392008-05-12 21:20:42 +020028#include <linux/list.h>
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020029
Abhishek Sagar395a59d2008-06-21 23:47:27 +053030#include <asm/ftrace.h>
31
Steven Rostedt3d083392008-05-12 21:20:42 +020032#include "trace.h"
33
Steven Rostedt69128962008-10-23 09:33:03 -040034#define FTRACE_WARN_ON(cond) \
35 do { \
36 if (WARN_ON(cond)) \
37 ftrace_kill(); \
38 } while (0)
39
40#define FTRACE_WARN_ON_ONCE(cond) \
41 do { \
42 if (WARN_ON_ONCE(cond)) \
43 ftrace_kill(); \
44 } while (0)
45
Steven Rostedt4eebcc82008-05-12 21:20:48 +020046/* ftrace_enabled is a method to turn ftrace on or off */
47int ftrace_enabled __read_mostly;
Steven Rostedtd61f82d2008-05-12 21:20:43 +020048static int last_ftrace_enabled;
Steven Rostedtb0fc4942008-05-12 21:20:43 +020049
Steven Rostedt4eebcc82008-05-12 21:20:48 +020050/*
51 * ftrace_disabled is set when an anomaly is discovered.
52 * ftrace_disabled is much stronger than ftrace_enabled.
53 */
54static int ftrace_disabled __read_mostly;
55
Steven Rostedt3d083392008-05-12 21:20:42 +020056static DEFINE_SPINLOCK(ftrace_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +020057static DEFINE_MUTEX(ftrace_sysctl_lock);
58
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020059static struct ftrace_ops ftrace_list_end __read_mostly =
60{
61 .func = ftrace_stub,
62};
63
64static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
65ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
66
Ingo Molnarf2252932008-05-22 10:37:48 +020067static void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020068{
69 struct ftrace_ops *op = ftrace_list;
70
71 /* in case someone actually ports this to alpha! */
72 read_barrier_depends();
73
74 while (op != &ftrace_list_end) {
75 /* silly alpha */
76 read_barrier_depends();
77 op->func(ip, parent_ip);
78 op = op->next;
79 };
80}
81
82/**
Steven Rostedt3d083392008-05-12 21:20:42 +020083 * clear_ftrace_function - reset the ftrace function
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020084 *
Steven Rostedt3d083392008-05-12 21:20:42 +020085 * This NULLs the ftrace function and in essence stops
86 * tracing. There may be lag
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020087 */
Steven Rostedt3d083392008-05-12 21:20:42 +020088void clear_ftrace_function(void)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020089{
Steven Rostedt3d083392008-05-12 21:20:42 +020090 ftrace_trace_function = ftrace_stub;
91}
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020092
Ingo Molnare309b412008-05-12 21:20:51 +020093static int __register_ftrace_function(struct ftrace_ops *ops)
Steven Rostedt3d083392008-05-12 21:20:42 +020094{
Steven Rostedt99ecdc42008-08-15 21:40:05 -040095 /* should not be called from interrupt context */
Steven Rostedt3d083392008-05-12 21:20:42 +020096 spin_lock(&ftrace_lock);
97
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +020098 ops->next = ftrace_list;
99 /*
100 * We are entering ops into the ftrace_list but another
101 * CPU might be walking that list. We need to make sure
102 * the ops->next pointer is valid before another CPU sees
103 * the ops pointer included into the ftrace_list.
104 */
105 smp_wmb();
106 ftrace_list = ops;
Steven Rostedt3d083392008-05-12 21:20:42 +0200107
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200108 if (ftrace_enabled) {
109 /*
110 * For one func, simply call it directly.
111 * For more than one func, call the chain.
112 */
113 if (ops->next == &ftrace_list_end)
114 ftrace_trace_function = ops->func;
115 else
116 ftrace_trace_function = ftrace_list_func;
117 }
Steven Rostedt3d083392008-05-12 21:20:42 +0200118
119 spin_unlock(&ftrace_lock);
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200120
121 return 0;
122}
123
Ingo Molnare309b412008-05-12 21:20:51 +0200124static int __unregister_ftrace_function(struct ftrace_ops *ops)
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200125{
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200126 struct ftrace_ops **p;
127 int ret = 0;
128
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400129 /* should not be called from interrupt context */
Steven Rostedt3d083392008-05-12 21:20:42 +0200130 spin_lock(&ftrace_lock);
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200131
132 /*
Steven Rostedt3d083392008-05-12 21:20:42 +0200133 * If we are removing the last function, then simply point
134 * to the ftrace_stub.
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200135 */
136 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
137 ftrace_trace_function = ftrace_stub;
138 ftrace_list = &ftrace_list_end;
139 goto out;
140 }
141
142 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
143 if (*p == ops)
144 break;
145
146 if (*p != ops) {
147 ret = -1;
148 goto out;
149 }
150
151 *p = (*p)->next;
152
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200153 if (ftrace_enabled) {
154 /* If we only have one func left, then call that directly */
155 if (ftrace_list == &ftrace_list_end ||
156 ftrace_list->next == &ftrace_list_end)
157 ftrace_trace_function = ftrace_list->func;
158 }
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200159
160 out:
Steven Rostedt3d083392008-05-12 21:20:42 +0200161 spin_unlock(&ftrace_lock);
162
163 return ret;
164}
165
166#ifdef CONFIG_DYNAMIC_FTRACE
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400167#ifndef CONFIG_FTRACE_MCOUNT_RECORD
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400168# error Dynamic ftrace depends on MCOUNT_RECORD
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400169#endif
170
Steven Noonan71c67d52008-09-20 01:00:37 -0700171/*
172 * Since MCOUNT_ADDR may point to mcount itself, we do not want
173 * to get it confused by reading a reference in the code as we
174 * are parsing on objcopy output of text. Use a variable for
175 * it instead.
176 */
177static unsigned long mcount_addr = MCOUNT_ADDR;
178
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200179enum {
180 FTRACE_ENABLE_CALLS = (1 << 0),
181 FTRACE_DISABLE_CALLS = (1 << 1),
182 FTRACE_UPDATE_TRACE_FUNC = (1 << 2),
183 FTRACE_ENABLE_MCOUNT = (1 << 3),
184 FTRACE_DISABLE_MCOUNT = (1 << 4),
185};
186
Steven Rostedt5072c592008-05-12 21:20:43 +0200187static int ftrace_filtered;
188
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400189static LIST_HEAD(ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200190
Steven Rostedt41c52c02008-05-22 11:46:33 -0400191static DEFINE_MUTEX(ftrace_regex_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200192
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200193struct ftrace_page {
194 struct ftrace_page *next;
David Milleraa5e5ce2008-05-13 22:06:56 -0700195 unsigned long index;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200196 struct dyn_ftrace records[];
David Milleraa5e5ce2008-05-13 22:06:56 -0700197};
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200198
199#define ENTRIES_PER_PAGE \
200 ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
201
202/* estimate from running different kernels */
203#define NR_TO_INIT 10000
204
205static struct ftrace_page *ftrace_pages_start;
206static struct ftrace_page *ftrace_pages;
207
Steven Rostedt37ad5082008-05-12 21:20:48 +0200208static struct dyn_ftrace *ftrace_free_records;
209
Abhishek Sagarecea6562008-06-21 23:47:53 +0530210
211#ifdef CONFIG_KPROBES
Ingo Molnarf17845e2008-10-24 12:47:10 +0200212
213static int frozen_record_count;
214
Abhishek Sagarecea6562008-06-21 23:47:53 +0530215static inline void freeze_record(struct dyn_ftrace *rec)
216{
217 if (!(rec->flags & FTRACE_FL_FROZEN)) {
218 rec->flags |= FTRACE_FL_FROZEN;
219 frozen_record_count++;
220 }
221}
222
223static inline void unfreeze_record(struct dyn_ftrace *rec)
224{
225 if (rec->flags & FTRACE_FL_FROZEN) {
226 rec->flags &= ~FTRACE_FL_FROZEN;
227 frozen_record_count--;
228 }
229}
230
231static inline int record_frozen(struct dyn_ftrace *rec)
232{
233 return rec->flags & FTRACE_FL_FROZEN;
234}
235#else
236# define freeze_record(rec) ({ 0; })
237# define unfreeze_record(rec) ({ 0; })
238# define record_frozen(rec) ({ 0; })
239#endif /* CONFIG_KPROBES */
240
Ingo Molnare309b412008-05-12 21:20:51 +0200241static void ftrace_free_rec(struct dyn_ftrace *rec)
Steven Rostedt37ad5082008-05-12 21:20:48 +0200242{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200243 rec->ip = (unsigned long)ftrace_free_records;
244 ftrace_free_records = rec;
245 rec->flags |= FTRACE_FL_FREE;
246}
247
Steven Rostedtfed19392008-08-14 22:47:19 -0400248void ftrace_release(void *start, unsigned long size)
249{
250 struct dyn_ftrace *rec;
251 struct ftrace_page *pg;
252 unsigned long s = (unsigned long)start;
253 unsigned long e = s + size;
254 int i;
255
Steven Rostedt00fd61a2008-08-15 21:40:04 -0400256 if (ftrace_disabled || !start)
Steven Rostedtfed19392008-08-14 22:47:19 -0400257 return;
258
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400259 /* should not be called from interrupt context */
Steven Rostedtfed19392008-08-14 22:47:19 -0400260 spin_lock(&ftrace_lock);
261
262 for (pg = ftrace_pages_start; pg; pg = pg->next) {
263 for (i = 0; i < pg->index; i++) {
264 rec = &pg->records[i];
265
266 if ((rec->ip >= s) && (rec->ip < e))
267 ftrace_free_rec(rec);
268 }
269 }
270 spin_unlock(&ftrace_lock);
Steven Rostedtfed19392008-08-14 22:47:19 -0400271}
272
Ingo Molnare309b412008-05-12 21:20:51 +0200273static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200274{
Steven Rostedt37ad5082008-05-12 21:20:48 +0200275 struct dyn_ftrace *rec;
276
277 /* First check for freed records */
278 if (ftrace_free_records) {
279 rec = ftrace_free_records;
280
Steven Rostedt37ad5082008-05-12 21:20:48 +0200281 if (unlikely(!(rec->flags & FTRACE_FL_FREE))) {
Steven Rostedt69128962008-10-23 09:33:03 -0400282 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt37ad5082008-05-12 21:20:48 +0200283 ftrace_free_records = NULL;
284 return NULL;
285 }
286
287 ftrace_free_records = (void *)rec->ip;
288 memset(rec, 0, sizeof(*rec));
289 return rec;
290 }
291
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200292 if (ftrace_pages->index == ENTRIES_PER_PAGE) {
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400293 if (!ftrace_pages->next) {
294 /* allocate another page */
295 ftrace_pages->next =
296 (void *)get_zeroed_page(GFP_KERNEL);
297 if (!ftrace_pages->next)
298 return NULL;
299 }
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200300 ftrace_pages = ftrace_pages->next;
301 }
302
303 return &ftrace_pages->records[ftrace_pages->index++];
304}
305
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400306static struct dyn_ftrace *
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200307ftrace_record_ip(unsigned long ip)
Steven Rostedt3d083392008-05-12 21:20:42 +0200308{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400309 struct dyn_ftrace *rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200310
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200311 if (!ftrace_enabled || ftrace_disabled)
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400312 return NULL;
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200313
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400314 rec = ftrace_alloc_dyn_node(ip);
315 if (!rec)
316 return NULL;
Steven Rostedt3d083392008-05-12 21:20:42 +0200317
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400318 rec->ip = ip;
Steven Rostedt3d083392008-05-12 21:20:42 +0200319
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400320 list_add(&rec->list, &ftrace_new_addrs);
Steven Rostedt3d083392008-05-12 21:20:42 +0200321
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400322 return rec;
Steven Rostedt3d083392008-05-12 21:20:42 +0200323}
324
Steven Rostedtcaf8cde2008-05-12 21:20:50 +0200325#define FTRACE_ADDR ((long)(ftrace_caller))
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200326
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530327static int
Steven Rostedt5072c592008-05-12 21:20:43 +0200328__ftrace_replace_code(struct dyn_ftrace *rec,
329 unsigned char *old, unsigned char *new, int enable)
330{
Steven Rostedt41c52c02008-05-22 11:46:33 -0400331 unsigned long ip, fl;
Steven Rostedt5072c592008-05-12 21:20:43 +0200332
333 ip = rec->ip;
334
335 if (ftrace_filtered && enable) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200336 /*
337 * If filtering is on:
338 *
339 * If this record is set to be filtered and
340 * is enabled then do nothing.
341 *
342 * If this record is set to be filtered and
343 * it is not enabled, enable it.
344 *
345 * If this record is not set to be filtered
346 * and it is not enabled do nothing.
347 *
Steven Rostedt41c52c02008-05-22 11:46:33 -0400348 * If this record is set not to trace then
349 * do nothing.
350 *
Abhishek Sagara4500b82008-06-14 11:59:39 +0530351 * If this record is set not to trace and
352 * it is enabled then disable it.
353 *
Steven Rostedt5072c592008-05-12 21:20:43 +0200354 * If this record is not set to be filtered and
355 * it is enabled, disable it.
356 */
Abhishek Sagara4500b82008-06-14 11:59:39 +0530357
358 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE |
359 FTRACE_FL_ENABLED);
Steven Rostedt5072c592008-05-12 21:20:43 +0200360
361 if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) ||
Abhishek Sagara4500b82008-06-14 11:59:39 +0530362 (fl == (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE)) ||
363 !fl || (fl == FTRACE_FL_NOTRACE))
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530364 return 0;
Steven Rostedt5072c592008-05-12 21:20:43 +0200365
366 /*
367 * If it is enabled disable it,
368 * otherwise enable it!
369 */
Abhishek Sagara4500b82008-06-14 11:59:39 +0530370 if (fl & FTRACE_FL_ENABLED) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200371 /* swap new and old */
372 new = old;
373 old = ftrace_call_replace(ip, FTRACE_ADDR);
374 rec->flags &= ~FTRACE_FL_ENABLED;
375 } else {
376 new = ftrace_call_replace(ip, FTRACE_ADDR);
377 rec->flags |= FTRACE_FL_ENABLED;
378 }
379 } else {
380
Steven Rostedt41c52c02008-05-22 11:46:33 -0400381 if (enable) {
382 /*
383 * If this record is set not to trace and is
384 * not enabled, do nothing.
385 */
386 fl = rec->flags & (FTRACE_FL_NOTRACE | FTRACE_FL_ENABLED);
387 if (fl == FTRACE_FL_NOTRACE)
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530388 return 0;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400389
Steven Rostedt5072c592008-05-12 21:20:43 +0200390 new = ftrace_call_replace(ip, FTRACE_ADDR);
Steven Rostedt41c52c02008-05-22 11:46:33 -0400391 } else
Steven Rostedt5072c592008-05-12 21:20:43 +0200392 old = ftrace_call_replace(ip, FTRACE_ADDR);
393
394 if (enable) {
395 if (rec->flags & FTRACE_FL_ENABLED)
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530396 return 0;
Steven Rostedt5072c592008-05-12 21:20:43 +0200397 rec->flags |= FTRACE_FL_ENABLED;
398 } else {
399 if (!(rec->flags & FTRACE_FL_ENABLED))
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530400 return 0;
Steven Rostedt5072c592008-05-12 21:20:43 +0200401 rec->flags &= ~FTRACE_FL_ENABLED;
402 }
403 }
404
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530405 return ftrace_modify_code(ip, old, new);
Steven Rostedt5072c592008-05-12 21:20:43 +0200406}
407
Ingo Molnare309b412008-05-12 21:20:51 +0200408static void ftrace_replace_code(int enable)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200409{
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530410 int i, failed;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200411 unsigned char *new = NULL, *old = NULL;
412 struct dyn_ftrace *rec;
413 struct ftrace_page *pg;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200414
Steven Rostedt5072c592008-05-12 21:20:43 +0200415 if (enable)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200416 old = ftrace_nop_replace();
417 else
418 new = ftrace_nop_replace();
419
420 for (pg = ftrace_pages_start; pg; pg = pg->next) {
421 for (i = 0; i < pg->index; i++) {
422 rec = &pg->records[i];
423
424 /* don't modify code that has already faulted */
425 if (rec->flags & FTRACE_FL_FAILED)
426 continue;
427
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530428 /* ignore updates to this record's mcount site */
Abhishek Sagar98a05ed2008-06-26 22:51:51 +0530429 if (get_kprobe((void *)rec->ip)) {
430 freeze_record(rec);
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530431 continue;
Abhishek Sagar98a05ed2008-06-26 22:51:51 +0530432 } else {
433 unfreeze_record(rec);
434 }
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530435
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530436 failed = __ftrace_replace_code(rec, old, new, enable);
437 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
438 rec->flags |= FTRACE_FL_FAILED;
439 if ((system_state == SYSTEM_BOOTING) ||
Abhishek Sagar34078a52008-06-03 08:33:41 +0530440 !core_kernel_text(rec->ip)) {
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530441 ftrace_free_rec(rec);
442 }
443 }
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200444 }
445 }
446}
447
Steven Rostedt05736a42008-09-22 14:55:47 -0700448static void print_ip_ins(const char *fmt, unsigned char *p)
449{
450 int i;
451
452 printk(KERN_CONT "%s", fmt);
453
454 for (i = 0; i < MCOUNT_INSN_SIZE; i++)
455 printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
456}
457
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530458static int
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200459ftrace_code_disable(struct dyn_ftrace *rec)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200460{
461 unsigned long ip;
462 unsigned char *nop, *call;
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400463 int ret;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200464
465 ip = rec->ip;
466
467 nop = ftrace_nop_replace();
Steven Rostedt3b47bfc2008-08-27 23:24:15 -0400468 call = ftrace_call_replace(ip, mcount_addr);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200469
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400470 ret = ftrace_modify_code(ip, call, nop);
471 if (ret) {
472 switch (ret) {
473 case -EFAULT:
Steven Rostedt69128962008-10-23 09:33:03 -0400474 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt05736a42008-09-22 14:55:47 -0700475 pr_info("ftrace faulted on modifying ");
476 print_ip_sym(ip);
477 break;
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400478 case -EINVAL:
Steven Rostedt69128962008-10-23 09:33:03 -0400479 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt05736a42008-09-22 14:55:47 -0700480 pr_info("ftrace failed to modify ");
481 print_ip_sym(ip);
482 print_ip_ins(" expected: ", call);
483 print_ip_ins(" actual: ", (unsigned char *)ip);
484 print_ip_ins(" replace: ", nop);
485 printk(KERN_CONT "\n");
486 break;
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400487 case -EPERM:
Steven Rostedt69128962008-10-23 09:33:03 -0400488 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400489 pr_info("ftrace faulted on writing ");
490 print_ip_sym(ip);
491 break;
492 default:
Steven Rostedt69128962008-10-23 09:33:03 -0400493 FTRACE_WARN_ON_ONCE(1);
Steven Rostedt593eb8a2008-10-23 09:32:59 -0400494 pr_info("ftrace faulted on unknown error ");
495 print_ip_sym(ip);
Steven Rostedt05736a42008-09-22 14:55:47 -0700496 }
497
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200498 rec->flags |= FTRACE_FL_FAILED;
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530499 return 0;
Steven Rostedt37ad5082008-05-12 21:20:48 +0200500 }
Abhishek Sagar492a7ea2008-05-25 00:10:04 +0530501 return 1;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200502}
503
Ingo Molnare309b412008-05-12 21:20:51 +0200504static int __ftrace_modify_code(void *data)
Steven Rostedt3d083392008-05-12 21:20:42 +0200505{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200506 int *command = data;
507
Steven Rostedta3583242008-11-11 15:01:42 -0500508 if (*command & FTRACE_ENABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200509 ftrace_replace_code(1);
Steven Rostedta3583242008-11-11 15:01:42 -0500510 else if (*command & FTRACE_DISABLE_CALLS)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200511 ftrace_replace_code(0);
512
513 if (*command & FTRACE_UPDATE_TRACE_FUNC)
514 ftrace_update_ftrace_func(ftrace_trace_function);
515
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200516 return 0;
Steven Rostedt3d083392008-05-12 21:20:42 +0200517}
518
Ingo Molnare309b412008-05-12 21:20:51 +0200519static void ftrace_run_update_code(int command)
Steven Rostedt3d083392008-05-12 21:20:42 +0200520{
Rusty Russell784e2d72008-07-28 12:16:31 -0500521 stop_machine(__ftrace_modify_code, &command, NULL);
Steven Rostedt3d083392008-05-12 21:20:42 +0200522}
523
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200524static ftrace_func_t saved_ftrace_func;
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400525static int ftrace_start;
526static DEFINE_MUTEX(ftrace_start_lock);
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200527
Ingo Molnare309b412008-05-12 21:20:51 +0200528static void ftrace_startup(void)
Steven Rostedt3d083392008-05-12 21:20:42 +0200529{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200530 int command = 0;
531
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200532 if (unlikely(ftrace_disabled))
533 return;
534
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400535 mutex_lock(&ftrace_start_lock);
536 ftrace_start++;
537 if (ftrace_start == 1)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200538 command |= FTRACE_ENABLE_CALLS;
Steven Rostedt3d083392008-05-12 21:20:42 +0200539
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200540 if (saved_ftrace_func != ftrace_trace_function) {
541 saved_ftrace_func = ftrace_trace_function;
542 command |= FTRACE_UPDATE_TRACE_FUNC;
543 }
544
545 if (!command || !ftrace_enabled)
546 goto out;
547
548 ftrace_run_update_code(command);
Steven Rostedt3d083392008-05-12 21:20:42 +0200549 out:
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400550 mutex_unlock(&ftrace_start_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200551}
552
Ingo Molnare309b412008-05-12 21:20:51 +0200553static void ftrace_shutdown(void)
Steven Rostedt3d083392008-05-12 21:20:42 +0200554{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200555 int command = 0;
556
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200557 if (unlikely(ftrace_disabled))
558 return;
559
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400560 mutex_lock(&ftrace_start_lock);
561 ftrace_start--;
562 if (!ftrace_start)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200563 command |= FTRACE_DISABLE_CALLS;
564
565 if (saved_ftrace_func != ftrace_trace_function) {
566 saved_ftrace_func = ftrace_trace_function;
567 command |= FTRACE_UPDATE_TRACE_FUNC;
568 }
569
570 if (!command || !ftrace_enabled)
Steven Rostedt3d083392008-05-12 21:20:42 +0200571 goto out;
572
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200573 ftrace_run_update_code(command);
Steven Rostedt3d083392008-05-12 21:20:42 +0200574 out:
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400575 mutex_unlock(&ftrace_start_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +0200576}
577
Ingo Molnare309b412008-05-12 21:20:51 +0200578static void ftrace_startup_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200579{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200580 int command = FTRACE_ENABLE_MCOUNT;
581
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200582 if (unlikely(ftrace_disabled))
583 return;
584
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400585 mutex_lock(&ftrace_start_lock);
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200586 /* Force update next time */
587 saved_ftrace_func = NULL;
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400588 /* ftrace_start is true if we want ftrace running */
589 if (ftrace_start)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200590 command |= FTRACE_ENABLE_CALLS;
591
592 ftrace_run_update_code(command);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400593 mutex_unlock(&ftrace_start_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200594}
595
Ingo Molnare309b412008-05-12 21:20:51 +0200596static void ftrace_shutdown_sysctl(void)
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200597{
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200598 int command = FTRACE_DISABLE_MCOUNT;
599
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200600 if (unlikely(ftrace_disabled))
601 return;
602
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400603 mutex_lock(&ftrace_start_lock);
604 /* ftrace_start is true if ftrace is running */
605 if (ftrace_start)
Steven Rostedtd61f82d2008-05-12 21:20:43 +0200606 command |= FTRACE_DISABLE_CALLS;
607
608 ftrace_run_update_code(command);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -0400609 mutex_unlock(&ftrace_start_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +0200610}
611
Steven Rostedt3d083392008-05-12 21:20:42 +0200612static cycle_t ftrace_update_time;
613static unsigned long ftrace_update_cnt;
614unsigned long ftrace_update_tot_cnt;
615
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400616static int ftrace_update_code(void)
Steven Rostedt3d083392008-05-12 21:20:42 +0200617{
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400618 struct dyn_ftrace *p, *t;
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530619 cycle_t start, stop;
Steven Rostedt3d083392008-05-12 21:20:42 +0200620
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200621 start = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200622 ftrace_update_cnt = 0;
623
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400624 list_for_each_entry_safe(p, t, &ftrace_new_addrs, list) {
Abhishek Sagarf22f9a82008-06-21 23:50:29 +0530625
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400626 /* If something went wrong, bail without enabling anything */
627 if (unlikely(ftrace_disabled))
628 return -1;
Steven Rostedt3d083392008-05-12 21:20:42 +0200629
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400630 list_del_init(&p->list);
Abhishek Sagar0eb96702008-06-01 21:47:30 +0530631
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400632 /* convert record (i.e, patch mcount-call with NOP) */
633 if (ftrace_code_disable(p)) {
634 p->flags |= FTRACE_FL_CONVERTED;
635 ftrace_update_cnt++;
636 } else
637 ftrace_free_rec(p);
Steven Rostedt3d083392008-05-12 21:20:42 +0200638 }
639
Ingo Molnar750ed1a2008-05-12 21:20:46 +0200640 stop = ftrace_now(raw_smp_processor_id());
Steven Rostedt3d083392008-05-12 21:20:42 +0200641 ftrace_update_time = stop - start;
642 ftrace_update_tot_cnt += ftrace_update_cnt;
643
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +0200644 return 0;
645}
646
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400647static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200648{
649 struct ftrace_page *pg;
650 int cnt;
651 int i;
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200652
653 /* allocate a few pages */
654 ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
655 if (!ftrace_pages_start)
656 return -1;
657
658 /*
659 * Allocate a few more pages.
660 *
661 * TODO: have some parser search vmlinux before
662 * final linking to find all calls to ftrace.
663 * Then we can:
664 * a) know how many pages to allocate.
665 * and/or
666 * b) set up the table then.
667 *
668 * The dynamic code is still necessary for
669 * modules.
670 */
671
672 pg = ftrace_pages = ftrace_pages_start;
673
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400674 cnt = num_to_init / ENTRIES_PER_PAGE;
Steven Rostedt08f5ac902008-10-23 09:33:07 -0400675 pr_info("ftrace: allocating %ld entries in %d pages\n",
Steven Rostedt68bf21a2008-08-14 15:45:08 -0400676 num_to_init, cnt);
Steven Rostedt3c1720f2008-05-12 21:20:43 +0200677
678 for (i = 0; i < cnt; i++) {
679 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
680
681 /* If we fail, we'll try later anyway */
682 if (!pg->next)
683 break;
684
685 pg = pg->next;
686 }
687
688 return 0;
689}
690
Steven Rostedt5072c592008-05-12 21:20:43 +0200691enum {
692 FTRACE_ITER_FILTER = (1 << 0),
693 FTRACE_ITER_CONT = (1 << 1),
Steven Rostedt41c52c02008-05-22 11:46:33 -0400694 FTRACE_ITER_NOTRACE = (1 << 2),
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530695 FTRACE_ITER_FAILURES = (1 << 3),
Steven Rostedt5072c592008-05-12 21:20:43 +0200696};
697
698#define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */
699
700struct ftrace_iterator {
701 loff_t pos;
702 struct ftrace_page *pg;
703 unsigned idx;
704 unsigned flags;
705 unsigned char buffer[FTRACE_BUFF_MAX+1];
706 unsigned buffer_idx;
707 unsigned filtered;
708};
709
Ingo Molnare309b412008-05-12 21:20:51 +0200710static void *
Steven Rostedt5072c592008-05-12 21:20:43 +0200711t_next(struct seq_file *m, void *v, loff_t *pos)
712{
713 struct ftrace_iterator *iter = m->private;
714 struct dyn_ftrace *rec = NULL;
715
716 (*pos)++;
717
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400718 /* should not be called from interrupt context */
719 spin_lock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200720 retry:
721 if (iter->idx >= iter->pg->index) {
722 if (iter->pg->next) {
723 iter->pg = iter->pg->next;
724 iter->idx = 0;
725 goto retry;
726 }
727 } else {
728 rec = &iter->pg->records[iter->idx++];
Steven Rostedta9fdda32008-08-14 22:47:17 -0400729 if ((rec->flags & FTRACE_FL_FREE) ||
730
731 (!(iter->flags & FTRACE_ITER_FAILURES) &&
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530732 (rec->flags & FTRACE_FL_FAILED)) ||
733
734 ((iter->flags & FTRACE_ITER_FAILURES) &&
Steven Rostedta9fdda32008-08-14 22:47:17 -0400735 !(rec->flags & FTRACE_FL_FAILED)) ||
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530736
Steven Rostedt41c52c02008-05-22 11:46:33 -0400737 ((iter->flags & FTRACE_ITER_NOTRACE) &&
738 !(rec->flags & FTRACE_FL_NOTRACE))) {
Steven Rostedt5072c592008-05-12 21:20:43 +0200739 rec = NULL;
740 goto retry;
741 }
742 }
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400743 spin_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200744
745 iter->pos = *pos;
746
747 return rec;
748}
749
750static void *t_start(struct seq_file *m, loff_t *pos)
751{
752 struct ftrace_iterator *iter = m->private;
753 void *p = NULL;
754 loff_t l = -1;
755
756 if (*pos != iter->pos) {
757 for (p = t_next(m, p, &l); p && l < *pos; p = t_next(m, p, &l))
758 ;
759 } else {
760 l = *pos;
761 p = t_next(m, p, &l);
762 }
763
764 return p;
765}
766
767static void t_stop(struct seq_file *m, void *p)
768{
769}
770
771static int t_show(struct seq_file *m, void *v)
772{
773 struct dyn_ftrace *rec = v;
774 char str[KSYM_SYMBOL_LEN];
775
776 if (!rec)
777 return 0;
778
779 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
780
781 seq_printf(m, "%s\n", str);
782
783 return 0;
784}
785
786static struct seq_operations show_ftrace_seq_ops = {
787 .start = t_start,
788 .next = t_next,
789 .stop = t_stop,
790 .show = t_show,
791};
792
Ingo Molnare309b412008-05-12 21:20:51 +0200793static int
Steven Rostedt5072c592008-05-12 21:20:43 +0200794ftrace_avail_open(struct inode *inode, struct file *file)
795{
796 struct ftrace_iterator *iter;
797 int ret;
798
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200799 if (unlikely(ftrace_disabled))
800 return -ENODEV;
801
Steven Rostedt5072c592008-05-12 21:20:43 +0200802 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
803 if (!iter)
804 return -ENOMEM;
805
806 iter->pg = ftrace_pages_start;
807 iter->pos = -1;
808
809 ret = seq_open(file, &show_ftrace_seq_ops);
810 if (!ret) {
811 struct seq_file *m = file->private_data;
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200812
Steven Rostedt5072c592008-05-12 21:20:43 +0200813 m->private = iter;
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200814 } else {
Steven Rostedt5072c592008-05-12 21:20:43 +0200815 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200816 }
Steven Rostedt5072c592008-05-12 21:20:43 +0200817
818 return ret;
819}
820
821int ftrace_avail_release(struct inode *inode, struct file *file)
822{
823 struct seq_file *m = (struct seq_file *)file->private_data;
824 struct ftrace_iterator *iter = m->private;
825
826 seq_release(inode, file);
827 kfree(iter);
Ingo Molnar4bf39a92008-05-12 21:20:46 +0200828
Steven Rostedt5072c592008-05-12 21:20:43 +0200829 return 0;
830}
831
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +0530832static int
833ftrace_failures_open(struct inode *inode, struct file *file)
834{
835 int ret;
836 struct seq_file *m;
837 struct ftrace_iterator *iter;
838
839 ret = ftrace_avail_open(inode, file);
840 if (!ret) {
841 m = (struct seq_file *)file->private_data;
842 iter = (struct ftrace_iterator *)m->private;
843 iter->flags = FTRACE_ITER_FAILURES;
844 }
845
846 return ret;
847}
848
849
Steven Rostedt41c52c02008-05-22 11:46:33 -0400850static void ftrace_filter_reset(int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +0200851{
852 struct ftrace_page *pg;
853 struct dyn_ftrace *rec;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400854 unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +0200855 unsigned i;
856
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400857 /* should not be called from interrupt context */
858 spin_lock(&ftrace_lock);
Steven Rostedt41c52c02008-05-22 11:46:33 -0400859 if (enable)
860 ftrace_filtered = 0;
Steven Rostedt5072c592008-05-12 21:20:43 +0200861 pg = ftrace_pages_start;
862 while (pg) {
863 for (i = 0; i < pg->index; i++) {
864 rec = &pg->records[i];
865 if (rec->flags & FTRACE_FL_FAILED)
866 continue;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400867 rec->flags &= ~type;
Steven Rostedt5072c592008-05-12 21:20:43 +0200868 }
869 pg = pg->next;
870 }
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400871 spin_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200872}
873
Ingo Molnare309b412008-05-12 21:20:51 +0200874static int
Steven Rostedt41c52c02008-05-22 11:46:33 -0400875ftrace_regex_open(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +0200876{
877 struct ftrace_iterator *iter;
878 int ret = 0;
879
Steven Rostedt4eebcc82008-05-12 21:20:48 +0200880 if (unlikely(ftrace_disabled))
881 return -ENODEV;
882
Steven Rostedt5072c592008-05-12 21:20:43 +0200883 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
884 if (!iter)
885 return -ENOMEM;
886
Steven Rostedt41c52c02008-05-22 11:46:33 -0400887 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200888 if ((file->f_mode & FMODE_WRITE) &&
889 !(file->f_flags & O_APPEND))
Steven Rostedt41c52c02008-05-22 11:46:33 -0400890 ftrace_filter_reset(enable);
Steven Rostedt5072c592008-05-12 21:20:43 +0200891
892 if (file->f_mode & FMODE_READ) {
893 iter->pg = ftrace_pages_start;
894 iter->pos = -1;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400895 iter->flags = enable ? FTRACE_ITER_FILTER :
896 FTRACE_ITER_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +0200897
898 ret = seq_open(file, &show_ftrace_seq_ops);
899 if (!ret) {
900 struct seq_file *m = file->private_data;
901 m->private = iter;
902 } else
903 kfree(iter);
904 } else
905 file->private_data = iter;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400906 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +0200907
908 return ret;
909}
910
Steven Rostedt41c52c02008-05-22 11:46:33 -0400911static int
912ftrace_filter_open(struct inode *inode, struct file *file)
913{
914 return ftrace_regex_open(inode, file, 1);
915}
916
917static int
918ftrace_notrace_open(struct inode *inode, struct file *file)
919{
920 return ftrace_regex_open(inode, file, 0);
921}
922
Ingo Molnare309b412008-05-12 21:20:51 +0200923static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -0400924ftrace_regex_read(struct file *file, char __user *ubuf,
Steven Rostedt5072c592008-05-12 21:20:43 +0200925 size_t cnt, loff_t *ppos)
926{
927 if (file->f_mode & FMODE_READ)
928 return seq_read(file, ubuf, cnt, ppos);
929 else
930 return -EPERM;
931}
932
Ingo Molnare309b412008-05-12 21:20:51 +0200933static loff_t
Steven Rostedt41c52c02008-05-22 11:46:33 -0400934ftrace_regex_lseek(struct file *file, loff_t offset, int origin)
Steven Rostedt5072c592008-05-12 21:20:43 +0200935{
936 loff_t ret;
937
938 if (file->f_mode & FMODE_READ)
939 ret = seq_lseek(file, offset, origin);
940 else
941 file->f_pos = ret = 1;
942
943 return ret;
944}
945
946enum {
947 MATCH_FULL,
948 MATCH_FRONT_ONLY,
949 MATCH_MIDDLE_ONLY,
950 MATCH_END_ONLY,
951};
952
Ingo Molnare309b412008-05-12 21:20:51 +0200953static void
Steven Rostedt41c52c02008-05-22 11:46:33 -0400954ftrace_match(unsigned char *buff, int len, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +0200955{
956 char str[KSYM_SYMBOL_LEN];
957 char *search = NULL;
958 struct ftrace_page *pg;
959 struct dyn_ftrace *rec;
960 int type = MATCH_FULL;
Steven Rostedt41c52c02008-05-22 11:46:33 -0400961 unsigned long flag = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
Steven Rostedt5072c592008-05-12 21:20:43 +0200962 unsigned i, match = 0, search_len = 0;
963
964 for (i = 0; i < len; i++) {
965 if (buff[i] == '*') {
966 if (!i) {
967 search = buff + i + 1;
968 type = MATCH_END_ONLY;
969 search_len = len - (i + 1);
970 } else {
971 if (type == MATCH_END_ONLY) {
972 type = MATCH_MIDDLE_ONLY;
973 } else {
974 match = i;
975 type = MATCH_FRONT_ONLY;
976 }
977 buff[i] = 0;
978 break;
979 }
980 }
981 }
982
Steven Rostedt99ecdc42008-08-15 21:40:05 -0400983 /* should not be called from interrupt context */
984 spin_lock(&ftrace_lock);
Steven Rostedt41c52c02008-05-22 11:46:33 -0400985 if (enable)
986 ftrace_filtered = 1;
Steven Rostedt5072c592008-05-12 21:20:43 +0200987 pg = ftrace_pages_start;
988 while (pg) {
989 for (i = 0; i < pg->index; i++) {
990 int matched = 0;
991 char *ptr;
992
993 rec = &pg->records[i];
994 if (rec->flags & FTRACE_FL_FAILED)
995 continue;
996 kallsyms_lookup(rec->ip, NULL, NULL, NULL, str);
997 switch (type) {
998 case MATCH_FULL:
999 if (strcmp(str, buff) == 0)
1000 matched = 1;
1001 break;
1002 case MATCH_FRONT_ONLY:
1003 if (memcmp(str, buff, match) == 0)
1004 matched = 1;
1005 break;
1006 case MATCH_MIDDLE_ONLY:
1007 if (strstr(str, search))
1008 matched = 1;
1009 break;
1010 case MATCH_END_ONLY:
1011 ptr = strstr(str, search);
1012 if (ptr && (ptr[search_len] == 0))
1013 matched = 1;
1014 break;
1015 }
1016 if (matched)
Steven Rostedt41c52c02008-05-22 11:46:33 -04001017 rec->flags |= flag;
Steven Rostedt5072c592008-05-12 21:20:43 +02001018 }
1019 pg = pg->next;
1020 }
Steven Rostedt99ecdc42008-08-15 21:40:05 -04001021 spin_unlock(&ftrace_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001022}
1023
Ingo Molnare309b412008-05-12 21:20:51 +02001024static ssize_t
Steven Rostedt41c52c02008-05-22 11:46:33 -04001025ftrace_regex_write(struct file *file, const char __user *ubuf,
1026 size_t cnt, loff_t *ppos, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001027{
1028 struct ftrace_iterator *iter;
1029 char ch;
1030 size_t read = 0;
1031 ssize_t ret;
1032
1033 if (!cnt || cnt < 0)
1034 return 0;
1035
Steven Rostedt41c52c02008-05-22 11:46:33 -04001036 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001037
1038 if (file->f_mode & FMODE_READ) {
1039 struct seq_file *m = file->private_data;
1040 iter = m->private;
1041 } else
1042 iter = file->private_data;
1043
1044 if (!*ppos) {
1045 iter->flags &= ~FTRACE_ITER_CONT;
1046 iter->buffer_idx = 0;
1047 }
1048
1049 ret = get_user(ch, ubuf++);
1050 if (ret)
1051 goto out;
1052 read++;
1053 cnt--;
1054
1055 if (!(iter->flags & ~FTRACE_ITER_CONT)) {
1056 /* skip white space */
1057 while (cnt && isspace(ch)) {
1058 ret = get_user(ch, ubuf++);
1059 if (ret)
1060 goto out;
1061 read++;
1062 cnt--;
1063 }
1064
Steven Rostedt5072c592008-05-12 21:20:43 +02001065 if (isspace(ch)) {
1066 file->f_pos += read;
1067 ret = read;
1068 goto out;
1069 }
1070
1071 iter->buffer_idx = 0;
1072 }
1073
1074 while (cnt && !isspace(ch)) {
1075 if (iter->buffer_idx < FTRACE_BUFF_MAX)
1076 iter->buffer[iter->buffer_idx++] = ch;
1077 else {
1078 ret = -EINVAL;
1079 goto out;
1080 }
1081 ret = get_user(ch, ubuf++);
1082 if (ret)
1083 goto out;
1084 read++;
1085 cnt--;
1086 }
1087
1088 if (isspace(ch)) {
1089 iter->filtered++;
1090 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001091 ftrace_match(iter->buffer, iter->buffer_idx, enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001092 iter->buffer_idx = 0;
1093 } else
1094 iter->flags |= FTRACE_ITER_CONT;
1095
1096
1097 file->f_pos += read;
1098
1099 ret = read;
1100 out:
Steven Rostedt41c52c02008-05-22 11:46:33 -04001101 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001102
1103 return ret;
1104}
1105
Steven Rostedt41c52c02008-05-22 11:46:33 -04001106static ssize_t
1107ftrace_filter_write(struct file *file, const char __user *ubuf,
1108 size_t cnt, loff_t *ppos)
1109{
1110 return ftrace_regex_write(file, ubuf, cnt, ppos, 1);
1111}
1112
1113static ssize_t
1114ftrace_notrace_write(struct file *file, const char __user *ubuf,
1115 size_t cnt, loff_t *ppos)
1116{
1117 return ftrace_regex_write(file, ubuf, cnt, ppos, 0);
1118}
1119
1120static void
1121ftrace_set_regex(unsigned char *buf, int len, int reset, int enable)
1122{
1123 if (unlikely(ftrace_disabled))
1124 return;
1125
1126 mutex_lock(&ftrace_regex_lock);
1127 if (reset)
1128 ftrace_filter_reset(enable);
1129 if (buf)
1130 ftrace_match(buf, len, enable);
1131 mutex_unlock(&ftrace_regex_lock);
1132}
1133
Steven Rostedt77a2b372008-05-12 21:20:45 +02001134/**
1135 * ftrace_set_filter - set a function to filter on in ftrace
1136 * @buf - the string that holds the function filter text.
1137 * @len - the length of the string.
1138 * @reset - non zero to reset all filters before applying this filter.
1139 *
1140 * Filters denote which functions should be enabled when tracing is enabled.
1141 * If @buf is NULL and reset is set, all functions will be enabled for tracing.
1142 */
Ingo Molnare309b412008-05-12 21:20:51 +02001143void ftrace_set_filter(unsigned char *buf, int len, int reset)
Steven Rostedt77a2b372008-05-12 21:20:45 +02001144{
Steven Rostedt41c52c02008-05-22 11:46:33 -04001145 ftrace_set_regex(buf, len, reset, 1);
1146}
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001147
Steven Rostedt41c52c02008-05-22 11:46:33 -04001148/**
1149 * ftrace_set_notrace - set a function to not trace in ftrace
1150 * @buf - the string that holds the function notrace text.
1151 * @len - the length of the string.
1152 * @reset - non zero to reset all filters before applying this filter.
1153 *
1154 * Notrace Filters denote which functions should not be enabled when tracing
1155 * is enabled. If @buf is NULL and reset is set, all functions will be enabled
1156 * for tracing.
1157 */
1158void ftrace_set_notrace(unsigned char *buf, int len, int reset)
1159{
1160 ftrace_set_regex(buf, len, reset, 0);
Steven Rostedt77a2b372008-05-12 21:20:45 +02001161}
1162
Ingo Molnare309b412008-05-12 21:20:51 +02001163static int
Steven Rostedt41c52c02008-05-22 11:46:33 -04001164ftrace_regex_release(struct inode *inode, struct file *file, int enable)
Steven Rostedt5072c592008-05-12 21:20:43 +02001165{
1166 struct seq_file *m = (struct seq_file *)file->private_data;
1167 struct ftrace_iterator *iter;
1168
Steven Rostedt41c52c02008-05-22 11:46:33 -04001169 mutex_lock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001170 if (file->f_mode & FMODE_READ) {
1171 iter = m->private;
1172
1173 seq_release(inode, file);
1174 } else
1175 iter = file->private_data;
1176
1177 if (iter->buffer_idx) {
1178 iter->filtered++;
1179 iter->buffer[iter->buffer_idx] = 0;
Steven Rostedt41c52c02008-05-22 11:46:33 -04001180 ftrace_match(iter->buffer, iter->buffer_idx, enable);
Steven Rostedt5072c592008-05-12 21:20:43 +02001181 }
1182
1183 mutex_lock(&ftrace_sysctl_lock);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -04001184 mutex_lock(&ftrace_start_lock);
1185 if (iter->filtered && ftrace_start && ftrace_enabled)
Steven Rostedt5072c592008-05-12 21:20:43 +02001186 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
Steven Rostedtcb7be3b2008-10-23 09:33:05 -04001187 mutex_unlock(&ftrace_start_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001188 mutex_unlock(&ftrace_sysctl_lock);
1189
1190 kfree(iter);
Steven Rostedt41c52c02008-05-22 11:46:33 -04001191 mutex_unlock(&ftrace_regex_lock);
Steven Rostedt5072c592008-05-12 21:20:43 +02001192 return 0;
1193}
1194
Steven Rostedt41c52c02008-05-22 11:46:33 -04001195static int
1196ftrace_filter_release(struct inode *inode, struct file *file)
1197{
1198 return ftrace_regex_release(inode, file, 1);
1199}
1200
1201static int
1202ftrace_notrace_release(struct inode *inode, struct file *file)
1203{
1204 return ftrace_regex_release(inode, file, 0);
1205}
1206
Steven Rostedt5072c592008-05-12 21:20:43 +02001207static struct file_operations ftrace_avail_fops = {
1208 .open = ftrace_avail_open,
1209 .read = seq_read,
1210 .llseek = seq_lseek,
1211 .release = ftrace_avail_release,
1212};
1213
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301214static struct file_operations ftrace_failures_fops = {
1215 .open = ftrace_failures_open,
1216 .read = seq_read,
1217 .llseek = seq_lseek,
1218 .release = ftrace_avail_release,
1219};
1220
Steven Rostedt5072c592008-05-12 21:20:43 +02001221static struct file_operations ftrace_filter_fops = {
1222 .open = ftrace_filter_open,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001223 .read = ftrace_regex_read,
Steven Rostedt5072c592008-05-12 21:20:43 +02001224 .write = ftrace_filter_write,
Steven Rostedt41c52c02008-05-22 11:46:33 -04001225 .llseek = ftrace_regex_lseek,
Steven Rostedt5072c592008-05-12 21:20:43 +02001226 .release = ftrace_filter_release,
1227};
1228
Steven Rostedt41c52c02008-05-22 11:46:33 -04001229static struct file_operations ftrace_notrace_fops = {
1230 .open = ftrace_notrace_open,
1231 .read = ftrace_regex_read,
1232 .write = ftrace_notrace_write,
1233 .llseek = ftrace_regex_lseek,
1234 .release = ftrace_notrace_release,
1235};
1236
Steven Rostedt5072c592008-05-12 21:20:43 +02001237static __init int ftrace_init_debugfs(void)
1238{
1239 struct dentry *d_tracer;
1240 struct dentry *entry;
1241
1242 d_tracer = tracing_init_dentry();
1243
1244 entry = debugfs_create_file("available_filter_functions", 0444,
1245 d_tracer, NULL, &ftrace_avail_fops);
1246 if (!entry)
1247 pr_warning("Could not create debugfs "
1248 "'available_filter_functions' entry\n");
1249
Abhishek Sagareb9a7bf2008-06-01 21:47:54 +05301250 entry = debugfs_create_file("failures", 0444,
1251 d_tracer, NULL, &ftrace_failures_fops);
1252 if (!entry)
1253 pr_warning("Could not create debugfs 'failures' entry\n");
1254
Steven Rostedt5072c592008-05-12 21:20:43 +02001255 entry = debugfs_create_file("set_ftrace_filter", 0644, d_tracer,
1256 NULL, &ftrace_filter_fops);
1257 if (!entry)
1258 pr_warning("Could not create debugfs "
1259 "'set_ftrace_filter' entry\n");
Steven Rostedt41c52c02008-05-22 11:46:33 -04001260
1261 entry = debugfs_create_file("set_ftrace_notrace", 0644, d_tracer,
1262 NULL, &ftrace_notrace_fops);
1263 if (!entry)
1264 pr_warning("Could not create debugfs "
1265 "'set_ftrace_notrace' entry\n");
Steven Rostedtad90c0e2008-05-27 20:48:37 -04001266
Steven Rostedt5072c592008-05-12 21:20:43 +02001267 return 0;
1268}
1269
1270fs_initcall(ftrace_init_debugfs);
1271
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001272static int ftrace_convert_nops(unsigned long *start,
1273 unsigned long *end)
1274{
1275 unsigned long *p;
1276 unsigned long addr;
1277 unsigned long flags;
1278
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001279 mutex_lock(&ftrace_start_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001280 p = start;
1281 while (p < end) {
1282 addr = ftrace_call_adjust(*p++);
1283 ftrace_record_ip(addr);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001284 }
1285
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001286 /* disable interrupts to prevent kstop machine */
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001287 local_irq_save(flags);
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001288 ftrace_update_code();
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001289 local_irq_restore(flags);
Steven Rostedt08f5ac902008-10-23 09:33:07 -04001290 mutex_unlock(&ftrace_start_lock);
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001291
1292 return 0;
1293}
1294
Steven Rostedt90d595f2008-08-14 15:45:09 -04001295void ftrace_init_module(unsigned long *start, unsigned long *end)
1296{
Steven Rostedt00fd61a2008-08-15 21:40:04 -04001297 if (ftrace_disabled || start == end)
Steven Rostedtfed19392008-08-14 22:47:19 -04001298 return;
Steven Rostedt90d595f2008-08-14 15:45:09 -04001299 ftrace_convert_nops(start, end);
1300}
1301
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001302extern unsigned long __start_mcount_loc[];
1303extern unsigned long __stop_mcount_loc[];
1304
1305void __init ftrace_init(void)
1306{
1307 unsigned long count, addr, flags;
1308 int ret;
1309
1310 /* Keep the ftrace pointer to the stub */
1311 addr = (unsigned long)ftrace_stub;
1312
1313 local_irq_save(flags);
1314 ftrace_dyn_arch_init(&addr);
1315 local_irq_restore(flags);
1316
1317 /* ftrace_dyn_arch_init places the return code in addr */
1318 if (addr)
1319 goto failed;
1320
1321 count = __stop_mcount_loc - __start_mcount_loc;
1322
1323 ret = ftrace_dyn_table_alloc(count);
1324 if (ret)
1325 goto failed;
1326
1327 last_ftrace_enabled = ftrace_enabled = 1;
1328
1329 ret = ftrace_convert_nops(__start_mcount_loc,
1330 __stop_mcount_loc);
1331
1332 return;
1333 failed:
1334 ftrace_disabled = 1;
1335}
Steven Rostedt68bf21a2008-08-14 15:45:08 -04001336
Steven Rostedt3d083392008-05-12 21:20:42 +02001337#else
Frederic Weisbecker0b6e4d52008-10-28 20:17:38 +01001338
1339static int __init ftrace_nodyn_init(void)
1340{
1341 ftrace_enabled = 1;
1342 return 0;
1343}
1344device_initcall(ftrace_nodyn_init);
1345
Ingo Molnarc7aafc52008-05-12 21:20:45 +02001346# define ftrace_startup() do { } while (0)
1347# define ftrace_shutdown() do { } while (0)
1348# define ftrace_startup_sysctl() do { } while (0)
1349# define ftrace_shutdown_sysctl() do { } while (0)
Steven Rostedt3d083392008-05-12 21:20:42 +02001350#endif /* CONFIG_DYNAMIC_FTRACE */
1351
1352/**
Steven Rostedt81adbdc2008-10-23 09:33:02 -04001353 * ftrace_kill - kill ftrace
Steven Rostedta2bb6a32008-07-10 20:58:15 -04001354 *
1355 * This function should be used by panic code. It stops ftrace
1356 * but in a not so nice way. If you need to simply kill ftrace
1357 * from a non-atomic section, use ftrace_kill.
1358 */
Steven Rostedt81adbdc2008-10-23 09:33:02 -04001359void ftrace_kill(void)
Steven Rostedta2bb6a32008-07-10 20:58:15 -04001360{
1361 ftrace_disabled = 1;
1362 ftrace_enabled = 0;
Steven Rostedta2bb6a32008-07-10 20:58:15 -04001363 clear_ftrace_function();
1364}
1365
1366/**
Steven Rostedt3d083392008-05-12 21:20:42 +02001367 * register_ftrace_function - register a function for profiling
1368 * @ops - ops structure that holds the function for profiling.
1369 *
1370 * Register a function to be called by all functions in the
1371 * kernel.
1372 *
1373 * Note: @ops->func and all the functions it calls must be labeled
1374 * with "notrace", otherwise it will go into a
1375 * recursive loop.
1376 */
1377int register_ftrace_function(struct ftrace_ops *ops)
1378{
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001379 int ret;
1380
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001381 if (unlikely(ftrace_disabled))
1382 return -1;
1383
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001384 mutex_lock(&ftrace_sysctl_lock);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001385 ret = __register_ftrace_function(ops);
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001386 ftrace_startup();
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001387 mutex_unlock(&ftrace_sysctl_lock);
1388
1389 return ret;
Steven Rostedt3d083392008-05-12 21:20:42 +02001390}
1391
1392/**
1393 * unregister_ftrace_function - unresgister a function for profiling.
1394 * @ops - ops structure that holds the function to unregister
1395 *
1396 * Unregister a function that was added to be called by ftrace profiling.
1397 */
1398int unregister_ftrace_function(struct ftrace_ops *ops)
1399{
1400 int ret;
1401
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001402 mutex_lock(&ftrace_sysctl_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02001403 ret = __unregister_ftrace_function(ops);
Steven Rostedtd61f82d2008-05-12 21:20:43 +02001404 ftrace_shutdown();
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001405 mutex_unlock(&ftrace_sysctl_lock);
1406
1407 return ret;
1408}
1409
Ingo Molnare309b412008-05-12 21:20:51 +02001410int
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001411ftrace_enable_sysctl(struct ctl_table *table, int write,
Steven Rostedt5072c592008-05-12 21:20:43 +02001412 struct file *file, void __user *buffer, size_t *lenp,
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001413 loff_t *ppos)
1414{
1415 int ret;
1416
Steven Rostedt4eebcc82008-05-12 21:20:48 +02001417 if (unlikely(ftrace_disabled))
1418 return -ENODEV;
1419
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001420 mutex_lock(&ftrace_sysctl_lock);
1421
Steven Rostedt5072c592008-05-12 21:20:43 +02001422 ret = proc_dointvec(table, write, file, buffer, lenp, ppos);
Steven Rostedtb0fc4942008-05-12 21:20:43 +02001423
1424 if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
1425 goto out;
1426
1427 last_ftrace_enabled = ftrace_enabled;
1428
1429 if (ftrace_enabled) {
1430
1431 ftrace_startup_sysctl();
1432
1433 /* we are starting ftrace again */
1434 if (ftrace_list != &ftrace_list_end) {
1435 if (ftrace_list->next == &ftrace_list_end)
1436 ftrace_trace_function = ftrace_list->func;
1437 else
1438 ftrace_trace_function = ftrace_list_func;
1439 }
1440
1441 } else {
1442 /* stopping ftrace calls (just send to ftrace_stub) */
1443 ftrace_trace_function = ftrace_stub;
1444
1445 ftrace_shutdown_sysctl();
1446 }
1447
1448 out:
1449 mutex_unlock(&ftrace_sysctl_lock);
Steven Rostedt3d083392008-05-12 21:20:42 +02001450 return ret;
Arnaldo Carvalho de Melo16444a82008-05-12 21:20:42 +02001451}
Ingo Molnarf17845e2008-10-24 12:47:10 +02001452