git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
sched: Fix select_task_rq() vs hotplug issues
[safe/jmp/linux-2.6]
/
kernel
/
tracepoint.c
diff --git
a/kernel/tracepoint.c
b/kernel/tracepoint.c
index
35dd27a
..
cc89be5
100644
(file)
--- a/
kernel/tracepoint.c
+++ b/
kernel/tracepoint.c
@@
-48,7
+48,7
@@
static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
/*
* Note about RCU :
/*
* 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.
*/
* 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);
{
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.
/*
* 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)
{
*/
static void disable_tracepoint(struct tracepoint *elem)
{
+ if (elem->unregfunc && elem->state)
+ elem->unregfunc();
+
elem->state = 0;
rcu_assign_pointer(elem->funcs, NULL);
}
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:
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);
case MODULE_STATE_GOING:
tracepoint_update_probe_range(mod->tracepoints,
mod->tracepoints + mod->num_tracepoints);
@@
-579,9
+584,9
@@
__initcall(init_tracepoints);
#endif /* CONFIG_MODULES */
#endif /* CONFIG_MODULES */
-#ifdef CONFIG_
FTRACE_SYSCALL
S
+#ifdef CONFIG_
HAVE_SYSCALL_TRACEPOINT
S
-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)
static int sys_tracepoint_refcount;
void syscall_regfunc(void)
@@
-589,16
+594,16
@@
void syscall_regfunc(void)
unsigned long flags;
struct task_struct *g, *t;
unsigned long flags;
struct task_struct *g, *t;
- mutex_lock(®func_mutex);
if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags);
do_each_thread(g, t) {
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++;
} while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags);
}
sys_tracepoint_refcount++;
- mutex_unlock(®func_mutex);
}
void syscall_unregfunc(void)
}
void syscall_unregfunc(void)
@@
-606,15
+611,13
@@
void syscall_unregfunc(void)
unsigned long flags;
struct task_struct *g, *t;
unsigned long flags;
struct task_struct *g, *t;
- mutex_lock(®func_mutex);
sys_tracepoint_refcount--;
if (!sys_tracepoint_refcount) {
read_lock_irqsave(&tasklist_lock, flags);
do_each_thread(g, t) {
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);
}
} while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags);
}
- mutex_unlock(®func_mutex);
}
#endif
}
#endif