diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/Kconfig | 4 | ||||
-rw-r--r-- | kernel/trace/trace_syscalls.c | 17 | ||||
-rw-r--r-- | kernel/tracepoint.c | 20 |
3 files changed, 23 insertions, 18 deletions
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 019f380fd764..06be85a7ef8c 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig | |||
@@ -41,7 +41,7 @@ config HAVE_FTRACE_MCOUNT_RECORD | |||
41 | config HAVE_HW_BRANCH_TRACER | 41 | config HAVE_HW_BRANCH_TRACER |
42 | bool | 42 | bool |
43 | 43 | ||
44 | config HAVE_FTRACE_SYSCALLS | 44 | config HAVE_SYSCALL_TRACEPOINTS |
45 | bool | 45 | bool |
46 | 46 | ||
47 | config TRACER_MAX_TRACE | 47 | config TRACER_MAX_TRACE |
@@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS | |||
211 | 211 | ||
212 | config FTRACE_SYSCALLS | 212 | config FTRACE_SYSCALLS |
213 | bool "Trace syscalls" | 213 | bool "Trace syscalls" |
214 | depends on HAVE_FTRACE_SYSCALLS | 214 | depends on HAVE_SYSCALL_TRACEPOINTS |
215 | select GENERIC_TRACER | 215 | select GENERIC_TRACER |
216 | select KALLSYMS | 216 | select KALLSYMS |
217 | help | 217 | help |
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 97a2454760b0..85291c4de406 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <trace/syscall.h> | 1 | #include <trace/syscall.h> |
2 | #include <trace/events/syscalls.h> | ||
2 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
3 | #include <linux/ftrace.h> | 4 | #include <linux/ftrace.h> |
4 | #include <linux/perf_counter.h> | 5 | #include <linux/perf_counter.h> |
@@ -288,7 +289,7 @@ int reg_event_syscall_enter(void *ptr) | |||
288 | return -ENOSYS; | 289 | return -ENOSYS; |
289 | mutex_lock(&syscall_trace_lock); | 290 | mutex_lock(&syscall_trace_lock); |
290 | if (!sys_refcount_enter) | 291 | if (!sys_refcount_enter) |
291 | ret = register_trace_syscall_enter(ftrace_syscall_enter); | 292 | ret = register_trace_sys_enter(ftrace_syscall_enter); |
292 | if (ret) { | 293 | if (ret) { |
293 | pr_info("event trace: Could not activate" | 294 | pr_info("event trace: Could not activate" |
294 | "syscall entry trace point"); | 295 | "syscall entry trace point"); |
@@ -313,7 +314,7 @@ void unreg_event_syscall_enter(void *ptr) | |||
313 | sys_refcount_enter--; | 314 | sys_refcount_enter--; |
314 | clear_bit(num, enabled_enter_syscalls); | 315 | clear_bit(num, enabled_enter_syscalls); |
315 | if (!sys_refcount_enter) | 316 | if (!sys_refcount_enter) |
316 | unregister_trace_syscall_enter(ftrace_syscall_enter); | 317 | unregister_trace_sys_enter(ftrace_syscall_enter); |
317 | mutex_unlock(&syscall_trace_lock); | 318 | mutex_unlock(&syscall_trace_lock); |
318 | } | 319 | } |
319 | 320 | ||
@@ -329,7 +330,7 @@ int reg_event_syscall_exit(void *ptr) | |||
329 | return -ENOSYS; | 330 | return -ENOSYS; |
330 | mutex_lock(&syscall_trace_lock); | 331 | mutex_lock(&syscall_trace_lock); |
331 | if (!sys_refcount_exit) | 332 | if (!sys_refcount_exit) |
332 | ret = register_trace_syscall_exit(ftrace_syscall_exit); | 333 | ret = register_trace_sys_exit(ftrace_syscall_exit); |
333 | if (ret) { | 334 | if (ret) { |
334 | pr_info("event trace: Could not activate" | 335 | pr_info("event trace: Could not activate" |
335 | "syscall exit trace point"); | 336 | "syscall exit trace point"); |
@@ -354,7 +355,7 @@ void unreg_event_syscall_exit(void *ptr) | |||
354 | sys_refcount_exit--; | 355 | sys_refcount_exit--; |
355 | clear_bit(num, enabled_exit_syscalls); | 356 | clear_bit(num, enabled_exit_syscalls); |
356 | if (!sys_refcount_exit) | 357 | if (!sys_refcount_exit) |
357 | unregister_trace_syscall_exit(ftrace_syscall_exit); | 358 | unregister_trace_sys_exit(ftrace_syscall_exit); |
358 | mutex_unlock(&syscall_trace_lock); | 359 | mutex_unlock(&syscall_trace_lock); |
359 | } | 360 | } |
360 | 361 | ||
@@ -420,7 +421,7 @@ int reg_prof_syscall_enter(char *name) | |||
420 | 421 | ||
421 | mutex_lock(&syscall_trace_lock); | 422 | mutex_lock(&syscall_trace_lock); |
422 | if (!sys_prof_refcount_enter) | 423 | if (!sys_prof_refcount_enter) |
423 | ret = register_trace_syscall_enter(prof_syscall_enter); | 424 | ret = register_trace_sys_enter(prof_syscall_enter); |
424 | if (ret) { | 425 | if (ret) { |
425 | pr_info("event trace: Could not activate" | 426 | pr_info("event trace: Could not activate" |
426 | "syscall entry trace point"); | 427 | "syscall entry trace point"); |
@@ -444,7 +445,7 @@ void unreg_prof_syscall_enter(char *name) | |||
444 | sys_prof_refcount_enter--; | 445 | sys_prof_refcount_enter--; |
445 | clear_bit(num, enabled_prof_enter_syscalls); | 446 | clear_bit(num, enabled_prof_enter_syscalls); |
446 | if (!sys_prof_refcount_enter) | 447 | if (!sys_prof_refcount_enter) |
447 | unregister_trace_syscall_enter(prof_syscall_enter); | 448 | unregister_trace_sys_enter(prof_syscall_enter); |
448 | mutex_unlock(&syscall_trace_lock); | 449 | mutex_unlock(&syscall_trace_lock); |
449 | } | 450 | } |
450 | 451 | ||
@@ -481,7 +482,7 @@ int reg_prof_syscall_exit(char *name) | |||
481 | 482 | ||
482 | mutex_lock(&syscall_trace_lock); | 483 | mutex_lock(&syscall_trace_lock); |
483 | if (!sys_prof_refcount_exit) | 484 | if (!sys_prof_refcount_exit) |
484 | ret = register_trace_syscall_exit(prof_syscall_exit); | 485 | ret = register_trace_sys_exit(prof_syscall_exit); |
485 | if (ret) { | 486 | if (ret) { |
486 | pr_info("event trace: Could not activate" | 487 | pr_info("event trace: Could not activate" |
487 | "syscall entry trace point"); | 488 | "syscall entry trace point"); |
@@ -505,7 +506,7 @@ void unreg_prof_syscall_exit(char *name) | |||
505 | sys_prof_refcount_exit--; | 506 | sys_prof_refcount_exit--; |
506 | clear_bit(num, enabled_prof_exit_syscalls); | 507 | clear_bit(num, enabled_prof_exit_syscalls); |
507 | if (!sys_prof_refcount_exit) | 508 | if (!sys_prof_refcount_exit) |
508 | unregister_trace_syscall_exit(prof_syscall_exit); | 509 | unregister_trace_sys_exit(prof_syscall_exit); |
509 | mutex_unlock(&syscall_trace_lock); | 510 | mutex_unlock(&syscall_trace_lock); |
510 | } | 511 | } |
511 | 512 | ||
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 |