aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt8
-rw-r--r--arch/arm/include/asm/ftrace.h5
-rw-r--r--arch/powerpc/include/asm/ftrace.h5
-rw-r--r--arch/sh/include/asm/ftrace.h5
-rw-r--r--arch/sparc/include/asm/ftrace.h5
-rw-r--r--arch/x86/Kconfig.debug4
-rw-r--r--arch/x86/include/asm/ftrace.h15
-rw-r--r--arch/x86/kernel/ftrace.c129
-rw-r--r--arch/x86/mm/Makefile3
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--include/linux/ftrace.h5
-rw-r--r--include/linux/hardirq.h15
-rw-r--r--include/linux/marker.h2
-rw-r--r--include/linux/tracepoint.h4
-rw-r--r--kernel/marker.c80
-rw-r--r--kernel/sysctl.c10
-rw-r--r--kernel/trace/trace.c117
-rw-r--r--kernel/tracepoint.c261
-rw-r--r--scripts/Makefile.build12
-rw-r--r--scripts/tracing/draw_functrace.py130
20 files changed, 612 insertions, 205 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 1bbcaa8982b6..4862284d3119 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -765,6 +765,14 @@ and is between 256 and 4096 characters. It is defined in the file
765 parameter will force ia64_sal_cache_flush to call 765 parameter will force ia64_sal_cache_flush to call
766 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH. 766 ia64_pal_cache_flush instead of SAL_CACHE_FLUSH.
767 767
768 ftrace=[tracer]
769 [ftrace] will set and start the specified tracer
770 as early as possible in order to facilitate early
771 boot debugging.
772
773 ftrace_dump_on_oops
774 [ftrace] will dump the trace buffers on oops.
775
768 gamecon.map[2|3]= 776 gamecon.map[2|3]=
769 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad 777 [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
770 support via parallel port (up to 5 devices per port) 778 support via parallel port (up to 5 devices per port)
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index 39c8bc1a006a..3f3a1d1508ea 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -1,6 +1,11 @@
1#ifndef _ASM_ARM_FTRACE 1#ifndef _ASM_ARM_FTRACE
2#define _ASM_ARM_FTRACE 2#define _ASM_ARM_FTRACE
3 3
4#ifndef __ASSEMBLY__
5static inline void ftrace_nmi_enter(void) { }
6static inline void ftrace_nmi_exit(void) { }
7#endif
8
4#ifdef CONFIG_FUNCTION_TRACER 9#ifdef CONFIG_FUNCTION_TRACER
5#define MCOUNT_ADDR ((long)(mcount)) 10#define MCOUNT_ADDR ((long)(mcount))
6#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ 11#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
index b298f7a631e6..1cd72700fbc0 100644
--- a/arch/powerpc/include/asm/ftrace.h
+++ b/arch/powerpc/include/asm/ftrace.h
@@ -1,6 +1,11 @@
1#ifndef _ASM_POWERPC_FTRACE 1#ifndef _ASM_POWERPC_FTRACE
2#define _ASM_POWERPC_FTRACE 2#define _ASM_POWERPC_FTRACE
3 3
4#ifndef __ASSEMBLY__
5static inline void ftrace_nmi_enter(void) { }
6static inline void ftrace_nmi_exit(void) { }
7#endif
8
4#ifdef CONFIG_FUNCTION_TRACER 9#ifdef CONFIG_FUNCTION_TRACER
5#define MCOUNT_ADDR ((long)(_mcount)) 10#define MCOUNT_ADDR ((long)(_mcount))
6#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ 11#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
index 3aed362c9463..31ada0370cb6 100644
--- a/arch/sh/include/asm/ftrace.h
+++ b/arch/sh/include/asm/ftrace.h
@@ -2,6 +2,11 @@
2#define __ASM_SH_FTRACE_H 2#define __ASM_SH_FTRACE_H
3 3
4#ifndef __ASSEMBLY__ 4#ifndef __ASSEMBLY__
5static inline void ftrace_nmi_enter(void) { }
6static inline void ftrace_nmi_exit(void) { }
7#endif
8
9#ifndef __ASSEMBLY__
5extern void mcount(void); 10extern void mcount(void);
6#endif 11#endif
7 12
diff --git a/arch/sparc/include/asm/ftrace.h b/arch/sparc/include/asm/ftrace.h
index d27716cd38c1..62055ac0496e 100644
--- a/arch/sparc/include/asm/ftrace.h
+++ b/arch/sparc/include/asm/ftrace.h
@@ -1,6 +1,11 @@
1#ifndef _ASM_SPARC64_FTRACE 1#ifndef _ASM_SPARC64_FTRACE
2#define _ASM_SPARC64_FTRACE 2#define _ASM_SPARC64_FTRACE
3 3
4#ifndef __ASSEMBLY__
5static inline void ftrace_nmi_enter(void) { }
6static inline void ftrace_nmi_exit(void) { }
7#endif
8
4#ifdef CONFIG_MCOUNT 9#ifdef CONFIG_MCOUNT
5#define MCOUNT_ADDR ((long)(_mcount)) 10#define MCOUNT_ADDR ((long)(_mcount))
6#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ 11#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index 2a3dfbd5e677..fa013f529b74 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -186,14 +186,10 @@ config IOMMU_LEAK
186 Add a simple leak tracer to the IOMMU code. This is useful when you 186 Add a simple leak tracer to the IOMMU code. This is useful when you
187 are debugging a buggy device driver that leaks IOMMU mappings. 187 are debugging a buggy device driver that leaks IOMMU mappings.
188 188
189config MMIOTRACE_HOOKS
190 bool
191
192config MMIOTRACE 189config MMIOTRACE
193 bool "Memory mapped IO tracing" 190 bool "Memory mapped IO tracing"
194 depends on DEBUG_KERNEL && PCI 191 depends on DEBUG_KERNEL && PCI
195 select TRACING 192 select TRACING
196 select MMIOTRACE_HOOKS
197 help 193 help
198 Mmiotrace traces Memory Mapped I/O access and is meant for 194 Mmiotrace traces Memory Mapped I/O access and is meant for
199 debugging and reverse engineering. It is called from the ioremap 195 debugging and reverse engineering. It is called from the ioremap
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index 9e8bc29b8b17..a23468194b8c 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -17,6 +17,21 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
17 */ 17 */
18 return addr - 1; 18 return addr - 1;
19} 19}
20
21#ifdef CONFIG_DYNAMIC_FTRACE
22extern void ftrace_nmi_enter(void);
23extern void ftrace_nmi_exit(void);
24#else
25static inline void ftrace_nmi_enter(void) { }
26static inline void ftrace_nmi_exit(void) { }
27#endif
28#endif /* __ASSEMBLY__ */
29
30#else /* CONFIG_FUNCTION_TRACER */
31
32#ifndef __ASSEMBLY__
33static inline void ftrace_nmi_enter(void) { }
34static inline void ftrace_nmi_exit(void) { }
20#endif 35#endif
21 36
22#endif /* CONFIG_FUNCTION_TRACER */ 37#endif /* CONFIG_FUNCTION_TRACER */
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 50ea0ac8c9bf..69149337f2fe 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -56,6 +56,133 @@ unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
56 return calc.code; 56 return calc.code;
57} 57}
58 58
59/*
60 * Modifying code must take extra care. On an SMP machine, if
61 * the code being modified is also being executed on another CPU
62 * that CPU will have undefined results and possibly take a GPF.
63 * We use kstop_machine to stop other CPUS from exectuing code.
64 * But this does not stop NMIs from happening. We still need
65 * to protect against that. We separate out the modification of
66 * the code to take care of this.
67 *
68 * Two buffers are added: An IP buffer and a "code" buffer.
69 *
70 * 1) Put the instruction pointer into the IP buffer
71 * and the new code into the "code" buffer.
72 * 2) Set a flag that says we are modifying code
73 * 3) Wait for any running NMIs to finish.
74 * 4) Write the code
75 * 5) clear the flag.
76 * 6) Wait for any running NMIs to finish.
77 *
78 * If an NMI is executed, the first thing it does is to call
79 * "ftrace_nmi_enter". This will check if the flag is set to write
80 * and if it is, it will write what is in the IP and "code" buffers.
81 *
82 * The trick is, it does not matter if everyone is writing the same
83 * content to the code location. Also, if a CPU is executing code
84 * it is OK to write to that code location if the contents being written
85 * are the same as what exists.
86 */
87
88static atomic_t in_nmi = ATOMIC_INIT(0);
89static int mod_code_status; /* holds return value of text write */
90static int mod_code_write; /* set when NMI should do the write */
91static void *mod_code_ip; /* holds the IP to write to */
92static void *mod_code_newcode; /* holds the text to write to the IP */
93
94static unsigned nmi_wait_count;
95static atomic_t nmi_update_count = ATOMIC_INIT(0);
96
97int ftrace_arch_read_dyn_info(char *buf, int size)
98{
99 int r;
100
101 r = snprintf(buf, size, "%u %u",
102 nmi_wait_count,
103 atomic_read(&nmi_update_count));
104 return r;
105}
106
107static void ftrace_mod_code(void)
108{
109 /*
110 * Yes, more than one CPU process can be writing to mod_code_status.
111 * (and the code itself)
112 * But if one were to fail, then they all should, and if one were
113 * to succeed, then they all should.
114 */
115 mod_code_status = probe_kernel_write(mod_code_ip, mod_code_newcode,
116 MCOUNT_INSN_SIZE);
117
118}
119
120void ftrace_nmi_enter(void)
121{
122 atomic_inc(&in_nmi);
123 /* Must have in_nmi seen before reading write flag */
124 smp_mb();
125 if (mod_code_write) {
126 ftrace_mod_code();
127 atomic_inc(&nmi_update_count);
128 }
129}
130
131void ftrace_nmi_exit(void)
132{
133 /* Finish all executions before clearing in_nmi */
134 smp_wmb();
135 atomic_dec(&in_nmi);
136}
137
138static void wait_for_nmi(void)
139{
140 int waited = 0;
141
142 while (atomic_read(&in_nmi)) {
143 waited = 1;
144 cpu_relax();
145 }
146
147 if (waited)
148 nmi_wait_count++;
149}
150
151static int
152do_ftrace_mod_code(unsigned long ip, void *new_code)
153{
154 mod_code_ip = (void *)ip;
155 mod_code_newcode = new_code;
156
157 /* The buffers need to be visible before we let NMIs write them */
158 smp_wmb();
159
160 mod_code_write = 1;
161
162 /* Make sure write bit is visible before we wait on NMIs */
163 smp_mb();
164
165 wait_for_nmi();
166
167 /* Make sure all running NMIs have finished before we write the code */
168 smp_mb();
169
170 ftrace_mod_code();
171
172 /* Make sure the write happens before clearing the bit */
173 smp_wmb();
174
175 mod_code_write = 0;
176
177 /* make sure NMIs see the cleared bit */
178 smp_mb();
179
180 wait_for_nmi();
181
182 return mod_code_status;
183}
184
185
59int 186int
60ftrace_modify_code(unsigned long ip, unsigned char *old_code, 187ftrace_modify_code(unsigned long ip, unsigned char *old_code,
61 unsigned char *new_code) 188 unsigned char *new_code)
@@ -81,7 +208,7 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
81 return -EINVAL; 208 return -EINVAL;
82 209
83 /* replace the text with the new text */ 210 /* replace the text with the new text */
84 if (probe_kernel_write((void *)ip, new_code, MCOUNT_INSN_SIZE)) 211 if (do_ftrace_mod_code(ip, new_code))
85 return -EPERM; 212 return -EPERM;
86 213
87 sync_core(); 214 sync_core();
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
index 59f89b434b45..0a21b7aab9dc 100644
--- a/arch/x86/mm/Makefile
+++ b/arch/x86/mm/Makefile
@@ -8,9 +8,8 @@ obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o
8 8
9obj-$(CONFIG_HIGHMEM) += highmem_32.o 9obj-$(CONFIG_HIGHMEM) += highmem_32.o
10 10
11obj-$(CONFIG_MMIOTRACE_HOOKS) += kmmio.o
12obj-$(CONFIG_MMIOTRACE) += mmiotrace.o 11obj-$(CONFIG_MMIOTRACE) += mmiotrace.o
13mmiotrace-y := pf_in.o mmio-mod.o 12mmiotrace-y := kmmio.o pf_in.o mmio-mod.o
14obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o 13obj-$(CONFIG_MMIOTRACE_TEST) += testmmiotrace.o
15 14
16obj-$(CONFIG_NUMA) += numa_$(BITS).o 15obj-$(CONFIG_NUMA) += numa_$(BITS).o
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 31e8730fa246..4152d3c3b138 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -53,7 +53,7 @@
53 53
54static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr) 54static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
55{ 55{
56#ifdef CONFIG_MMIOTRACE_HOOKS 56#ifdef CONFIG_MMIOTRACE
57 if (unlikely(is_kmmio_active())) 57 if (unlikely(is_kmmio_active()))
58 if (kmmio_handler(regs, addr) == 1) 58 if (kmmio_handler(regs, addr) == 1)
59 return -1; 59 return -1;
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 703eb53cfa2b..e46a7b34037c 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -74,6 +74,9 @@ extern void ftrace_caller(void);
74extern void ftrace_call(void); 74extern void ftrace_call(void);
75extern void mcount_call(void); 75extern void mcount_call(void);
76 76
77/* May be defined in arch */
78extern int ftrace_arch_read_dyn_info(char *buf, int size);
79
77/** 80/**
78 * ftrace_modify_code - modify code segment 81 * ftrace_modify_code - modify code segment
79 * @ip: the address of the code segment 82 * @ip: the address of the code segment
@@ -181,6 +184,8 @@ static inline void __ftrace_enabled_restore(int enabled)
181#endif 184#endif
182 185
183#ifdef CONFIG_TRACING 186#ifdef CONFIG_TRACING
187extern int ftrace_dump_on_oops;
188
184extern void 189extern void
185ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); 190ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
186 191
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 181006cc94a0..0087cb43becf 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -5,6 +5,7 @@
5#include <linux/smp_lock.h> 5#include <linux/smp_lock.h>
6#include <linux/lockdep.h> 6#include <linux/lockdep.h>
7#include <asm/hardirq.h> 7#include <asm/hardirq.h>
8#include <asm/ftrace.h>
8#include <asm/system.h> 9#include <asm/system.h>
9 10
10/* 11/*
@@ -161,7 +162,17 @@ extern void irq_enter(void);
161 */ 162 */
162extern void irq_exit(void); 163extern void irq_exit(void);
163 164
164#define nmi_enter() do { lockdep_off(); __irq_enter(); } while (0) 165#define nmi_enter() \
165#define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) 166 do { \
167 ftrace_nmi_enter(); \
168 lockdep_off(); \
169 __irq_enter(); \
170 } while (0)
171#define nmi_exit() \
172 do { \
173 __irq_exit(); \
174 lockdep_on(); \
175 ftrace_nmi_exit(); \
176 } while (0)
166 177
167#endif /* LINUX_HARDIRQ_H */ 178#endif /* LINUX_HARDIRQ_H */
diff --git a/include/linux/marker.h b/include/linux/marker.h
index 889196c7fbb1..4cf45472d9f5 100644
--- a/include/linux/marker.h
+++ b/include/linux/marker.h
@@ -136,8 +136,6 @@ extern marker_probe_func __mark_empty_function;
136 136
137extern void marker_probe_cb(const struct marker *mdata, 137extern void marker_probe_cb(const struct marker *mdata,
138 void *call_private, ...); 138 void *call_private, ...);
139extern void marker_probe_cb_noarg(const struct marker *mdata,
140 void *call_private, ...);
141 139
142/* 140/*
143 * Connect a probe to a marker. 141 * Connect a probe to a marker.
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
index c5bb39c7a770..63064e9403f2 100644
--- a/include/linux/tracepoint.h
+++ b/include/linux/tracepoint.h
@@ -112,6 +112,10 @@ extern int tracepoint_probe_register(const char *name, void *probe);
112 */ 112 */
113extern int tracepoint_probe_unregister(const char *name, void *probe); 113extern int tracepoint_probe_unregister(const char *name, void *probe);
114 114
115extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
116extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
117extern void tracepoint_probe_update_all(void);
118
115struct tracepoint_iter { 119struct tracepoint_iter {
116 struct module *module; 120 struct module *module;
117 struct tracepoint *tracepoint; 121 struct tracepoint *tracepoint;
diff --git a/kernel/marker.c b/kernel/marker.c
index e9c6b2bc9400..2898b647d415 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -43,6 +43,7 @@ static DEFINE_MUTEX(markers_mutex);
43 */ 43 */
44#define MARKER_HASH_BITS 6 44#define MARKER_HASH_BITS 6
45#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) 45#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
46static struct hlist_head marker_table[MARKER_TABLE_SIZE];
46 47
47/* 48/*
48 * Note about RCU : 49 * Note about RCU :
@@ -64,11 +65,10 @@ struct marker_entry {
64 void *oldptr; 65 void *oldptr;
65 int rcu_pending; 66 int rcu_pending;
66 unsigned char ptype:1; 67 unsigned char ptype:1;
68 unsigned char format_allocated:1;
67 char name[0]; /* Contains name'\0'format'\0' */ 69 char name[0]; /* Contains name'\0'format'\0' */
68}; 70};
69 71
70static struct hlist_head marker_table[MARKER_TABLE_SIZE];
71
72/** 72/**
73 * __mark_empty_function - Empty probe callback 73 * __mark_empty_function - Empty probe callback
74 * @probe_private: probe private data 74 * @probe_private: probe private data
@@ -157,7 +157,7 @@ EXPORT_SYMBOL_GPL(marker_probe_cb);
157 * 157 *
158 * Should be connected to markers "MARK_NOARGS". 158 * Should be connected to markers "MARK_NOARGS".
159 */ 159 */
160void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) 160static void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
161{ 161{
162 va_list args; /* not initialized */ 162 va_list args; /* not initialized */
163 char ptype; 163 char ptype;
@@ -197,7 +197,6 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
197 } 197 }
198 rcu_read_unlock_sched(); 198 rcu_read_unlock_sched();
199} 199}
200EXPORT_SYMBOL_GPL(marker_probe_cb_noarg);
201 200
202static void free_old_closure(struct rcu_head *head) 201static void free_old_closure(struct rcu_head *head)
203{ 202{
@@ -416,6 +415,7 @@ static struct marker_entry *add_marker(const char *name, const char *format)
416 e->single.probe_private = NULL; 415 e->single.probe_private = NULL;
417 e->multi = NULL; 416 e->multi = NULL;
418 e->ptype = 0; 417 e->ptype = 0;
418 e->format_allocated = 0;
419 e->refcount = 0; 419 e->refcount = 0;
420 e->rcu_pending = 0; 420 e->rcu_pending = 0;
421 hlist_add_head(&e->hlist, head); 421 hlist_add_head(&e->hlist, head);
@@ -447,6 +447,8 @@ static int remove_marker(const char *name)
447 if (e->single.func != __mark_empty_function) 447 if (e->single.func != __mark_empty_function)
448 return -EBUSY; 448 return -EBUSY;
449 hlist_del(&e->hlist); 449 hlist_del(&e->hlist);
450 if (e->format_allocated)
451 kfree(e->format);
450 /* Make sure the call_rcu has been executed */ 452 /* Make sure the call_rcu has been executed */
451 if (e->rcu_pending) 453 if (e->rcu_pending)
452 rcu_barrier_sched(); 454 rcu_barrier_sched();
@@ -457,57 +459,34 @@ static int remove_marker(const char *name)
457/* 459/*
458 * Set the mark_entry format to the format found in the element. 460 * Set the mark_entry format to the format found in the element.
459 */ 461 */
460static int marker_set_format(struct marker_entry **entry, const char *format) 462static int marker_set_format(struct marker_entry *entry, const char *format)
461{ 463{
462 struct marker_entry *e; 464 entry->format = kstrdup(format, GFP_KERNEL);
463 size_t name_len = strlen((*entry)->name) + 1; 465 if (!entry->format)
464 size_t format_len = strlen(format) + 1;
465
466
467 e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
468 GFP_KERNEL);
469 if (!e)
470 return -ENOMEM; 466 return -ENOMEM;
471 memcpy(&e->name[0], (*entry)->name, name_len); 467 entry->format_allocated = 1;
472 e->format = &e->name[name_len]; 468
473 memcpy(e->format, format, format_len);
474 if (strcmp(e->format, MARK_NOARGS) == 0)
475 e->call = marker_probe_cb_noarg;
476 else
477 e->call = marker_probe_cb;
478 e->single = (*entry)->single;
479 e->multi = (*entry)->multi;
480 e->ptype = (*entry)->ptype;
481 e->refcount = (*entry)->refcount;
482 e->rcu_pending = 0;
483 hlist_add_before(&e->hlist, &(*entry)->hlist);
484 hlist_del(&(*entry)->hlist);
485 /* Make sure the call_rcu has been executed */
486 if ((*entry)->rcu_pending)
487 rcu_barrier_sched();
488 kfree(*entry);
489 *entry = e;
490 trace_mark(core_marker_format, "name %s format %s", 469 trace_mark(core_marker_format, "name %s format %s",
491 e->name, e->format); 470 entry->name, entry->format);
492 return 0; 471 return 0;
493} 472}
494 473
495/* 474/*
496 * Sets the probe callback corresponding to one marker. 475 * Sets the probe callback corresponding to one marker.
497 */ 476 */
498static int set_marker(struct marker_entry **entry, struct marker *elem, 477static int set_marker(struct marker_entry *entry, struct marker *elem,
499 int active) 478 int active)
500{ 479{
501 int ret; 480 int ret;
502 WARN_ON(strcmp((*entry)->name, elem->name) != 0); 481 WARN_ON(strcmp(entry->name, elem->name) != 0);
503 482
504 if ((*entry)->format) { 483 if (entry->format) {
505 if (strcmp((*entry)->format, elem->format) != 0) { 484 if (strcmp(entry->format, elem->format) != 0) {
506 printk(KERN_NOTICE 485 printk(KERN_NOTICE
507 "Format mismatch for probe %s " 486 "Format mismatch for probe %s "
508 "(%s), marker (%s)\n", 487 "(%s), marker (%s)\n",
509 (*entry)->name, 488 entry->name,
510 (*entry)->format, 489 entry->format,
511 elem->format); 490 elem->format);
512 return -EPERM; 491 return -EPERM;
513 } 492 }
@@ -523,34 +502,33 @@ static int set_marker(struct marker_entry **entry, struct marker *elem,
523 * pass from a "safe" callback (with argument) to an "unsafe" 502 * pass from a "safe" callback (with argument) to an "unsafe"
524 * callback (does not set arguments). 503 * callback (does not set arguments).
525 */ 504 */
526 elem->call = (*entry)->call; 505 elem->call = entry->call;
527 /* 506 /*
528 * Sanity check : 507 * Sanity check :
529 * We only update the single probe private data when the ptr is 508 * We only update the single probe private data when the ptr is
530 * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1) 509 * set to a _non_ single probe! (0 -> 1 and N -> 1, N != 1)
531 */ 510 */
532 WARN_ON(elem->single.func != __mark_empty_function 511 WARN_ON(elem->single.func != __mark_empty_function
533 && elem->single.probe_private 512 && elem->single.probe_private != entry->single.probe_private
534 != (*entry)->single.probe_private && 513 && !elem->ptype);
535 !elem->ptype); 514 elem->single.probe_private = entry->single.probe_private;
536 elem->single.probe_private = (*entry)->single.probe_private;
537 /* 515 /*
538 * Make sure the private data is valid when we update the 516 * Make sure the private data is valid when we update the
539 * single probe ptr. 517 * single probe ptr.
540 */ 518 */
541 smp_wmb(); 519 smp_wmb();
542 elem->single.func = (*entry)->single.func; 520 elem->single.func = entry->single.func;
543 /* 521 /*
544 * We also make sure that the new probe callbacks array is consistent 522 * We also make sure that the new probe callbacks array is consistent
545 * before setting a pointer to it. 523 * before setting a pointer to it.
546 */ 524 */
547 rcu_assign_pointer(elem->multi, (*entry)->multi); 525 rcu_assign_pointer(elem->multi, entry->multi);
548 /* 526 /*
549 * Update the function or multi probe array pointer before setting the 527 * Update the function or multi probe array pointer before setting the
550 * ptype. 528 * ptype.
551 */ 529 */
552 smp_wmb(); 530 smp_wmb();
553 elem->ptype = (*entry)->ptype; 531 elem->ptype = entry->ptype;
554 elem->state = active; 532 elem->state = active;
555 533
556 return 0; 534 return 0;
@@ -594,8 +572,7 @@ void marker_update_probe_range(struct marker *begin,
594 for (iter = begin; iter < end; iter++) { 572 for (iter = begin; iter < end; iter++) {
595 mark_entry = get_marker(iter->name); 573 mark_entry = get_marker(iter->name);
596 if (mark_entry) { 574 if (mark_entry) {
597 set_marker(&mark_entry, iter, 575 set_marker(mark_entry, iter, !!mark_entry->refcount);
598 !!mark_entry->refcount);
599 /* 576 /*
600 * ignore error, continue 577 * ignore error, continue
601 */ 578 */
@@ -657,7 +634,7 @@ int marker_probe_register(const char *name, const char *format,
657 ret = PTR_ERR(entry); 634 ret = PTR_ERR(entry);
658 } else if (format) { 635 } else if (format) {
659 if (!entry->format) 636 if (!entry->format)
660 ret = marker_set_format(&entry, format); 637 ret = marker_set_format(entry, format);
661 else if (strcmp(entry->format, format)) 638 else if (strcmp(entry->format, format))
662 ret = -EPERM; 639 ret = -EPERM;
663 } 640 }
@@ -848,8 +825,6 @@ void *marker_get_private_data(const char *name, marker_probe_func *probe,
848 if (!e->ptype) { 825 if (!e->ptype) {
849 if (num == 0 && e->single.func == probe) 826 if (num == 0 && e->single.func == probe)
850 return e->single.probe_private; 827 return e->single.probe_private;
851 else
852 break;
853 } else { 828 } else {
854 struct marker_probe_closure *closure; 829 struct marker_probe_closure *closure;
855 int match = 0; 830 int match = 0;
@@ -861,6 +836,7 @@ void *marker_get_private_data(const char *name, marker_probe_func *probe,
861 return closure[i].probe_private; 836 return closure[i].probe_private;
862 } 837 }
863 } 838 }
839 break;
864 } 840 }
865 } 841 }
866 return ERR_PTR(-ENOENT); 842 return ERR_PTR(-ENOENT);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 9d048fa2d902..6b6b727258b5 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -484,6 +484,16 @@ static struct ctl_table kern_table[] = {
484 .proc_handler = &ftrace_enable_sysctl, 484 .proc_handler = &ftrace_enable_sysctl,
485 }, 485 },
486#endif 486#endif
487#ifdef CONFIG_TRACING
488 {
489 .ctl_name = CTL_UNNUMBERED,
490 .procname = "ftrace_dump_on_opps",
491 .data = &ftrace_dump_on_oops,
492 .maxlen = sizeof(int),
493 .mode = 0644,
494 .proc_handler = &proc_dointvec,
495 },
496#endif
487#ifdef CONFIG_MODULES 497#ifdef CONFIG_MODULES
488 { 498 {
489 .ctl_name = KERN_MODPROBE, 499 .ctl_name = KERN_MODPROBE,
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 85bee775a03e..e4c40c868d67 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -64,6 +64,37 @@ static cpumask_t __read_mostly tracing_buffer_mask;
64 64
65static int tracing_disabled = 1; 65static int tracing_disabled = 1;
66 66
67/*
68 * ftrace_dump_on_oops - variable to dump ftrace buffer on oops
69 *
70 * If there is an oops (or kernel panic) and the ftrace_dump_on_oops
71 * is set, then ftrace_dump is called. This will output the contents
72 * of the ftrace buffers to the console. This is very useful for
73 * capturing traces that lead to crashes and outputing it to a
74 * serial console.
75 *
76 * It is default off, but you can enable it with either specifying
77 * "ftrace_dump_on_oops" in the kernel command line, or setting
78 * /proc/sys/kernel/ftrace_dump_on_oops to true.
79 */
80int ftrace_dump_on_oops;
81
82static int tracing_set_tracer(char *buf);
83
84static int __init set_ftrace(char *str)
85{
86 tracing_set_tracer(str);
87 return 1;
88}
89__setup("ftrace", set_ftrace);
90
91static int __init set_ftrace_dump_on_oops(char *str)
92{
93 ftrace_dump_on_oops = 1;
94 return 1;
95}
96__setup("ftrace_dump_on_oops", set_ftrace_dump_on_oops);
97
67long 98long
68ns2usecs(cycle_t nsec) 99ns2usecs(cycle_t nsec)
69{ 100{
@@ -2374,29 +2405,11 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf,
2374 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 2405 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2375} 2406}
2376 2407
2377static ssize_t 2408static int tracing_set_tracer(char *buf)
2378tracing_set_trace_write(struct file *filp, const char __user *ubuf,
2379 size_t cnt, loff_t *ppos)
2380{ 2409{
2381 struct trace_array *tr = &global_trace; 2410 struct trace_array *tr = &global_trace;
2382 struct tracer *t; 2411 struct tracer *t;
2383 char buf[max_tracer_type_len+1]; 2412 int ret = 0;
2384 int i;
2385 size_t ret;
2386
2387 ret = cnt;
2388
2389 if (cnt > max_tracer_type_len)
2390 cnt = max_tracer_type_len;
2391
2392 if (copy_from_user(&buf, ubuf, cnt))
2393 return -EFAULT;
2394
2395 buf[cnt] = 0;
2396
2397 /* strip ending whitespace. */
2398 for (i = cnt - 1; i > 0 && isspace(buf[i]); i--)
2399 buf[i] = 0;
2400 2413
2401 mutex_lock(&trace_types_lock); 2414 mutex_lock(&trace_types_lock);
2402 for (t = trace_types; t; t = t->next) { 2415 for (t = trace_types; t; t = t->next) {
@@ -2420,6 +2433,33 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
2420 out: 2433 out:
2421 mutex_unlock(&trace_types_lock); 2434 mutex_unlock(&trace_types_lock);
2422 2435
2436 return ret;
2437}
2438
2439static ssize_t
2440tracing_set_trace_write(struct file *filp, const char __user *ubuf,
2441 size_t cnt, loff_t *ppos)
2442{
2443 char buf[max_tracer_type_len+1];
2444 int i;
2445 size_t ret;
2446
2447 if (cnt > max_tracer_type_len)
2448 cnt = max_tracer_type_len;
2449
2450 if (copy_from_user(&buf, ubuf, cnt))
2451 return -EFAULT;
2452
2453 buf[cnt] = 0;
2454
2455 /* strip ending whitespace. */
2456 for (i = cnt - 1; i > 0 && isspace(buf[i]); i--)
2457 buf[i] = 0;
2458
2459 ret = tracing_set_tracer(buf);
2460 if (!ret)
2461 ret = cnt;
2462
2423 if (ret > 0) 2463 if (ret > 0)
2424 filp->f_pos += ret; 2464 filp->f_pos += ret;
2425 2465
@@ -2822,22 +2862,38 @@ static struct file_operations tracing_mark_fops = {
2822 2862
2823#ifdef CONFIG_DYNAMIC_FTRACE 2863#ifdef CONFIG_DYNAMIC_FTRACE
2824 2864
2865int __weak ftrace_arch_read_dyn_info(char *buf, int size)
2866{
2867 return 0;
2868}
2869
2825static ssize_t 2870static ssize_t
2826tracing_read_long(struct file *filp, char __user *ubuf, 2871tracing_read_dyn_info(struct file *filp, char __user *ubuf,
2827 size_t cnt, loff_t *ppos) 2872 size_t cnt, loff_t *ppos)
2828{ 2873{
2874 static char ftrace_dyn_info_buffer[1024];
2875 static DEFINE_MUTEX(dyn_info_mutex);
2829 unsigned long *p = filp->private_data; 2876 unsigned long *p = filp->private_data;
2830 char buf[64]; 2877 char *buf = ftrace_dyn_info_buffer;
2878 int size = ARRAY_SIZE(ftrace_dyn_info_buffer);
2831 int r; 2879 int r;
2832 2880
2833 r = sprintf(buf, "%ld\n", *p); 2881 mutex_lock(&dyn_info_mutex);
2882 r = sprintf(buf, "%ld ", *p);
2834 2883
2835 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); 2884 r += ftrace_arch_read_dyn_info(buf+r, (size-1)-r);
2885 buf[r++] = '\n';
2886
2887 r = simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2888
2889 mutex_unlock(&dyn_info_mutex);
2890
2891 return r;
2836} 2892}
2837 2893
2838static struct file_operations tracing_read_long_fops = { 2894static struct file_operations tracing_dyn_info_fops = {
2839 .open = tracing_open_generic, 2895 .open = tracing_open_generic,
2840 .read = tracing_read_long, 2896 .read = tracing_read_dyn_info,
2841}; 2897};
2842#endif 2898#endif
2843 2899
@@ -2946,7 +3002,7 @@ static __init int tracer_init_debugfs(void)
2946#ifdef CONFIG_DYNAMIC_FTRACE 3002#ifdef CONFIG_DYNAMIC_FTRACE
2947 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, 3003 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
2948 &ftrace_update_tot_cnt, 3004 &ftrace_update_tot_cnt,
2949 &tracing_read_long_fops); 3005 &tracing_dyn_info_fops);
2950 if (!entry) 3006 if (!entry)
2951 pr_warning("Could not create debugfs " 3007 pr_warning("Could not create debugfs "
2952 "'dyn_ftrace_total_info' entry\n"); 3008 "'dyn_ftrace_total_info' entry\n");
@@ -3027,7 +3083,8 @@ EXPORT_SYMBOL_GPL(__ftrace_printk);
3027static int trace_panic_handler(struct notifier_block *this, 3083static int trace_panic_handler(struct notifier_block *this,
3028 unsigned long event, void *unused) 3084 unsigned long event, void *unused)
3029{ 3085{
3030 ftrace_dump(); 3086 if (ftrace_dump_on_oops)
3087 ftrace_dump();
3031 return NOTIFY_OK; 3088 return NOTIFY_OK;
3032} 3089}
3033 3090
@@ -3043,7 +3100,8 @@ static int trace_die_handler(struct notifier_block *self,
3043{ 3100{
3044 switch (val) { 3101 switch (val) {
3045 case DIE_OOPS: 3102 case DIE_OOPS:
3046 ftrace_dump(); 3103 if (ftrace_dump_on_oops)
3104 ftrace_dump();
3047 break; 3105 break;
3048 default: 3106 default:
3049 break; 3107 break;
@@ -3084,7 +3142,6 @@ trace_printk_seq(struct trace_seq *s)
3084 trace_seq_reset(s); 3142 trace_seq_reset(s);
3085} 3143}
3086 3144
3087
3088void ftrace_dump(void) 3145void ftrace_dump(void)
3089{ 3146{
3090 static DEFINE_SPINLOCK(ftrace_dump_lock); 3147 static DEFINE_SPINLOCK(ftrace_dump_lock);
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index af8c85664882..e96590f17de1 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -43,6 +43,7 @@ static DEFINE_MUTEX(tracepoints_mutex);
43 */ 43 */
44#define TRACEPOINT_HASH_BITS 6 44#define TRACEPOINT_HASH_BITS 6
45#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) 45#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
46static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
46 47
47/* 48/*
48 * Note about RCU : 49 * Note about RCU :
@@ -54,40 +55,43 @@ struct tracepoint_entry {
54 struct hlist_node hlist; 55 struct hlist_node hlist;
55 void **funcs; 56 void **funcs;
56 int refcount; /* Number of times armed. 0 if disarmed. */ 57 int refcount; /* Number of times armed. 0 if disarmed. */
57 struct rcu_head rcu;
58 void *oldptr;
59 unsigned char rcu_pending:1;
60 char name[0]; 58 char name[0];
61}; 59};
62 60
63static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; 61struct tp_probes {
62 union {
63 struct rcu_head rcu;
64 struct list_head list;
65 } u;
66 void *probes[0];
67};
64 68
65static void free_old_closure(struct rcu_head *head) 69static inline void *allocate_probes(int count)
66{ 70{
67 struct tracepoint_entry *entry = container_of(head, 71 struct tp_probes *p = kmalloc(count * sizeof(void *)
68 struct tracepoint_entry, rcu); 72 + sizeof(struct tp_probes), GFP_KERNEL);
69 kfree(entry->oldptr); 73 return p == NULL ? NULL : p->probes;
70 /* Make sure we free the data before setting the pending flag to 0 */
71 smp_wmb();
72 entry->rcu_pending = 0;
73} 74}
74 75
75static void tracepoint_entry_free_old(struct tracepoint_entry *entry, void *old) 76static void rcu_free_old_probes(struct rcu_head *head)
76{ 77{
77 if (!old) 78 kfree(container_of(head, struct tp_probes, u.rcu));
78 return; 79}
79 entry->oldptr = old; 80
80 entry->rcu_pending = 1; 81static inline void release_probes(void *old)
81 /* write rcu_pending before calling the RCU callback */ 82{
82 smp_wmb(); 83 if (old) {
83 call_rcu_sched(&entry->rcu, free_old_closure); 84 struct tp_probes *tp_probes = container_of(old,
85 struct tp_probes, probes[0]);
86 call_rcu_sched(&tp_probes->u.rcu, rcu_free_old_probes);
87 }
84} 88}
85 89
86static void debug_print_probes(struct tracepoint_entry *entry) 90static void debug_print_probes(struct tracepoint_entry *entry)
87{ 91{
88 int i; 92 int i;
89 93
90 if (!tracepoint_debug) 94 if (!tracepoint_debug || !entry->funcs)
91 return; 95 return;
92 96
93 for (i = 0; entry->funcs[i]; i++) 97 for (i = 0; entry->funcs[i]; i++)
@@ -111,12 +115,13 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
111 return ERR_PTR(-EEXIST); 115 return ERR_PTR(-EEXIST);
112 } 116 }
113 /* + 2 : one for new probe, one for NULL func */ 117 /* + 2 : one for new probe, one for NULL func */
114 new = kzalloc((nr_probes + 2) * sizeof(void *), GFP_KERNEL); 118 new = allocate_probes(nr_probes + 2);
115 if (new == NULL) 119 if (new == NULL)
116 return ERR_PTR(-ENOMEM); 120 return ERR_PTR(-ENOMEM);
117 if (old) 121 if (old)
118 memcpy(new, old, nr_probes * sizeof(void *)); 122 memcpy(new, old, nr_probes * sizeof(void *));
119 new[nr_probes] = probe; 123 new[nr_probes] = probe;
124 new[nr_probes + 1] = NULL;
120 entry->refcount = nr_probes + 1; 125 entry->refcount = nr_probes + 1;
121 entry->funcs = new; 126 entry->funcs = new;
122 debug_print_probes(entry); 127 debug_print_probes(entry);
@@ -132,7 +137,7 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
132 old = entry->funcs; 137 old = entry->funcs;
133 138
134 if (!old) 139 if (!old)
135 return NULL; 140 return ERR_PTR(-ENOENT);
136 141
137 debug_print_probes(entry); 142 debug_print_probes(entry);
138 /* (N -> M), (N > 1, M >= 0) probes */ 143 /* (N -> M), (N > 1, M >= 0) probes */
@@ -151,13 +156,13 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
151 int j = 0; 156 int j = 0;
152 /* N -> M, (N > 1, M > 0) */ 157 /* N -> M, (N > 1, M > 0) */
153 /* + 1 for NULL */ 158 /* + 1 for NULL */
154 new = kzalloc((nr_probes - nr_del + 1) 159 new = allocate_probes(nr_probes - nr_del + 1);
155 * sizeof(void *), GFP_KERNEL);
156 if (new == NULL) 160 if (new == NULL)
157 return ERR_PTR(-ENOMEM); 161 return ERR_PTR(-ENOMEM);
158 for (i = 0; old[i]; i++) 162 for (i = 0; old[i]; i++)
159 if ((probe && old[i] != probe)) 163 if ((probe && old[i] != probe))
160 new[j++] = old[i]; 164 new[j++] = old[i];
165 new[nr_probes - nr_del] = NULL;
161 entry->refcount = nr_probes - nr_del; 166 entry->refcount = nr_probes - nr_del;
162 entry->funcs = new; 167 entry->funcs = new;
163 } 168 }
@@ -215,7 +220,6 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
215 memcpy(&e->name[0], name, name_len); 220 memcpy(&e->name[0], name, name_len);
216 e->funcs = NULL; 221 e->funcs = NULL;
217 e->refcount = 0; 222 e->refcount = 0;
218 e->rcu_pending = 0;
219 hlist_add_head(&e->hlist, head); 223 hlist_add_head(&e->hlist, head);
220 return e; 224 return e;
221} 225}
@@ -224,32 +228,10 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
224 * Remove the tracepoint from the tracepoint hash table. Must be called with 228 * Remove the tracepoint from the tracepoint hash table. Must be called with
225 * mutex_lock held. 229 * mutex_lock held.
226 */ 230 */
227static int remove_tracepoint(const char *name) 231static inline void remove_tracepoint(struct tracepoint_entry *e)
228{ 232{
229 struct hlist_head *head;
230 struct hlist_node *node;
231 struct tracepoint_entry *e;
232 int found = 0;
233 size_t len = strlen(name) + 1;
234 u32 hash = jhash(name, len-1, 0);
235
236 head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
237 hlist_for_each_entry(e, node, head, hlist) {
238 if (!strcmp(name, e->name)) {
239 found = 1;
240 break;
241 }
242 }
243 if (!found)
244 return -ENOENT;
245 if (e->refcount)
246 return -EBUSY;
247 hlist_del(&e->hlist); 233 hlist_del(&e->hlist);
248 /* Make sure the call_rcu_sched has been executed */
249 if (e->rcu_pending)
250 rcu_barrier_sched();
251 kfree(e); 234 kfree(e);
252 return 0;
253} 235}
254 236
255/* 237/*
@@ -320,6 +302,23 @@ static void tracepoint_update_probes(void)
320 module_update_tracepoints(); 302 module_update_tracepoints();
321} 303}
322 304
305static void *tracepoint_add_probe(const char *name, void *probe)
306{
307 struct tracepoint_entry *entry;
308 void *old;
309
310 entry = get_tracepoint(name);
311 if (!entry) {
312 entry = add_tracepoint(name);
313 if (IS_ERR(entry))
314 return entry;
315 }
316 old = tracepoint_entry_add_probe(entry, probe);
317 if (IS_ERR(old) && !entry->refcount)
318 remove_tracepoint(entry);
319 return old;
320}
321
323/** 322/**
324 * tracepoint_probe_register - Connect a probe to a tracepoint 323 * tracepoint_probe_register - Connect a probe to a tracepoint
325 * @name: tracepoint name 324 * @name: tracepoint name
@@ -330,44 +329,36 @@ static void tracepoint_update_probes(void)
330 */ 329 */
331int tracepoint_probe_register(const char *name, void *probe) 330int tracepoint_probe_register(const char *name, void *probe)
332{ 331{
333 struct tracepoint_entry *entry;
334 int ret = 0;
335 void *old; 332 void *old;
336 333
337 mutex_lock(&tracepoints_mutex); 334 mutex_lock(&tracepoints_mutex);
338 entry = get_tracepoint(name); 335 old = tracepoint_add_probe(name, probe);
339 if (!entry) {
340 entry = add_tracepoint(name);
341 if (IS_ERR(entry)) {
342 ret = PTR_ERR(entry);
343 goto end;
344 }
345 }
346 /*
347 * If we detect that a call_rcu_sched is pending for this tracepoint,
348 * make sure it's executed now.
349 */
350 if (entry->rcu_pending)
351 rcu_barrier_sched();
352 old = tracepoint_entry_add_probe(entry, probe);
353 if (IS_ERR(old)) {
354 ret = PTR_ERR(old);
355 goto end;
356 }
357 mutex_unlock(&tracepoints_mutex); 336 mutex_unlock(&tracepoints_mutex);
337 if (IS_ERR(old))
338 return PTR_ERR(old);
339
358 tracepoint_update_probes(); /* may update entry */ 340 tracepoint_update_probes(); /* may update entry */
359 mutex_lock(&tracepoints_mutex); 341 release_probes(old);
360 entry = get_tracepoint(name); 342 return 0;
361 WARN_ON(!entry);
362 if (entry->rcu_pending)
363 rcu_barrier_sched();
364 tracepoint_entry_free_old(entry, old);
365end:
366 mutex_unlock(&tracepoints_mutex);
367 return ret;
368} 343}
369EXPORT_SYMBOL_GPL(tracepoint_probe_register); 344EXPORT_SYMBOL_GPL(tracepoint_probe_register);
370 345
346static void *tracepoint_remove_probe(const char *name, void *probe)
347{
348 struct tracepoint_entry *entry;
349 void *old;
350
351 entry = get_tracepoint(name);
352 if (!entry)
353 return ERR_PTR(-ENOENT);
354 old = tracepoint_entry_remove_probe(entry, probe);
355 if (IS_ERR(old))
356 return old;
357 if (!entry->refcount)
358 remove_tracepoint(entry);
359 return old;
360}
361
371/** 362/**
372 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint 363 * tracepoint_probe_unregister - Disconnect a probe from a tracepoint
373 * @name: tracepoint name 364 * @name: tracepoint name
@@ -380,38 +371,104 @@ EXPORT_SYMBOL_GPL(tracepoint_probe_register);
380 */ 371 */
381int tracepoint_probe_unregister(const char *name, void *probe) 372int tracepoint_probe_unregister(const char *name, void *probe)
382{ 373{
383 struct tracepoint_entry *entry;
384 void *old; 374 void *old;
385 int ret = -ENOENT;
386 375
387 mutex_lock(&tracepoints_mutex); 376 mutex_lock(&tracepoints_mutex);
388 entry = get_tracepoint(name); 377 old = tracepoint_remove_probe(name, probe);
389 if (!entry)
390 goto end;
391 if (entry->rcu_pending)
392 rcu_barrier_sched();
393 old = tracepoint_entry_remove_probe(entry, probe);
394 if (!old) {
395 printk(KERN_WARNING "Warning: Trying to unregister a probe"
396 "that doesn't exist\n");
397 goto end;
398 }
399 mutex_unlock(&tracepoints_mutex); 378 mutex_unlock(&tracepoints_mutex);
379 if (IS_ERR(old))
380 return PTR_ERR(old);
381
400 tracepoint_update_probes(); /* may update entry */ 382 tracepoint_update_probes(); /* may update entry */
383 release_probes(old);
384 return 0;
385}
386EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
387
388static LIST_HEAD(old_probes);
389static int need_update;
390
391static void tracepoint_add_old_probes(void *old)
392{
393 need_update = 1;
394 if (old) {
395 struct tp_probes *tp_probes = container_of(old,
396 struct tp_probes, probes[0]);
397 list_add(&tp_probes->u.list, &old_probes);
398 }
399}
400
401/**
402 * tracepoint_probe_register_noupdate - register a probe but not connect
403 * @name: tracepoint name
404 * @probe: probe handler
405 *
406 * caller must call tracepoint_probe_update_all()
407 */
408int tracepoint_probe_register_noupdate(const char *name, void *probe)
409{
410 void *old;
411
401 mutex_lock(&tracepoints_mutex); 412 mutex_lock(&tracepoints_mutex);
402 entry = get_tracepoint(name); 413 old = tracepoint_add_probe(name, probe);
403 if (!entry) 414 if (IS_ERR(old)) {
404 goto end; 415 mutex_unlock(&tracepoints_mutex);
405 if (entry->rcu_pending) 416 return PTR_ERR(old);
406 rcu_barrier_sched(); 417 }
407 tracepoint_entry_free_old(entry, old); 418 tracepoint_add_old_probes(old);
408 remove_tracepoint(name); /* Ignore busy error message */
409 ret = 0;
410end:
411 mutex_unlock(&tracepoints_mutex); 419 mutex_unlock(&tracepoints_mutex);
412 return ret; 420 return 0;
413} 421}
414EXPORT_SYMBOL_GPL(tracepoint_probe_unregister); 422EXPORT_SYMBOL_GPL(tracepoint_probe_register_noupdate);
423
424/**
425 * tracepoint_probe_unregister_noupdate - remove a probe but not disconnect
426 * @name: tracepoint name
427 * @probe: probe function pointer
428 *
429 * caller must call tracepoint_probe_update_all()
430 */
431int tracepoint_probe_unregister_noupdate(const char *name, void *probe)
432{
433 void *old;
434
435 mutex_lock(&tracepoints_mutex);
436 old = tracepoint_remove_probe(name, probe);
437 if (IS_ERR(old)) {
438 mutex_unlock(&tracepoints_mutex);
439 return PTR_ERR(old);
440 }
441 tracepoint_add_old_probes(old);
442 mutex_unlock(&tracepoints_mutex);
443 return 0;
444}
445EXPORT_SYMBOL_GPL(tracepoint_probe_unregister_noupdate);
446
447/**
448 * tracepoint_probe_update_all - update tracepoints
449 */
450void tracepoint_probe_update_all(void)
451{
452 LIST_HEAD(release_probes);
453 struct tp_probes *pos, *next;
454
455 mutex_lock(&tracepoints_mutex);
456 if (!need_update) {
457 mutex_unlock(&tracepoints_mutex);
458 return;
459 }
460 if (!list_empty(&old_probes))
461 list_replace_init(&old_probes, &release_probes);
462 need_update = 0;
463 mutex_unlock(&tracepoints_mutex);
464
465 tracepoint_update_probes();
466 list_for_each_entry_safe(pos, next, &release_probes, u.list) {
467 list_del(&pos->u.list);
468 call_rcu_sched(&pos->u.rcu, rcu_free_old_probes);
469 }
470}
471EXPORT_SYMBOL_GPL(tracepoint_probe_update_all);
415 472
416/** 473/**
417 * tracepoint_get_iter_range - Get a next tracepoint iterator given a range. 474 * tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 468fbc9016c7..7a176773af85 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -198,16 +198,10 @@ cmd_modversions = \
198 fi; 198 fi;
199endif 199endif
200 200
201ifdef CONFIG_64BIT
202arch_bits = 64
203else
204arch_bits = 32
205endif
206
207ifdef CONFIG_FTRACE_MCOUNT_RECORD 201ifdef CONFIG_FTRACE_MCOUNT_RECORD
208cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \ 202cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
209 "$(ARCH)" "$(arch_bits)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" \ 203 "$(if $(CONFIG_64BIT),64,32)" \
210 "$(NM)" "$(RM)" "$(MV)" "$(@)"; 204 "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" "$(@)";
211endif 205endif
212 206
213define rule_cc_o_c 207define rule_cc_o_c
diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py
new file mode 100644
index 000000000000..902f9a992620
--- /dev/null
+++ b/scripts/tracing/draw_functrace.py
@@ -0,0 +1,130 @@
1#!/usr/bin/python
2
3"""
4Copyright 2008 (c) Frederic Weisbecker <fweisbec@gmail.com>
5Licensed under the terms of the GNU GPL License version 2
6
7This script parses a trace provided by the function tracer in
8kernel/trace/trace_functions.c
9The resulted trace is processed into a tree to produce a more human
10view of the call stack by drawing textual but hierarchical tree of
11calls. Only the functions's names and the the call time are provided.
12
13Usage:
14 Be sure that you have CONFIG_FUNCTION_TRACER
15 # mkdir /debugfs
16 # mount -t debug debug /debug
17 # echo function > /debug/tracing/current_tracer
18 $ cat /debug/tracing/trace_pipe > ~/raw_trace_func
19 Wait some times but not too much, the script is a bit slow.
20 Break the pipe (Ctrl + Z)
21 $ scripts/draw_functrace.py < raw_trace_func > draw_functrace
22 Then you have your drawn trace in draw_functrace
23"""
24
25
26import sys, re
27
28class CallTree:
29 """ This class provides a tree representation of the functions
30 call stack. If a function has no parent in the kernel (interrupt,
31 syscall, kernel thread...) then it is attached to a virtual parent
32 called ROOT.
33 """
34 ROOT = None
35
36 def __init__(self, func, time = None, parent = None):
37 self._func = func
38 self._time = time
39 if parent is None:
40 self._parent = CallTree.ROOT
41 else:
42 self._parent = parent
43 self._children = []
44
45 def calls(self, func, calltime):
46 """ If a function calls another one, call this method to insert it
47 into the tree at the appropriate place.
48 @return: A reference to the newly created child node.
49 """
50 child = CallTree(func, calltime, self)
51 self._children.append(child)
52 return child
53
54 def getParent(self, func):
55 """ Retrieve the last parent of the current node that
56 has the name given by func. If this function is not
57 on a parent, then create it as new child of root
58 @return: A reference to the parent.
59 """
60 tree = self
61 while tree != CallTree.ROOT and tree._func != func:
62 tree = tree._parent
63 if tree == CallTree.ROOT:
64 child = CallTree.ROOT.calls(func, None)
65 return child
66 return tree
67
68 def __repr__(self):
69 return self.__toString("", True)
70
71 def __toString(self, branch, lastChild):
72 if self._time is not None:
73 s = "%s----%s (%s)\n" % (branch, self._func, self._time)
74 else:
75 s = "%s----%s\n" % (branch, self._func)
76
77 i = 0
78 if lastChild:
79 branch = branch[:-1] + " "
80 while i < len(self._children):
81 if i != len(self._children) - 1:
82 s += "%s" % self._children[i].__toString(branch +\
83 " |", False)
84 else:
85 s += "%s" % self._children[i].__toString(branch +\
86 " |", True)
87 i += 1
88 return s
89
90class BrokenLineException(Exception):
91 """If the last line is not complete because of the pipe breakage,
92 we want to stop the processing and ignore this line.
93 """
94 pass
95
96class CommentLineException(Exception):
97 """ If the line is a comment (as in the beginning of the trace file),
98 just ignore it.
99 """
100 pass
101
102
103def parseLine(line):
104 line = line.strip()
105 if line.startswith("#"):
106 raise CommentLineException
107 m = re.match("[^]]+?\\] +([0-9.]+): (\\w+) <-(\\w+)", line)
108 if m is None:
109 raise BrokenLineException
110 return (m.group(1), m.group(2), m.group(3))
111
112
113def main():
114 CallTree.ROOT = CallTree("Root (Nowhere)", None, None)
115 tree = CallTree.ROOT
116
117 for line in sys.stdin:
118 try:
119 calltime, callee, caller = parseLine(line)
120 except BrokenLineException:
121 break
122 except CommentLineException:
123 continue
124 tree = tree.getParent(caller)
125 tree = tree.calls(callee, calltime)
126
127 print CallTree.ROOT
128
129if __name__ == "__main__":
130 main()