tracing/core: Make the stack entry helpers global
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / trace / trace_sched_switch.c
CommitLineData
35e8e302
SR
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/fs.h>
9#include <linux/debugfs.h>
10#include <linux/kallsyms.h>
11#include <linux/uaccess.h>
35e8e302 12#include <linux/ftrace.h>
ad8d75ff 13#include <trace/events/sched.h>
35e8e302
SR
14
15#include "trace.h"
16
17static struct trace_array *ctx_trace;
18static int __read_mostly tracer_enabled;
efade6e7
FW
19static int sched_ref;
20static DEFINE_MUTEX(sched_register_mutex);
5fec6ddc 21static int sched_stopped;
35e8e302 22
e309b41d 23static void
b07c3f19 24probe_sched_switch(struct rq *__rq, struct task_struct *prev,
5b82a1b0 25 struct task_struct *next)
35e8e302 26{
35e8e302
SR
27 struct trace_array_cpu *data;
28 unsigned long flags;
35e8e302 29 int cpu;
38697053 30 int pc;
35e8e302 31
dcef788e 32 if (unlikely(!sched_ref))
b07c3f19
MD
33 return;
34
41bc8144
SR
35 tracing_record_cmdline(prev);
36 tracing_record_cmdline(next);
37
dcef788e 38 if (!tracer_enabled || sched_stopped)
35e8e302
SR
39 return;
40
38697053 41 pc = preempt_count();
18cef379 42 local_irq_save(flags);
35e8e302 43 cpu = raw_smp_processor_id();
b07c3f19 44 data = ctx_trace->data[cpu];
35e8e302 45
3ea2e6d7 46 if (likely(!atomic_read(&data->disabled)))
7be42151 47 tracing_sched_switch_trace(ctx_trace, prev, next, flags, pc);
35e8e302 48
18cef379 49 local_irq_restore(flags);
35e8e302
SR
50}
51
4e655519 52static void
468a15bb 53probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee, int success)
57422797 54{
57422797
IM
55 struct trace_array_cpu *data;
56 unsigned long flags;
38697053 57 int cpu, pc;
57422797 58
dcef788e 59 if (unlikely(!sched_ref))
57422797
IM
60 return;
61
b07c3f19 62 tracing_record_cmdline(current);
d9af56fb 63
dcef788e 64 if (!tracer_enabled || sched_stopped)
8bcae09b
Z
65 return;
66
dcef788e 67 pc = preempt_count();
57422797
IM
68 local_irq_save(flags);
69 cpu = raw_smp_processor_id();
b07c3f19 70 data = ctx_trace->data[cpu];
57422797 71
3ea2e6d7 72 if (likely(!atomic_read(&data->disabled)))
7be42151 73 tracing_sched_wakeup_trace(ctx_trace, wakee, current,
38697053 74 flags, pc);
57422797 75
57422797
IM
76 local_irq_restore(flags);
77}
78
5b82a1b0
MD
79static int tracing_sched_register(void)
80{
81 int ret;
82
b07c3f19 83 ret = register_trace_sched_wakeup(probe_sched_wakeup);
5b82a1b0 84 if (ret) {
b07c3f19 85 pr_info("wakeup trace: Couldn't activate tracepoint"
5b82a1b0
MD
86 " probe to kernel_sched_wakeup\n");
87 return ret;
88 }
89
b07c3f19 90 ret = register_trace_sched_wakeup_new(probe_sched_wakeup);
5b82a1b0 91 if (ret) {
b07c3f19 92 pr_info("wakeup trace: Couldn't activate tracepoint"
5b82a1b0
MD
93 " probe to kernel_sched_wakeup_new\n");
94 goto fail_deprobe;
95 }
96
b07c3f19 97 ret = register_trace_sched_switch(probe_sched_switch);
5b82a1b0 98 if (ret) {
b07c3f19 99 pr_info("sched trace: Couldn't activate tracepoint"
73d8b8bc 100 " probe to kernel_sched_switch\n");
5b82a1b0
MD
101 goto fail_deprobe_wake_new;
102 }
103
104 return ret;
105fail_deprobe_wake_new:
b07c3f19 106 unregister_trace_sched_wakeup_new(probe_sched_wakeup);
5b82a1b0 107fail_deprobe:
b07c3f19 108 unregister_trace_sched_wakeup(probe_sched_wakeup);
5b82a1b0
MD
109 return ret;
110}
111
112static void tracing_sched_unregister(void)
113{
b07c3f19
MD
114 unregister_trace_sched_switch(probe_sched_switch);
115 unregister_trace_sched_wakeup_new(probe_sched_wakeup);
116 unregister_trace_sched_wakeup(probe_sched_wakeup);
5b82a1b0
MD
117}
118
f2252935 119static void tracing_start_sched_switch(void)
5b82a1b0 120{
efade6e7 121 mutex_lock(&sched_register_mutex);
e168e051 122 if (!(sched_ref++))
5b82a1b0 123 tracing_sched_register();
efade6e7 124 mutex_unlock(&sched_register_mutex);
5b82a1b0
MD
125}
126
f2252935 127static void tracing_stop_sched_switch(void)
5b82a1b0 128{
efade6e7 129 mutex_lock(&sched_register_mutex);
e168e051 130 if (!(--sched_ref))
5b82a1b0 131 tracing_sched_unregister();
efade6e7 132 mutex_unlock(&sched_register_mutex);
5b82a1b0
MD
133}
134
41bc8144
SR
135void tracing_start_cmdline_record(void)
136{
137 tracing_start_sched_switch();
138}
139
140void tracing_stop_cmdline_record(void)
141{
142 tracing_stop_sched_switch();
143}
144
75f5c47d 145/**
e168e051
SR
146 * tracing_start_sched_switch_record - start tracing context switches
147 *
148 * Turns on context switch tracing for a tracer.
149 */
150void tracing_start_sched_switch_record(void)
151{
152 if (unlikely(!ctx_trace)) {
153 WARN_ON(1);
154 return;
155 }
156
157 tracing_start_sched_switch();
158
159 mutex_lock(&sched_register_mutex);
160 tracer_enabled++;
161 mutex_unlock(&sched_register_mutex);
162}
163
164/**
165 * tracing_stop_sched_switch_record - start tracing context switches
166 *
167 * Turns off context switch tracing for a tracer.
168 */
169void tracing_stop_sched_switch_record(void)
170{
171 mutex_lock(&sched_register_mutex);
172 tracer_enabled--;
173 WARN_ON(tracer_enabled < 0);
174 mutex_unlock(&sched_register_mutex);
175
176 tracing_stop_sched_switch();
177}
178
179/**
180 * tracing_sched_switch_assign_trace - assign a trace array for ctx switch
75f5c47d
SR
181 * @tr: trace array pointer to assign
182 *
183 * Some tracers might want to record the context switches in their
184 * trace. This function lets those tracers assign the trace array
185 * to use.
186 */
e168e051 187void tracing_sched_switch_assign_trace(struct trace_array *tr)
75f5c47d
SR
188{
189 ctx_trace = tr;
190}
191
e309b41d 192static void stop_sched_trace(struct trace_array *tr)
35e8e302 193{
e168e051 194 tracing_stop_sched_switch_record();
35e8e302
SR
195}
196
1c80025a 197static int sched_switch_trace_init(struct trace_array *tr)
35e8e302
SR
198{
199 ctx_trace = tr;
5fec6ddc 200 tracing_reset_online_cpus(tr);
b6f11df2 201 tracing_start_sched_switch_record();
1c80025a 202 return 0;
35e8e302
SR
203}
204
e309b41d 205static void sched_switch_trace_reset(struct trace_array *tr)
35e8e302 206{
c76f0694 207 if (sched_ref)
35e8e302
SR
208 stop_sched_trace(tr);
209}
210
9036990d
SR
211static void sched_switch_trace_start(struct trace_array *tr)
212{
5fec6ddc 213 sched_stopped = 0;
9036990d
SR
214}
215
216static void sched_switch_trace_stop(struct trace_array *tr)
217{
5fec6ddc 218 sched_stopped = 1;
9036990d
SR
219}
220
75f5c47d 221static struct tracer sched_switch_trace __read_mostly =
35e8e302
SR
222{
223 .name = "sched_switch",
224 .init = sched_switch_trace_init,
225 .reset = sched_switch_trace_reset,
9036990d
SR
226 .start = sched_switch_trace_start,
227 .stop = sched_switch_trace_stop,
6eaaa5d5 228 .wait_pipe = poll_wait_pipe,
60a11774
SR
229#ifdef CONFIG_FTRACE_SELFTEST
230 .selftest = trace_selftest_startup_sched_switch,
231#endif
35e8e302
SR
232};
233
234__init static int init_sched_switch_trace(void)
235{
236 return register_tracer(&sched_switch_trace);
237}
238device_initcall(init_sched_switch_trace);
c71dd42d 239