1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2007 Steven Rostedt <srostedt@redhat.com>
8 #include <linux/module.h>
9 #include <linux/kallsyms.h>
10 #include <linux/uaccess.h>
11 #include <linux/ftrace.h>
12 #include <trace/events/sched.h>
16 #define RECORD_CMDLINE 1
19 static int sched_cmdline_ref
;
20 static int sched_tgid_ref
;
21 static DEFINE_MUTEX(sched_register_mutex
);
24 probe_sched_switch(void *ignore
, bool preempt
,
25 struct task_struct
*prev
, struct task_struct
*next
)
29 flags
= (RECORD_TGID
* !!sched_tgid_ref
) +
30 (RECORD_CMDLINE
* !!sched_cmdline_ref
);
34 tracing_record_taskinfo_sched_switch(prev
, next
, flags
);
38 probe_sched_wakeup(void *ignore
, struct task_struct
*wakee
)
42 flags
= (RECORD_TGID
* !!sched_tgid_ref
) +
43 (RECORD_CMDLINE
* !!sched_cmdline_ref
);
47 tracing_record_taskinfo(current
, flags
);
50 static int tracing_sched_register(void)
54 ret
= register_trace_sched_wakeup(probe_sched_wakeup
, NULL
);
56 pr_info("wakeup trace: Couldn't activate tracepoint"
57 " probe to kernel_sched_wakeup\n");
61 ret
= register_trace_sched_wakeup_new(probe_sched_wakeup
, NULL
);
63 pr_info("wakeup trace: Couldn't activate tracepoint"
64 " probe to kernel_sched_wakeup_new\n");
68 ret
= register_trace_sched_switch(probe_sched_switch
, NULL
);
70 pr_info("sched trace: Couldn't activate tracepoint"
71 " probe to kernel_sched_switch\n");
72 goto fail_deprobe_wake_new
;
76 fail_deprobe_wake_new
:
77 unregister_trace_sched_wakeup_new(probe_sched_wakeup
, NULL
);
79 unregister_trace_sched_wakeup(probe_sched_wakeup
, NULL
);
83 static void tracing_sched_unregister(void)
85 unregister_trace_sched_switch(probe_sched_switch
, NULL
);
86 unregister_trace_sched_wakeup_new(probe_sched_wakeup
, NULL
);
87 unregister_trace_sched_wakeup(probe_sched_wakeup
, NULL
);
90 static void tracing_start_sched_switch(int ops
)
92 bool sched_register
= (!sched_cmdline_ref
&& !sched_tgid_ref
);
93 mutex_lock(&sched_register_mutex
);
105 if (sched_register
&& (sched_cmdline_ref
|| sched_tgid_ref
))
106 tracing_sched_register();
107 mutex_unlock(&sched_register_mutex
);
110 static void tracing_stop_sched_switch(int ops
)
112 mutex_lock(&sched_register_mutex
);
124 if (!sched_cmdline_ref
&& !sched_tgid_ref
)
125 tracing_sched_unregister();
126 mutex_unlock(&sched_register_mutex
);
129 void tracing_start_cmdline_record(void)
131 tracing_start_sched_switch(RECORD_CMDLINE
);
134 void tracing_stop_cmdline_record(void)
136 tracing_stop_sched_switch(RECORD_CMDLINE
);
139 void tracing_start_tgid_record(void)
141 tracing_start_sched_switch(RECORD_TGID
);
144 void tracing_stop_tgid_record(void)
146 tracing_stop_sched_switch(RECORD_TGID
);