aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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.h3
-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/trace/Kconfig2
-rw-r--r--kernel/trace/trace.c32
-rw-r--r--kernel/tracepoint.c261
17 files changed, 398 insertions, 174 deletions
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 899ec4b26b6c..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
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/trace/Kconfig b/kernel/trace/Kconfig
index b58f43bec363..33dbefd471e8 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -25,7 +25,7 @@ config TRACING
25 bool 25 bool
26 select DEBUG_FS 26 select DEBUG_FS
27 select RING_BUFFER 27 select RING_BUFFER
28 select STACKTRACE 28 select STACKTRACE if STACKTRACE_SUPPORT
29 select TRACEPOINTS 29 select TRACEPOINTS
30 select NOP_TRACER 30 select NOP_TRACER
31 31
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 482583eb8001..e4c40c868d67 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -736,6 +736,7 @@ static void ftrace_trace_stack(struct trace_array *tr,
736 unsigned long flags, 736 unsigned long flags,
737 int skip, int pc) 737 int skip, int pc)
738{ 738{
739#ifdef CONFIG_STACKTRACE
739 struct ring_buffer_event *event; 740 struct ring_buffer_event *event;
740 struct stack_entry *entry; 741 struct stack_entry *entry;
741 struct stack_trace trace; 742 struct stack_trace trace;
@@ -761,6 +762,7 @@ static void ftrace_trace_stack(struct trace_array *tr,
761 762
762 save_stack_trace(&trace); 763 save_stack_trace(&trace);
763 ring_buffer_unlock_commit(tr->buffer, event, irq_flags); 764 ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
765#endif
764} 766}
765 767
766void __trace_stack(struct trace_array *tr, 768void __trace_stack(struct trace_array *tr,
@@ -2860,22 +2862,38 @@ static struct file_operations tracing_mark_fops = {
2860 2862
2861#ifdef CONFIG_DYNAMIC_FTRACE 2863#ifdef CONFIG_DYNAMIC_FTRACE
2862 2864
2865int __weak ftrace_arch_read_dyn_info(char *buf, int size)
2866{
2867 return 0;
2868}
2869
2863static ssize_t 2870static ssize_t
2864tracing_read_long(struct file *filp, char __user *ubuf, 2871tracing_read_dyn_info(struct file *filp, char __user *ubuf,
2865 size_t cnt, loff_t *ppos) 2872 size_t cnt, loff_t *ppos)
2866{ 2873{
2874 static char ftrace_dyn_info_buffer[1024];
2875 static DEFINE_MUTEX(dyn_info_mutex);
2867 unsigned long *p = filp->private_data; 2876 unsigned long *p = filp->private_data;
2868 char buf[64]; 2877 char *buf = ftrace_dyn_info_buffer;
2878 int size = ARRAY_SIZE(ftrace_dyn_info_buffer);
2869 int r; 2879 int r;
2870 2880
2871 r = sprintf(buf, "%ld\n", *p); 2881 mutex_lock(&dyn_info_mutex);
2882 r = sprintf(buf, "%ld ", *p);
2872 2883
2873 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;
2874} 2892}
2875 2893
2876static struct file_operations tracing_read_long_fops = { 2894static struct file_operations tracing_dyn_info_fops = {
2877 .open = tracing_open_generic, 2895 .open = tracing_open_generic,
2878 .read = tracing_read_long, 2896 .read = tracing_read_dyn_info,
2879}; 2897};
2880#endif 2898#endif
2881 2899
@@ -2984,7 +3002,7 @@ static __init int tracer_init_debugfs(void)
2984#ifdef CONFIG_DYNAMIC_FTRACE 3002#ifdef CONFIG_DYNAMIC_FTRACE
2985 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, 3003 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
2986 &ftrace_update_tot_cnt, 3004 &ftrace_update_tot_cnt,
2987 &tracing_read_long_fops); 3005 &tracing_dyn_info_fops);
2988 if (!entry) 3006 if (!entry)
2989 pr_warning("Could not create debugfs " 3007 pr_warning("Could not create debugfs "
2990 "'dyn_ftrace_total_info' entry\n"); 3008 "'dyn_ftrace_total_info' entry\n");
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.