aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c2
-rw-r--r--arch/x86/kernel/process.c3
-rw-r--r--include/trace/power.h25
-rw-r--r--kernel/trace/trace_power.c173
4 files changed, 119 insertions, 84 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 7ed925edf4d2..c5d737cdb365 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -70,6 +70,8 @@ struct acpi_cpufreq_data {
70 70
71static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data); 71static DEFINE_PER_CPU(struct acpi_cpufreq_data *, drv_data);
72 72
73DEFINE_TRACE(power_mark);
74
73/* acpi_perf_data is a pointer to percpu data. */ 75/* acpi_perf_data is a pointer to percpu data. */
74static struct acpi_processor_performance *acpi_perf_data; 76static struct acpi_processor_performance *acpi_perf_data;
75 77
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 026819ffcb0c..e0d0fd7ab514 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -19,6 +19,9 @@ EXPORT_SYMBOL(idle_nomwait);
19 19
20struct kmem_cache *task_xstate_cachep; 20struct kmem_cache *task_xstate_cachep;
21 21
22DEFINE_TRACE(power_start);
23DEFINE_TRACE(power_end);
24
22int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) 25int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
23{ 26{
24 *dst = *src; 27 *dst = *src;
diff --git a/include/trace/power.h b/include/trace/power.h
index c7cefbcdaea4..2c733e58e89c 100644
--- a/include/trace/power.h
+++ b/include/trace/power.h
@@ -2,6 +2,7 @@
2#define _TRACE_POWER_H 2#define _TRACE_POWER_H
3 3
4#include <linux/ktime.h> 4#include <linux/ktime.h>
5#include <linux/tracepoint.h>
5 6
6enum { 7enum {
7 POWER_NONE = 0, 8 POWER_NONE = 0,
@@ -18,18 +19,16 @@ struct power_trace {
18#endif 19#endif
19}; 20};
20 21
21#ifdef CONFIG_POWER_TRACER 22DECLARE_TRACE(power_start,
22extern void trace_power_start(struct power_trace *it, unsigned int type, 23 TPPROTO(struct power_trace *it, unsigned int type, unsigned int state),
23 unsigned int state); 24 TPARGS(it, type, state));
24extern void trace_power_mark(struct power_trace *it, unsigned int type, 25
25 unsigned int state); 26DECLARE_TRACE(power_mark,
26extern void trace_power_end(struct power_trace *it); 27 TPPROTO(struct power_trace *it, unsigned int type, unsigned int state),
27#else 28 TPARGS(it, type, state));
28static inline void trace_power_start(struct power_trace *it, unsigned int type, 29
29 unsigned int state) { } 30DECLARE_TRACE(power_end,
30static inline void trace_power_mark(struct power_trace *it, unsigned int type, 31 TPPROTO(struct power_trace *it),
31 unsigned int state) { } 32 TPARGS(it));
32static inline void trace_power_end(struct power_trace *it) { }
33#endif
34 33
35#endif /* _TRACE_POWER_H */ 34#endif /* _TRACE_POWER_H */
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
index b1d0d087d3a6..91ce672fb037 100644
--- a/kernel/trace/trace_power.c
+++ b/kernel/trace/trace_power.c
@@ -21,15 +21,116 @@
21static struct trace_array *power_trace; 21static struct trace_array *power_trace;
22static int __read_mostly trace_power_enabled; 22static int __read_mostly trace_power_enabled;
23 23
24static void probe_power_start(struct power_trace *it, unsigned int type,
25 unsigned int level)
26{
27 if (!trace_power_enabled)
28 return;
29
30 memset(it, 0, sizeof(struct power_trace));
31 it->state = level;
32 it->type = type;
33 it->stamp = ktime_get();
34}
35
36
37static void probe_power_end(struct power_trace *it)
38{
39 struct ring_buffer_event *event;
40 struct trace_power *entry;
41 struct trace_array_cpu *data;
42 struct trace_array *tr = power_trace;
43
44 if (!trace_power_enabled)
45 return;
46
47 preempt_disable();
48 it->end = ktime_get();
49 data = tr->data[smp_processor_id()];
50
51 event = trace_buffer_lock_reserve(tr, TRACE_POWER,
52 sizeof(*entry), 0, 0);
53 if (!event)
54 goto out;
55 entry = ring_buffer_event_data(event);
56 entry->state_data = *it;
57 trace_buffer_unlock_commit(tr, event, 0, 0);
58 out:
59 preempt_enable();
60}
61
62static void probe_power_mark(struct power_trace *it, unsigned int type,
63 unsigned int level)
64{
65 struct ring_buffer_event *event;
66 struct trace_power *entry;
67 struct trace_array_cpu *data;
68 struct trace_array *tr = power_trace;
69
70 if (!trace_power_enabled)
71 return;
72
73 memset(it, 0, sizeof(struct power_trace));
74 it->state = level;
75 it->type = type;
76 it->stamp = ktime_get();
77 preempt_disable();
78 it->end = it->stamp;
79 data = tr->data[smp_processor_id()];
80
81 event = trace_buffer_lock_reserve(tr, TRACE_POWER,
82 sizeof(*entry), 0, 0);
83 if (!event)
84 goto out;
85 entry = ring_buffer_event_data(event);
86 entry->state_data = *it;
87 trace_buffer_unlock_commit(tr, event, 0, 0);
88 out:
89 preempt_enable();
90}
91
92static int tracing_power_register(void)
93{
94 int ret;
95
96 ret = register_trace_power_start(probe_power_start);
97 if (ret) {
98 pr_info("power trace: Couldn't activate tracepoint"
99 " probe to trace_power_start\n");
100 return ret;
101 }
102 ret = register_trace_power_end(probe_power_end);
103 if (ret) {
104 pr_info("power trace: Couldn't activate tracepoint"
105 " probe to trace_power_end\n");
106 goto fail_start;
107 }
108 ret = register_trace_power_mark(probe_power_mark);
109 if (ret) {
110 pr_info("power trace: Couldn't activate tracepoint"
111 " probe to trace_power_mark\n");
112 goto fail_end;
113 }
114 return ret;
115fail_end:
116 unregister_trace_power_end(probe_power_end);
117fail_start:
118 unregister_trace_power_start(probe_power_start);
119 return ret;
120}
24 121
25static void start_power_trace(struct trace_array *tr) 122static void start_power_trace(struct trace_array *tr)
26{ 123{
27 trace_power_enabled = 1; 124 trace_power_enabled = 1;
125 tracing_power_register();
28} 126}
29 127
30static void stop_power_trace(struct trace_array *tr) 128static void stop_power_trace(struct trace_array *tr)
31{ 129{
32 trace_power_enabled = 0; 130 trace_power_enabled = 0;
131 unregister_trace_power_start(probe_power_start);
132 unregister_trace_power_end(probe_power_end);
133 unregister_trace_power_mark(probe_power_mark);
33} 134}
34 135
35 136
@@ -39,6 +140,7 @@ static int power_trace_init(struct trace_array *tr)
39 power_trace = tr; 140 power_trace = tr;
40 141
41 trace_power_enabled = 1; 142 trace_power_enabled = 1;
143 tracing_power_register();
42 144
43 for_each_cpu(cpu, cpu_possible_mask) 145 for_each_cpu(cpu, cpu_possible_mask)
44 tracing_reset(tr, cpu); 146 tracing_reset(tr, cpu);
@@ -95,74 +197,3 @@ static int init_power_trace(void)
95 return register_tracer(&power_tracer); 197 return register_tracer(&power_tracer);
96} 198}
97device_initcall(init_power_trace); 199device_initcall(init_power_trace);
98
99void trace_power_start(struct power_trace *it, unsigned int type,
100 unsigned int level)
101{
102 if (!trace_power_enabled)
103 return;
104
105 memset(it, 0, sizeof(struct power_trace));
106 it->state = level;
107 it->type = type;
108 it->stamp = ktime_get();
109}
110EXPORT_SYMBOL_GPL(trace_power_start);
111
112
113void trace_power_end(struct power_trace *it)
114{
115 struct ring_buffer_event *event;
116 struct trace_power *entry;
117 struct trace_array_cpu *data;
118 struct trace_array *tr = power_trace;
119
120 if (!trace_power_enabled)
121 return;
122
123 preempt_disable();
124 it->end = ktime_get();
125 data = tr->data[smp_processor_id()];
126
127 event = trace_buffer_lock_reserve(tr, TRACE_POWER,
128 sizeof(*entry), 0, 0);
129 if (!event)
130 goto out;
131 entry = ring_buffer_event_data(event);
132 entry->state_data = *it;
133 trace_buffer_unlock_commit(tr, event, 0, 0);
134 out:
135 preempt_enable();
136}
137EXPORT_SYMBOL_GPL(trace_power_end);
138
139void trace_power_mark(struct power_trace *it, unsigned int type,
140 unsigned int level)
141{
142 struct ring_buffer_event *event;
143 struct trace_power *entry;
144 struct trace_array_cpu *data;
145 struct trace_array *tr = power_trace;
146
147 if (!trace_power_enabled)
148 return;
149
150 memset(it, 0, sizeof(struct power_trace));
151 it->state = level;
152 it->type = type;
153 it->stamp = ktime_get();
154 preempt_disable();
155 it->end = it->stamp;
156 data = tr->data[smp_processor_id()];
157
158 event = trace_buffer_lock_reserve(tr, TRACE_POWER,
159 sizeof(*entry), 0, 0);
160 if (!event)
161 goto out;
162 entry = ring_buffer_event_data(event);
163 entry->state_data = *it;
164 trace_buffer_unlock_commit(tr, event, 0, 0);
165 out:
166 preempt_enable();
167}
168EXPORT_SYMBOL_GPL(trace_power_mark);