aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/Kconfig4
-rw-r--r--kernel/trace/trace_syscalls.c17
-rw-r--r--kernel/tracepoint.c20
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
41config HAVE_HW_BRANCH_TRACER 41config HAVE_HW_BRANCH_TRACER
42 bool 42 bool
43 43
44config HAVE_FTRACE_SYSCALLS 44config HAVE_SYSCALL_TRACEPOINTS
45 bool 45 bool
46 46
47config TRACER_MAX_TRACE 47config TRACER_MAX_TRACE
@@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS
211 211
212config FTRACE_SYSCALLS 212config 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 */
263static void disable_tracepoint(struct tracepoint *elem) 268static 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
581static DEFINE_MUTEX(regfunc_mutex); 589/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
582static int sys_tracepoint_refcount; 590static int sys_tracepoint_refcount;
583 591
584void syscall_regfunc(void) 592void 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(&regfunc_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(&regfunc_mutex);
599} 605}
600 606
601void syscall_unregfunc(void) 607void 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(&regfunc_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(&regfunc_mutex);
616} 620}
617#endif 621#endif