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
19c73464b1SPeter Zijlstra probe_sched_switch(void *ignore, bool preempt,
20c73464b1SPeter Zijlstra 		   struct task_struct *prev, struct task_struct *next)
2135e8e302SSteven Rostedt {
22dcef788eSZhaolei 	if (unlikely(!sched_ref))
23b07c3f19SMathieu Desnoyers 		return;
24b07c3f19SMathieu Desnoyers 
2541bc8144SSteven Rostedt 	tracing_record_cmdline(prev);
2641bc8144SSteven Rostedt 	tracing_record_cmdline(next);
2735e8e302SSteven Rostedt }
2835e8e302SSteven Rostedt 
295b82a1b0SMathieu Desnoyers static void
30fbd705a0SPeter Zijlstra probe_sched_wakeup(void *ignore, struct task_struct *wakee)
315b82a1b0SMathieu Desnoyers {
32dcef788eSZhaolei 	if (unlikely(!sched_ref))
33dcef788eSZhaolei 		return;
34dcef788eSZhaolei 
35dcef788eSZhaolei 	tracing_record_cmdline(current);
3657422797SIngo Molnar }
3757422797SIngo Molnar 
385b82a1b0SMathieu Desnoyers static int tracing_sched_register(void)
395b82a1b0SMathieu Desnoyers {
405b82a1b0SMathieu Desnoyers 	int ret;
415b82a1b0SMathieu Desnoyers 
4238516ab5SSteven Rostedt 	ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL);
435b82a1b0SMathieu Desnoyers 	if (ret) {
44b07c3f19SMathieu Desnoyers 		pr_info("wakeup trace: Couldn't activate tracepoint"
455b82a1b0SMathieu Desnoyers 			" probe to kernel_sched_wakeup\n");
465b82a1b0SMathieu Desnoyers 		return ret;
475b82a1b0SMathieu Desnoyers 	}
485b82a1b0SMathieu Desnoyers 
4938516ab5SSteven Rostedt 	ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
505b82a1b0SMathieu Desnoyers 	if (ret) {
51b07c3f19SMathieu Desnoyers 		pr_info("wakeup trace: Couldn't activate tracepoint"
525b82a1b0SMathieu Desnoyers 			" probe to kernel_sched_wakeup_new\n");
535b82a1b0SMathieu Desnoyers 		goto fail_deprobe;
545b82a1b0SMathieu Desnoyers 	}
555b82a1b0SMathieu Desnoyers 
5638516ab5SSteven Rostedt 	ret = register_trace_sched_switch(probe_sched_switch, NULL);
575b82a1b0SMathieu Desnoyers 	if (ret) {
58b07c3f19SMathieu Desnoyers 		pr_info("sched trace: Couldn't activate tracepoint"
5973d8b8bcSWenji Huang 			" probe to kernel_sched_switch\n");
605b82a1b0SMathieu Desnoyers 		goto fail_deprobe_wake_new;
615b82a1b0SMathieu Desnoyers 	}
625b82a1b0SMathieu Desnoyers 
635b82a1b0SMathieu Desnoyers 	return ret;
645b82a1b0SMathieu Desnoyers fail_deprobe_wake_new:
6538516ab5SSteven Rostedt 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
665b82a1b0SMathieu Desnoyers fail_deprobe:
6738516ab5SSteven Rostedt 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
685b82a1b0SMathieu Desnoyers 	return ret;
695b82a1b0SMathieu Desnoyers }
705b82a1b0SMathieu Desnoyers 
715b82a1b0SMathieu Desnoyers static void tracing_sched_unregister(void)
725b82a1b0SMathieu Desnoyers {
7338516ab5SSteven Rostedt 	unregister_trace_sched_switch(probe_sched_switch, NULL);
7438516ab5SSteven Rostedt 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
7538516ab5SSteven Rostedt 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
765b82a1b0SMathieu Desnoyers }
775b82a1b0SMathieu Desnoyers 
78f2252935SIngo Molnar static void tracing_start_sched_switch(void)
795b82a1b0SMathieu Desnoyers {
80efade6e7SFrederic Weisbecker 	mutex_lock(&sched_register_mutex);
81e168e051SSteven Rostedt 	if (!(sched_ref++))
825b82a1b0SMathieu Desnoyers 		tracing_sched_register();
83efade6e7SFrederic Weisbecker 	mutex_unlock(&sched_register_mutex);
845b82a1b0SMathieu Desnoyers }
855b82a1b0SMathieu Desnoyers 
86f2252935SIngo Molnar static void tracing_stop_sched_switch(void)
875b82a1b0SMathieu Desnoyers {
88efade6e7SFrederic Weisbecker 	mutex_lock(&sched_register_mutex);
89e168e051SSteven Rostedt 	if (!(--sched_ref))
905b82a1b0SMathieu Desnoyers 		tracing_sched_unregister();
91efade6e7SFrederic Weisbecker 	mutex_unlock(&sched_register_mutex);
925b82a1b0SMathieu Desnoyers }
935b82a1b0SMathieu Desnoyers 
9441bc8144SSteven Rostedt void tracing_start_cmdline_record(void)
9541bc8144SSteven Rostedt {
9641bc8144SSteven Rostedt 	tracing_start_sched_switch();
9741bc8144SSteven Rostedt }
9841bc8144SSteven Rostedt 
9941bc8144SSteven Rostedt void tracing_stop_cmdline_record(void)
10041bc8144SSteven Rostedt {
10141bc8144SSteven Rostedt 	tracing_stop_sched_switch();
10241bc8144SSteven Rostedt }
103