xref: /linux/kernel/trace/trace_sched_switch.c (revision 93df8a1ed6231727c5db94a80b1a6bd5ee67cec3)
1 /*
2  * trace context switch
3  *
4  * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
5  *
6  */
7 #include <linux/module.h>
8 #include <linux/kallsyms.h>
9 #include <linux/uaccess.h>
10 #include <linux/ftrace.h>
11 #include <trace/events/sched.h>
12 
13 #include "trace.h"
14 
15 static int			sched_ref;
16 static DEFINE_MUTEX(sched_register_mutex);
17 
18 static void
19 probe_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next)
20 {
21 	if (unlikely(!sched_ref))
22 		return;
23 
24 	tracing_record_cmdline(prev);
25 	tracing_record_cmdline(next);
26 }
27 
28 static void
29 probe_sched_wakeup(void *ignore, struct task_struct *wakee, int success)
30 {
31 	if (unlikely(!sched_ref))
32 		return;
33 
34 	tracing_record_cmdline(current);
35 }
36 
37 static int tracing_sched_register(void)
38 {
39 	int ret;
40 
41 	ret = register_trace_sched_wakeup(probe_sched_wakeup, NULL);
42 	if (ret) {
43 		pr_info("wakeup trace: Couldn't activate tracepoint"
44 			" probe to kernel_sched_wakeup\n");
45 		return ret;
46 	}
47 
48 	ret = register_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
49 	if (ret) {
50 		pr_info("wakeup trace: Couldn't activate tracepoint"
51 			" probe to kernel_sched_wakeup_new\n");
52 		goto fail_deprobe;
53 	}
54 
55 	ret = register_trace_sched_switch(probe_sched_switch, NULL);
56 	if (ret) {
57 		pr_info("sched trace: Couldn't activate tracepoint"
58 			" probe to kernel_sched_switch\n");
59 		goto fail_deprobe_wake_new;
60 	}
61 
62 	return ret;
63 fail_deprobe_wake_new:
64 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
65 fail_deprobe:
66 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
67 	return ret;
68 }
69 
70 static void tracing_sched_unregister(void)
71 {
72 	unregister_trace_sched_switch(probe_sched_switch, NULL);
73 	unregister_trace_sched_wakeup_new(probe_sched_wakeup, NULL);
74 	unregister_trace_sched_wakeup(probe_sched_wakeup, NULL);
75 }
76 
77 static void tracing_start_sched_switch(void)
78 {
79 	mutex_lock(&sched_register_mutex);
80 	if (!(sched_ref++))
81 		tracing_sched_register();
82 	mutex_unlock(&sched_register_mutex);
83 }
84 
85 static void tracing_stop_sched_switch(void)
86 {
87 	mutex_lock(&sched_register_mutex);
88 	if (!(--sched_ref))
89 		tracing_sched_unregister();
90 	mutex_unlock(&sched_register_mutex);
91 }
92 
93 void tracing_start_cmdline_record(void)
94 {
95 	tracing_start_sched_switch();
96 }
97 
98 void tracing_stop_cmdline_record(void)
99 {
100 	tracing_stop_sched_switch();
101 }
102