135e8e302SSteven Rostedt /*
235e8e302SSteven Rostedt  * trace context switch
335e8e302SSteven Rostedt  *
435e8e302SSteven Rostedt  * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
535e8e302SSteven Rostedt  *
635e8e302SSteven Rostedt  */
735e8e302SSteven Rostedt #include <linux/module.h>
835e8e302SSteven Rostedt #include <linux/kallsyms.h>
935e8e302SSteven Rostedt #include <linux/uaccess.h>
1035e8e302SSteven Rostedt #include <linux/ftrace.h>
11ad8d75ffSSteven Rostedt #include <trace/events/sched.h>
1235e8e302SSteven Rostedt 
1335e8e302SSteven Rostedt #include "trace.h"
1435e8e302SSteven Rostedt 
15efade6e7SFrederic Weisbecker static int			sched_ref;
16efade6e7SFrederic Weisbecker static DEFINE_MUTEX(sched_register_mutex);
1782e04af4SFrederic Weisbecker 
18e309b41dSIngo Molnar static void
1938516ab5SSteven Rostedt probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next)
2035e8e302SSteven Rostedt {
21dcef788eSZhaolei 	if (unlikely(!sched_ref))
22b07c3f19SMathieu Desnoyers 		return;
23b07c3f19SMathieu Desnoyers 
2441bc8144SSteven Rostedt 	tracing_record_cmdline(prev);
2541bc8144SSteven Rostedt 	tracing_record_cmdline(next);
2635e8e302SSteven Rostedt }
2735e8e302SSteven Rostedt 
285b82a1b0SMathieu Desnoyers static void
29fbd705a0SPeter Zijlstra probe_sched_wakeup(void *ignore, struct task_struct *wakee)
305b82a1b0SMathieu Desnoyers {
31dcef788eSZhaolei 	if (unlikely(!sched_ref))
32dcef788eSZhaolei 		return;
33dcef788eSZhaolei 
34dcef788eSZhaolei 	tracing_record_cmdline(current);
3557422797SIngo Molnar }
3657422797SIngo Molnar 
375b82a1b0SMathieu Desnoyers static int tracing_sched_register(void)
385b82a1b0SMathieu Desnoyers {
395b82a1b0SMathieu Desnoyers 	int ret;
405b82a1b0SMathieu Desnoyers 
4138516ab5SSteven Rostedt 	ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL);
425b82a1b0SMathieu Desnoyers 	if (ret) {
43b07c3f19SMathieu Desnoyers 		pr_info("wakeup trace: Couldn't activate tracepoint"
445b82a1b0SMathieu Desnoyers 			" probe to kernel_sched_wakeup\n");
455b82a1b0SMathieu Desnoyers 		return ret;
465b82a1b0SMathieu Desnoyers 	}
475b82a1b0SMathieu Desnoyers 
4838516ab5SSteven Rostedt 	ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
495b82a1b0SMathieu Desnoyers 	if (ret) {
50b07c3f19SMathieu Desnoyers 		pr_info("wakeup trace: Couldn't activate tracepoint"
515b82a1b0SMathieu Desnoyers 			" probe to kernel_sched_wakeup_new\n");
525b82a1b0SMathieu Desnoyers 		goto fail_deprobe;
535b82a1b0SMathieu Desnoyers 	}
545b82a1b0SMathieu Desnoyers 
5538516ab5SSteven Rostedt 	ret = register_trace_sched_switch(probe_sched_switch, NULL);
565b82a1b0SMathieu Desnoyers 	if (ret) {
57b07c3f19SMathieu Desnoyers 		pr_info("sched trace: Couldn't activate tracepoint"
5873d8b8bcSWenji Huang 			" probe to kernel_sched_switch\n");
595b82a1b0SMathieu Desnoyers 		goto fail_deprobe_wake_new;
605b82a1b0SMathieu Desnoyers 	}
615b82a1b0SMathieu Desnoyers 
625b82a1b0SMathieu Desnoyers 	return ret;
635b82a1b0SMathieu Desnoyers fail_deprobe_wake_new:
6438516ab5SSteven Rostedt 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
655b82a1b0SMathieu Desnoyers fail_deprobe:
6638516ab5SSteven Rostedt 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
675b82a1b0SMathieu Desnoyers 	return ret;
685b82a1b0SMathieu Desnoyers }
695b82a1b0SMathieu Desnoyers 
705b82a1b0SMathieu Desnoyers static void tracing_sched_unregister(void)
715b82a1b0SMathieu Desnoyers {
7238516ab5SSteven Rostedt 	unregister_trace_sched_switch(probe_sched_switch, NULL);
7338516ab5SSteven Rostedt 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
7438516ab5SSteven Rostedt 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
755b82a1b0SMathieu Desnoyers }
765b82a1b0SMathieu Desnoyers 
77f2252935SIngo Molnar static void tracing_start_sched_switch(void)
785b82a1b0SMathieu Desnoyers {
79efade6e7SFrederic Weisbecker 	mutex_lock(&sched_register_mutex);
80e168e051SSteven Rostedt 	if (!(sched_ref++))
815b82a1b0SMathieu Desnoyers 		tracing_sched_register();
82efade6e7SFrederic Weisbecker 	mutex_unlock(&sched_register_mutex);
835b82a1b0SMathieu Desnoyers }
845b82a1b0SMathieu Desnoyers 
85f2252935SIngo Molnar static void tracing_stop_sched_switch(void)
865b82a1b0SMathieu Desnoyers {
87efade6e7SFrederic Weisbecker 	mutex_lock(&sched_register_mutex);
88e168e051SSteven Rostedt 	if (!(--sched_ref))
895b82a1b0SMathieu Desnoyers 		tracing_sched_unregister();
90efade6e7SFrederic Weisbecker 	mutex_unlock(&sched_register_mutex);
915b82a1b0SMathieu Desnoyers }
925b82a1b0SMathieu Desnoyers 
9341bc8144SSteven Rostedt void tracing_start_cmdline_record(void)
9441bc8144SSteven Rostedt {
9541bc8144SSteven Rostedt 	tracing_start_sched_switch();
9641bc8144SSteven Rostedt }
9741bc8144SSteven Rostedt 
9841bc8144SSteven Rostedt void tracing_stop_cmdline_record(void)
9941bc8144SSteven Rostedt {
10041bc8144SSteven Rostedt 	tracing_stop_sched_switch();
10141bc8144SSteven Rostedt }
102