diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-08-26 02:29:02 -0400 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-08-26 02:29:02 -0400 | 
| commit | 35dce1a99d010f3d738af4ce1b9b77302fdfe69c (patch) | |
| tree | e34a37de965a79a2ae301de4d0557f500111dde6 /kernel/tracepoint.c | |
| parent | 7cb2e3ee2aeec5b83ecadba929a2dc575dd4008f (diff) | |
| parent | 1c569f0264ea629c10bbab471dd0626ce4d3f19f (diff) | |
Merge branch 'tracing/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into tracing/core
Conflicts:
	include/linux/tracepoint.h
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/tracepoint.c')
| -rw-r--r-- | kernel/tracepoint.c | 20 | 
1 files changed, 12 insertions, 8 deletions
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 06f165a44083..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 | */ | 
| 263 | static void disable_tracepoint(struct tracepoint *elem) | 268 | static 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 | } | 
| @@ -576,9 +584,9 @@ __initcall(init_tracepoints); | |||
| 576 | 584 | ||
| 577 | #endif /* CONFIG_MODULES */ | 585 | #endif /* CONFIG_MODULES */ | 
| 578 | 586 | ||
| 579 | #ifdef CONFIG_FTRACE_SYSCALLS | 587 | #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS | 
| 580 | 588 | ||
| 581 | static DEFINE_MUTEX(regfunc_mutex); | 589 | /* NB: reg/unreg are called while guarded with the tracepoints_mutex */ | 
| 582 | static int sys_tracepoint_refcount; | 590 | static int sys_tracepoint_refcount; | 
| 583 | 591 | ||
| 584 | void syscall_regfunc(void) | 592 | void syscall_regfunc(void) | 
| @@ -586,16 +594,14 @@ 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(®func_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) { | 
| 593 | set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); | 600 | set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); | 
| 594 | } while_each_thread(g, t); | 601 | } while_each_thread(g, t); | 
| 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(®func_mutex); | ||
| 599 | } | 605 | } | 
| 600 | 606 | ||
| 601 | void syscall_unregfunc(void) | 607 | void syscall_unregfunc(void) | 
| @@ -603,15 +609,13 @@ 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(®func_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); | 
| 610 | do_each_thread(g, t) { | 615 | do_each_thread(g, t) { | 
| 611 | clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); | 616 | clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT); | 
| 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(®func_mutex); | ||
| 616 | } | 620 | } | 
| 617 | #endif | 621 | #endif | 
