ftrace: move memory management out of arch code
[linux-block.git] / kernel / trace / ftrace.c
CommitLineData
16444a8a
ACM
1/*
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
3d083395
SR
16#include <linux/stop_machine.h>
17#include <linux/clocksource.h>
18#include <linux/kallsyms.h>
19#include <linux/kthread.h>
20#include <linux/hardirq.h>
16444a8a 21#include <linux/ftrace.h>
3d083395 22#include <linux/module.h>
b0fc494f 23#include <linux/sysctl.h>
3d083395
SR
24#include <linux/hash.h>
25#include <linux/list.h>
26
27#include "trace.h"
16444a8a 28
b0fc494f
SR
29#ifdef CONFIG_DYNAMIC_FTRACE
30# define FTRACE_ENABLED_INIT 1
31#else
32# define FTRACE_ENABLED_INIT 0
33#endif
34
35int ftrace_enabled = FTRACE_ENABLED_INIT;
36static int last_ftrace_enabled = FTRACE_ENABLED_INIT;
37
3d083395 38static DEFINE_SPINLOCK(ftrace_lock);
b0fc494f
SR
39static DEFINE_MUTEX(ftrace_sysctl_lock);
40
16444a8a
ACM
41static struct ftrace_ops ftrace_list_end __read_mostly =
42{
43 .func = ftrace_stub,
44};
45
46static struct ftrace_ops *ftrace_list __read_mostly = &ftrace_list_end;
47ftrace_func_t ftrace_trace_function __read_mostly = ftrace_stub;
48
49/* mcount is defined per arch in assembly */
50EXPORT_SYMBOL(mcount);
51
52notrace void ftrace_list_func(unsigned long ip, unsigned long parent_ip)
53{
54 struct ftrace_ops *op = ftrace_list;
55
56 /* in case someone actually ports this to alpha! */
57 read_barrier_depends();
58
59 while (op != &ftrace_list_end) {
60 /* silly alpha */
61 read_barrier_depends();
62 op->func(ip, parent_ip);
63 op = op->next;
64 };
65}
66
67/**
3d083395 68 * clear_ftrace_function - reset the ftrace function
16444a8a 69 *
3d083395
SR
70 * This NULLs the ftrace function and in essence stops
71 * tracing. There may be lag
16444a8a 72 */
3d083395 73void clear_ftrace_function(void)
16444a8a 74{
3d083395
SR
75 ftrace_trace_function = ftrace_stub;
76}
77
78static int notrace __register_ftrace_function(struct ftrace_ops *ops)
79{
80 /* Should never be called by interrupts */
81 spin_lock(&ftrace_lock);
16444a8a 82
16444a8a
ACM
83 ops->next = ftrace_list;
84 /*
85 * We are entering ops into the ftrace_list but another
86 * CPU might be walking that list. We need to make sure
87 * the ops->next pointer is valid before another CPU sees
88 * the ops pointer included into the ftrace_list.
89 */
90 smp_wmb();
91 ftrace_list = ops;
3d083395 92
b0fc494f
SR
93 if (ftrace_enabled) {
94 /*
95 * For one func, simply call it directly.
96 * For more than one func, call the chain.
97 */
98 if (ops->next == &ftrace_list_end)
99 ftrace_trace_function = ops->func;
100 else
101 ftrace_trace_function = ftrace_list_func;
102 }
3d083395
SR
103
104 spin_unlock(&ftrace_lock);
16444a8a
ACM
105
106 return 0;
107}
108
3d083395 109static int notrace __unregister_ftrace_function(struct ftrace_ops *ops)
16444a8a 110{
16444a8a
ACM
111 struct ftrace_ops **p;
112 int ret = 0;
113
3d083395 114 spin_lock(&ftrace_lock);
16444a8a
ACM
115
116 /*
3d083395
SR
117 * If we are removing the last function, then simply point
118 * to the ftrace_stub.
16444a8a
ACM
119 */
120 if (ftrace_list == ops && ops->next == &ftrace_list_end) {
121 ftrace_trace_function = ftrace_stub;
122 ftrace_list = &ftrace_list_end;
123 goto out;
124 }
125
126 for (p = &ftrace_list; *p != &ftrace_list_end; p = &(*p)->next)
127 if (*p == ops)
128 break;
129
130 if (*p != ops) {
131 ret = -1;
132 goto out;
133 }
134
135 *p = (*p)->next;
136
b0fc494f
SR
137 if (ftrace_enabled) {
138 /* If we only have one func left, then call that directly */
139 if (ftrace_list == &ftrace_list_end ||
140 ftrace_list->next == &ftrace_list_end)
141 ftrace_trace_function = ftrace_list->func;
142 }
16444a8a
ACM
143
144 out:
3d083395
SR
145 spin_unlock(&ftrace_lock);
146
147 return ret;
148}
149
150#ifdef CONFIG_DYNAMIC_FTRACE
151
152static struct hlist_head ftrace_hash[FTRACE_HASHSIZE];
153
154static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu);
155
156static DEFINE_SPINLOCK(ftrace_shutdown_lock);
157static DEFINE_MUTEX(ftraced_lock);
158
3c1720f0
SR
159struct ftrace_page {
160 struct ftrace_page *next;
161 int index;
162 struct dyn_ftrace records[];
163} __attribute__((packed));
164
165#define ENTRIES_PER_PAGE \
166 ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace))
167
168/* estimate from running different kernels */
169#define NR_TO_INIT 10000
170
171static struct ftrace_page *ftrace_pages_start;
172static struct ftrace_page *ftrace_pages;
173
3d083395
SR
174static int ftraced_trigger;
175static int ftraced_suspend;
176
177static int ftrace_record_suspend;
178
179static inline int
180notrace ftrace_ip_in_hash(unsigned long ip, unsigned long key)
181{
182 struct dyn_ftrace *p;
183 struct hlist_node *t;
184 int found = 0;
185
186 hlist_for_each_entry(p, t, &ftrace_hash[key], node) {
187 if (p->ip == ip) {
188 found = 1;
189 break;
190 }
191 }
192
193 return found;
194}
195
196static inline void notrace
197ftrace_add_hash(struct dyn_ftrace *node, unsigned long key)
198{
199 hlist_add_head(&node->node, &ftrace_hash[key]);
200}
201
3c1720f0
SR
202static notrace struct dyn_ftrace *ftrace_alloc_shutdown_node(unsigned long ip)
203{
204 /* If this was already converted, skip it */
205 if (ftrace_ip_converted(ip))
206 return NULL;
207
208 if (ftrace_pages->index == ENTRIES_PER_PAGE) {
209 if (!ftrace_pages->next)
210 return NULL;
211 ftrace_pages = ftrace_pages->next;
212 }
213
214 return &ftrace_pages->records[ftrace_pages->index++];
215}
216
3d083395
SR
217static void notrace
218ftrace_record_ip(unsigned long ip, unsigned long parent_ip)
219{
220 struct dyn_ftrace *node;
221 unsigned long flags;
222 unsigned long key;
223 int resched;
224 int atomic;
225
226 resched = need_resched();
227 preempt_disable_notrace();
228
229 /* We simply need to protect against recursion */
230 __get_cpu_var(ftrace_shutdown_disable_cpu)++;
231 if (__get_cpu_var(ftrace_shutdown_disable_cpu) != 1)
232 goto out;
233
234 if (unlikely(ftrace_record_suspend))
235 goto out;
236
237 key = hash_long(ip, FTRACE_HASHBITS);
238
239 WARN_ON_ONCE(key >= FTRACE_HASHSIZE);
240
241 if (ftrace_ip_in_hash(ip, key))
242 goto out;
243
244 atomic = irqs_disabled();
245
246 spin_lock_irqsave(&ftrace_shutdown_lock, flags);
247
248 /* This ip may have hit the hash before the lock */
249 if (ftrace_ip_in_hash(ip, key))
250 goto out_unlock;
251
252 /*
253 * There's a slight race that the ftraced will update the
254 * hash and reset here. The arch alloc is responsible
255 * for seeing if the IP has already changed, and if
256 * it has, the alloc will fail.
257 */
258 node = ftrace_alloc_shutdown_node(ip);
259 if (!node)
260 goto out_unlock;
261
262 node->ip = ip;
263
264 ftrace_add_hash(node, key);
265
266 ftraced_trigger = 1;
267
268 out_unlock:
269 spin_unlock_irqrestore(&ftrace_shutdown_lock, flags);
270 out:
271 __get_cpu_var(ftrace_shutdown_disable_cpu)--;
272
273 /* prevent recursion with scheduler */
274 if (resched)
275 preempt_enable_no_resched_notrace();
276 else
277 preempt_enable_notrace();
278}
279
280static struct ftrace_ops ftrace_shutdown_ops __read_mostly =
281{
282 .func = ftrace_record_ip,
283};
284
3c1720f0
SR
285#define MCOUNT_ADDR ((long)(&mcount))
286
287static void notrace ftrace_replace_code(int saved)
288{
289 unsigned char *new = NULL, *old = NULL;
290 struct dyn_ftrace *rec;
291 struct ftrace_page *pg;
292 unsigned long ip;
293 int failed;
294 int i;
295
296 if (saved)
297 old = ftrace_nop_replace();
298 else
299 new = ftrace_nop_replace();
300
301 for (pg = ftrace_pages_start; pg; pg = pg->next) {
302 for (i = 0; i < pg->index; i++) {
303 rec = &pg->records[i];
304
305 /* don't modify code that has already faulted */
306 if (rec->flags & FTRACE_FL_FAILED)
307 continue;
308
309 ip = rec->ip;
310
311 if (saved)
312 new = ftrace_call_replace(ip, MCOUNT_ADDR);
313 else
314 old = ftrace_call_replace(ip, MCOUNT_ADDR);
315
316 failed = ftrace_modify_code(ip, old, new);
317 if (failed)
318 rec->flags |= FTRACE_FL_FAILED;
319 }
320 }
321}
322
323static notrace void ftrace_startup_code(void)
324{
325 ftrace_replace_code(1);
326}
327
328static notrace void ftrace_shutdown_code(void)
329{
330 ftrace_replace_code(0);
331}
332
333static notrace void ftrace_shutdown_replenish(void)
334{
335 if (ftrace_pages->next)
336 return;
337
338 /* allocate another page */
339 ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL);
340}
3d083395
SR
341
342static int notrace __ftrace_modify_code(void *data)
343{
344 void (*func)(void) = data;
345
346 func();
347 return 0;
348}
349
3c1720f0
SR
350static notrace void
351ftrace_code_disable(struct dyn_ftrace *rec, unsigned long addr)
352{
353 unsigned long ip;
354 unsigned char *nop, *call;
355 int failed;
356
357 ip = rec->ip;
358
359 nop = ftrace_nop_replace();
360 call = ftrace_call_replace(ip, addr);
361
362 failed = ftrace_modify_code(ip, call, nop);
363 if (failed)
364 rec->flags |= FTRACE_FL_FAILED;
365}
366
3d083395
SR
367static void notrace ftrace_run_startup_code(void)
368{
369 stop_machine_run(__ftrace_modify_code, ftrace_startup_code, NR_CPUS);
370}
371
372static void notrace ftrace_run_shutdown_code(void)
373{
374 stop_machine_run(__ftrace_modify_code, ftrace_shutdown_code, NR_CPUS);
375}
376
377static void notrace ftrace_startup(void)
378{
379 mutex_lock(&ftraced_lock);
380 ftraced_suspend++;
381 if (ftraced_suspend != 1)
382 goto out;
383 __unregister_ftrace_function(&ftrace_shutdown_ops);
384
b0fc494f
SR
385 if (ftrace_enabled)
386 ftrace_run_startup_code();
3d083395
SR
387 out:
388 mutex_unlock(&ftraced_lock);
389}
390
391static void notrace ftrace_shutdown(void)
392{
393 mutex_lock(&ftraced_lock);
394 ftraced_suspend--;
395 if (ftraced_suspend)
396 goto out;
397
b0fc494f
SR
398 if (ftrace_enabled)
399 ftrace_run_shutdown_code();
3d083395
SR
400
401 __register_ftrace_function(&ftrace_shutdown_ops);
402 out:
403 mutex_unlock(&ftraced_lock);
404}
405
b0fc494f
SR
406static void notrace ftrace_startup_sysctl(void)
407{
408 mutex_lock(&ftraced_lock);
409 /* ftraced_suspend is true if we want ftrace running */
410 if (ftraced_suspend)
411 ftrace_run_startup_code();
412 mutex_unlock(&ftraced_lock);
413}
414
415static void notrace ftrace_shutdown_sysctl(void)
416{
417 mutex_lock(&ftraced_lock);
418 /* ftraced_suspend is true if ftrace is running */
419 if (ftraced_suspend)
420 ftrace_run_shutdown_code();
421 mutex_unlock(&ftraced_lock);
422}
423
3d083395
SR
424static cycle_t ftrace_update_time;
425static unsigned long ftrace_update_cnt;
426unsigned long ftrace_update_tot_cnt;
427
428static int notrace __ftrace_update_code(void *ignore)
429{
430 struct dyn_ftrace *p;
431 struct hlist_head head;
432 struct hlist_node *t;
433 cycle_t start, stop;
434 int i;
435
436 /* Don't be calling ftrace ops now */
437 __unregister_ftrace_function(&ftrace_shutdown_ops);
438
439 start = now(raw_smp_processor_id());
440 ftrace_update_cnt = 0;
441
442 /* No locks needed, the machine is stopped! */
443 for (i = 0; i < FTRACE_HASHSIZE; i++) {
444 if (hlist_empty(&ftrace_hash[i]))
445 continue;
446
447 head = ftrace_hash[i];
448 INIT_HLIST_HEAD(&ftrace_hash[i]);
449
450 /* all CPUS are stopped, we are safe to modify code */
451 hlist_for_each_entry(p, t, &head, node) {
3c1720f0 452 ftrace_code_disable(p, MCOUNT_ADDR);
3d083395
SR
453 ftrace_update_cnt++;
454 }
455
456 }
457
458 stop = now(raw_smp_processor_id());
459 ftrace_update_time = stop - start;
460 ftrace_update_tot_cnt += ftrace_update_cnt;
461
462 __register_ftrace_function(&ftrace_shutdown_ops);
16444a8a
ACM
463
464 return 0;
465}
466
3d083395
SR
467static void notrace ftrace_update_code(void)
468{
469 stop_machine_run(__ftrace_update_code, NULL, NR_CPUS);
470}
471
472static int notrace ftraced(void *ignore)
473{
474 unsigned long usecs;
475
476 set_current_state(TASK_INTERRUPTIBLE);
477
478 while (!kthread_should_stop()) {
479
480 /* check once a second */
481 schedule_timeout(HZ);
482
b0fc494f 483 mutex_lock(&ftrace_sysctl_lock);
3d083395 484 mutex_lock(&ftraced_lock);
b0fc494f 485 if (ftrace_enabled && ftraced_trigger && !ftraced_suspend) {
3d083395
SR
486 ftrace_record_suspend++;
487 ftrace_update_code();
488 usecs = nsecs_to_usecs(ftrace_update_time);
489 if (ftrace_update_tot_cnt > 100000) {
490 ftrace_update_tot_cnt = 0;
491 pr_info("hm, dftrace overflow: %lu change%s"
492 " (%lu total) in %lu usec%s\n",
493 ftrace_update_cnt,
494 ftrace_update_cnt != 1 ? "s" : "",
495 ftrace_update_tot_cnt,
496 usecs, usecs != 1 ? "s" : "");
497 WARN_ON_ONCE(1);
498 }
499 ftraced_trigger = 0;
500 ftrace_record_suspend--;
501 }
502 mutex_unlock(&ftraced_lock);
b0fc494f 503 mutex_unlock(&ftrace_sysctl_lock);
3d083395
SR
504
505 ftrace_shutdown_replenish();
506
507 set_current_state(TASK_INTERRUPTIBLE);
508 }
509 __set_current_state(TASK_RUNNING);
510 return 0;
511}
512
3c1720f0
SR
513static int __init ftrace_dyn_table_alloc(void)
514{
515 struct ftrace_page *pg;
516 int cnt;
517 int i;
518 int ret;
519
520 ret = ftrace_dyn_arch_init();
521 if (ret)
522 return ret;
523
524 /* allocate a few pages */
525 ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL);
526 if (!ftrace_pages_start)
527 return -1;
528
529 /*
530 * Allocate a few more pages.
531 *
532 * TODO: have some parser search vmlinux before
533 * final linking to find all calls to ftrace.
534 * Then we can:
535 * a) know how many pages to allocate.
536 * and/or
537 * b) set up the table then.
538 *
539 * The dynamic code is still necessary for
540 * modules.
541 */
542
543 pg = ftrace_pages = ftrace_pages_start;
544
545 cnt = NR_TO_INIT / ENTRIES_PER_PAGE;
546
547 for (i = 0; i < cnt; i++) {
548 pg->next = (void *)get_zeroed_page(GFP_KERNEL);
549
550 /* If we fail, we'll try later anyway */
551 if (!pg->next)
552 break;
553
554 pg = pg->next;
555 }
556
557 return 0;
558}
559
3d083395
SR
560static int __init notrace ftrace_shutdown_init(void)
561{
562 struct task_struct *p;
563 int ret;
564
3c1720f0 565 ret = ftrace_dyn_table_alloc();
3d083395
SR
566 if (ret)
567 return ret;
568
569 p = kthread_run(ftraced, NULL, "ftraced");
570 if (IS_ERR(p))
571 return -1;
572
573 __register_ftrace_function(&ftrace_shutdown_ops);
574
575 return 0;
576}
577
578core_initcall(ftrace_shutdown_init);
579#else
b0fc494f
SR
580# define ftrace_startup() do { } while (0)
581# define ftrace_shutdown() do { } while (0)
582# define ftrace_startup_sysctl() do { } while (0)
583# define ftrace_shutdown_sysctl() do { } while (0)
3d083395
SR
584#endif /* CONFIG_DYNAMIC_FTRACE */
585
16444a8a 586/**
3d083395
SR
587 * register_ftrace_function - register a function for profiling
588 * @ops - ops structure that holds the function for profiling.
16444a8a 589 *
3d083395
SR
590 * Register a function to be called by all functions in the
591 * kernel.
592 *
593 * Note: @ops->func and all the functions it calls must be labeled
594 * with "notrace", otherwise it will go into a
595 * recursive loop.
16444a8a 596 */
3d083395 597int register_ftrace_function(struct ftrace_ops *ops)
16444a8a 598{
b0fc494f
SR
599 int ret;
600
601 mutex_lock(&ftrace_sysctl_lock);
3d083395
SR
602 ftrace_startup();
603
b0fc494f
SR
604 ret = __register_ftrace_function(ops);
605 mutex_unlock(&ftrace_sysctl_lock);
606
607 return ret;
3d083395
SR
608}
609
610/**
611 * unregister_ftrace_function - unresgister a function for profiling.
612 * @ops - ops structure that holds the function to unregister
613 *
614 * Unregister a function that was added to be called by ftrace profiling.
615 */
616int unregister_ftrace_function(struct ftrace_ops *ops)
617{
618 int ret;
619
b0fc494f 620 mutex_lock(&ftrace_sysctl_lock);
3d083395
SR
621 ret = __unregister_ftrace_function(ops);
622
623 if (ftrace_list == &ftrace_list_end)
624 ftrace_shutdown();
625
b0fc494f
SR
626 mutex_unlock(&ftrace_sysctl_lock);
627
628 return ret;
629}
630
631notrace int
632ftrace_enable_sysctl(struct ctl_table *table, int write,
633 struct file *filp, void __user *buffer, size_t *lenp,
634 loff_t *ppos)
635{
636 int ret;
637
638 mutex_lock(&ftrace_sysctl_lock);
639
640 ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);
641
642 if (ret || !write || (last_ftrace_enabled == ftrace_enabled))
643 goto out;
644
645 last_ftrace_enabled = ftrace_enabled;
646
647 if (ftrace_enabled) {
648
649 ftrace_startup_sysctl();
650
651 /* we are starting ftrace again */
652 if (ftrace_list != &ftrace_list_end) {
653 if (ftrace_list->next == &ftrace_list_end)
654 ftrace_trace_function = ftrace_list->func;
655 else
656 ftrace_trace_function = ftrace_list_func;
657 }
658
659 } else {
660 /* stopping ftrace calls (just send to ftrace_stub) */
661 ftrace_trace_function = ftrace_stub;
662
663 ftrace_shutdown_sysctl();
664 }
665
666 out:
667 mutex_unlock(&ftrace_sysctl_lock);
3d083395 668 return ret;
16444a8a 669}