aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/tracepoint.c
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-08-24 17:43:13 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-08-25 18:36:41 -0400
commit97419875865859fd2403e66266c02ce028e2f5ab (patch)
tree7df6e6df767e9c8ff538a50bcae17638a1c8da99 /kernel/tracepoint.c
parent3d27d8cb34fc156beb86de2338ca4029873a5cc6 (diff)
tracing: Move tracepoint callbacks from declaration to definition
It's not strictly correct for the tracepoint reg/unreg callbacks to occur when a client is hooking up, because the actual tracepoint may not be present yet. This happens to be fine for syscall, since that's in the core kernel, but it would cause problems for tracepoints defined in a module that hasn't been loaded yet. It also means the reg/unreg has to be EXPORTed for any modules to use the tracepoint (as in SystemTap). This patch removes DECLARE_TRACE_WITH_CALLBACK, and instead introduces DEFINE_TRACE_FN which stores the callbacks in struct tracepoint. The callbacks are used now when the active state of the tracepoint changes in set_tracepoint & disable_tracepoint. This also introduces TRACE_EVENT_FN, so ftrace events can also provide registration callbacks if needed. Signed-off-by: Josh Stone <jistone@redhat.com> Cc: Jason Baron <jbaron@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Jiaying Zhang <jiayingz@google.com> Cc: Martin Bligh <mbligh@google.com> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> LKML-Reference: <1251150194-1713-4-git-send-email-jistone@redhat.com> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'kernel/tracepoint.c')
-rw-r--r--kernel/tracepoint.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
index 9e0a36f0e2a9..1a6a453b7efb 100644
--- a/kernel/tracepoint.c
+++ b/kernel/tracepoint.c
@@ -243,6 +243,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,
243{ 243{
244 WARN_ON(strcmp((*entry)->name, elem->name) != 0); 244 WARN_ON(strcmp((*entry)->name, elem->name) != 0);
245 245
246 if (elem->regfunc && !elem->state && active)
247 elem->regfunc();
248 else if (elem->unregfunc && elem->state && !active)
249 elem->unregfunc();
250
246 /* 251 /*
247 * rcu_assign_pointer has a smp_wmb() which makes sure that the new 252 * rcu_assign_pointer has a smp_wmb() which makes sure that the new
248 * probe callbacks array is consistent before setting a pointer to it. 253 * probe callbacks array is consistent before setting a pointer to it.
@@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,
262 */ 267 */
263static void disable_tracepoint(struct tracepoint *elem) 268static void disable_tracepoint(struct tracepoint *elem)
264{ 269{
270 if (elem->unregfunc && elem->state)
271 elem->unregfunc();
272
265 elem->state = 0; 273 elem->state = 0;
266 rcu_assign_pointer(elem->funcs, NULL); 274 rcu_assign_pointer(elem->funcs, NULL);
267} 275}
@@ -578,7 +586,7 @@ __initcall(init_tracepoints);
578 586
579#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS 587#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
580 588
581static DEFINE_MUTEX(regfunc_mutex); 589/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
582static int sys_tracepoint_refcount; 590static int sys_tracepoint_refcount;
583 591
584void syscall_regfunc(void) 592void syscall_regfunc(void)
@@ -586,7 +594,6 @@ void syscall_regfunc(void)
586 unsigned long flags; 594 unsigned long flags;
587 struct task_struct *g, *t; 595 struct task_struct *g, *t;
588 596
589 mutex_lock(&regfunc_mutex);
590 if (!sys_tracepoint_refcount) { 597 if (!sys_tracepoint_refcount) {
591 read_lock_irqsave(&tasklist_lock, flags); 598 read_lock_irqsave(&tasklist_lock, flags);
592 do_each_thread(g, t) { 599 do_each_thread(g, t) {
@@ -595,7 +602,6 @@ void syscall_regfunc(void)
595 read_unlock_irqrestore(&tasklist_lock, flags); 602 read_unlock_irqrestore(&tasklist_lock, flags);
596 } 603 }
597 sys_tracepoint_refcount++; 604 sys_tracepoint_refcount++;
598 mutex_unlock(&regfunc_mutex);
599} 605}
600 606
601void syscall_unregfunc(void) 607void syscall_unregfunc(void)
@@ -603,7 +609,6 @@ void syscall_unregfunc(void)
603 unsigned long flags; 609 unsigned long flags;
604 struct task_struct *g, *t; 610 struct task_struct *g, *t;
605 611
606 mutex_lock(&regfunc_mutex);
607 sys_tracepoint_refcount--; 612 sys_tracepoint_refcount--;
608 if (!sys_tracepoint_refcount) { 613 if (!sys_tracepoint_refcount) {
609 read_lock_irqsave(&tasklist_lock, flags); 614 read_lock_irqsave(&tasklist_lock, flags);
@@ -612,6 +617,5 @@ void syscall_unregfunc(void)
612 } while_each_thread(g, t); 617 } while_each_thread(g, t);
613 read_unlock_irqrestore(&tasklist_lock, flags); 618 read_unlock_irqrestore(&tasklist_lock, flags);
614 } 619 }
615 mutex_unlock(&regfunc_mutex);
616} 620}
617#endif 621#endif