summaryrefslogtreecommitdiff
path: root/kernel/tracepoint.c
diff options
context:
space:
mode:
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,
{
WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+ if (elem->regfunc && !elem->state && active)
+ elem->regfunc();
+ else if (elem->unregfunc && elem->state && !active)
+ elem->unregfunc();
+
/*
* rcu_assign_pointer has a smp_wmb() which makes sure that the new
* probe callbacks array is consistent before setting a pointer to it.
@@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,
*/
static void disable_tracepoint(struct tracepoint *elem)
{
+ if (elem->unregfunc && elem->state)
+ elem->unregfunc();
+
elem->state = 0;
rcu_assign_pointer(elem->funcs, NULL);
}
@@ -578,7 +586,7 @@ __initcall(init_tracepoints);
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
-static DEFINE_MUTEX(regfunc_mutex);
+/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
static int sys_tracepoint_refcount;
void syscall_regfunc(void)
@@ -586,7 +594,6 @@ void syscall_regfunc(void)
unsigned long flags;
struct task_struct *g, *t;
- mutex_lock(&regfunc_mutex);
if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags);
do_each_thread(g, t) {
@@ -595,7 +602,6 @@ void syscall_regfunc(void)
read_unlock_irqrestore(&tasklist_lock, flags);
}
sys_tracepoint_refcount++;
- mutex_unlock(&regfunc_mutex);
}
void syscall_unregfunc(void)
@@ -603,7 +609,6 @@ void syscall_unregfunc(void)
unsigned long flags;
struct task_struct *g, *t;
- mutex_lock(&regfunc_mutex);
sys_tracepoint_refcount--;
if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags);
@@ -612,6 +617,5 @@ void syscall_unregfunc(void)
} while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags);
}
- mutex_unlock(&regfunc_mutex);
}
#endif