ALSA: usb-audio: add support for Akai MPD16
[safe/jmp/linux-2.6] / kernel / tracepoint.c
index 070a42b..cc89be5 100644 (file)
@@ -48,7 +48,7 @@ static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
 
 /*
  * Note about RCU :
- * It is used to to delay the free of multiple probes array until a quiescent
+ * It is used to delay the free of multiple probes array until a quiescent
  * state is reached.
  * Tracepoint entries modifications are protected by the tracepoints_mutex.
  */
@@ -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);
 }
@@ -555,9 +563,6 @@ int tracepoint_module_notify(struct notifier_block *self,
 
        switch (val) {
        case MODULE_STATE_COMING:
-               tracepoint_update_probe_range(mod->tracepoints,
-                       mod->tracepoints + mod->num_tracepoints);
-               break;
        case MODULE_STATE_GOING:
                tracepoint_update_probe_range(mod->tracepoints,
                        mod->tracepoints + mod->num_tracepoints);
@@ -579,7 +584,9 @@ __initcall(init_tracepoints);
 
 #endif /* CONFIG_MODULES */
 
-static DEFINE_MUTEX(regfunc_mutex);
+#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
+
+/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
 static int sys_tracepoint_refcount;
 
 void syscall_regfunc(void)
@@ -587,16 +594,16 @@ 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) {
-                       set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+                       /* Skip kernel threads. */
+                       if (t->mm)
+                               set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
                } while_each_thread(g, t);
                read_unlock_irqrestore(&tasklist_lock, flags);
        }
        sys_tracepoint_refcount++;
-       mutex_unlock(&regfunc_mutex);
 }
 
 void syscall_unregfunc(void)
@@ -604,14 +611,13 @@ 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);
                do_each_thread(g, t) {
-                       clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE);
+                       clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);
                } while_each_thread(g, t);
                read_unlock_irqrestore(&tasklist_lock, flags);
        }
-       mutex_unlock(&regfunc_mutex);
 }
+#endif