aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/process.c7
-rw-r--r--arch/x86/kernel/process_32.c2
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--drivers/cpufreq/cpufreq.c1
-rw-r--r--drivers/cpuidle/cpuidle.c1
-rw-r--r--drivers/idle/intel_idle.c1
-rw-r--r--include/trace/events/power.h98
-rw-r--r--kernel/trace/Kconfig15
-rw-r--r--kernel/trace/power-traces.c3
9 files changed, 119 insertions, 11 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 96ed1aac543a..c852041bfc3d 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -373,6 +373,7 @@ void default_idle(void)
373{ 373{
374 if (hlt_use_halt()) { 374 if (hlt_use_halt()) {
375 trace_power_start(POWER_CSTATE, 1, smp_processor_id()); 375 trace_power_start(POWER_CSTATE, 1, smp_processor_id());
376 trace_cpu_idle(1, smp_processor_id());
376 current_thread_info()->status &= ~TS_POLLING; 377 current_thread_info()->status &= ~TS_POLLING;
377 /* 378 /*
378 * TS_POLLING-cleared state must be visible before we 379 * TS_POLLING-cleared state must be visible before we
@@ -443,6 +444,7 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
443void mwait_idle_with_hints(unsigned long ax, unsigned long cx) 444void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
444{ 445{
445 trace_power_start(POWER_CSTATE, (ax>>4)+1, smp_processor_id()); 446 trace_power_start(POWER_CSTATE, (ax>>4)+1, smp_processor_id());
447 trace_cpu_idle((ax>>4)+1, smp_processor_id());
446 if (!need_resched()) { 448 if (!need_resched()) {
447 if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) 449 if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
448 clflush((void *)&current_thread_info()->flags); 450 clflush((void *)&current_thread_info()->flags);
@@ -459,6 +461,7 @@ static void mwait_idle(void)
459{ 461{
460 if (!need_resched()) { 462 if (!need_resched()) {
461 trace_power_start(POWER_CSTATE, 1, smp_processor_id()); 463 trace_power_start(POWER_CSTATE, 1, smp_processor_id());
464 trace_cpu_idle(1, smp_processor_id());
462 if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR)) 465 if (cpu_has(&current_cpu_data, X86_FEATURE_CLFLUSH_MONITOR))
463 clflush((void *)&current_thread_info()->flags); 466 clflush((void *)&current_thread_info()->flags);
464 467
@@ -480,10 +483,12 @@ static void mwait_idle(void)
480static void poll_idle(void) 483static void poll_idle(void)
481{ 484{
482 trace_power_start(POWER_CSTATE, 0, smp_processor_id()); 485 trace_power_start(POWER_CSTATE, 0, smp_processor_id());
486 trace_cpu_idle(0, smp_processor_id());
483 local_irq_enable(); 487 local_irq_enable();
484 while (!need_resched()) 488 while (!need_resched())
485 cpu_relax(); 489 cpu_relax();
486 trace_power_end(0); 490 trace_power_end(smp_processor_id());
491 trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
487} 492}
488 493
489/* 494/*
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 96586c3cbbbf..4b9befa0e347 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -113,8 +113,8 @@ void cpu_idle(void)
113 stop_critical_timings(); 113 stop_critical_timings();
114 pm_idle(); 114 pm_idle();
115 start_critical_timings(); 115 start_critical_timings();
116
117 trace_power_end(smp_processor_id()); 116 trace_power_end(smp_processor_id());
117 trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
118 } 118 }
119 tick_nohz_restart_sched_tick(); 119 tick_nohz_restart_sched_tick();
120 preempt_enable_no_resched(); 120 preempt_enable_no_resched();
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index b3d7a3a04f38..4c818a738396 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -142,6 +142,8 @@ void cpu_idle(void)
142 start_critical_timings(); 142 start_critical_timings();
143 143
144 trace_power_end(smp_processor_id()); 144 trace_power_end(smp_processor_id());
145 trace_cpu_idle(PWR_EVENT_EXIT,
146 smp_processor_id());
145 147
146 /* In many cases the interrupt that ended idle 148 /* In many cases the interrupt that ended idle
147 has already called exit_idle. But some idle 149 has already called exit_idle. But some idle
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index c63a43823744..1109f6848a43 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -355,6 +355,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
355 dprintk("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new, 355 dprintk("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
356 (unsigned long)freqs->cpu); 356 (unsigned long)freqs->cpu);
357 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu); 357 trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
358 trace_cpu_frequency(freqs->new, freqs->cpu);
358 srcu_notifier_call_chain(&cpufreq_transition_notifier_list, 359 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
359 CPUFREQ_POSTCHANGE, freqs); 360 CPUFREQ_POSTCHANGE, freqs);
360 if (likely(policy) && likely(policy->cpu == freqs->cpu)) 361 if (likely(policy) && likely(policy->cpu == freqs->cpu))
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index a50710843378..08d5f05378d9 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -107,6 +107,7 @@ static void cpuidle_idle_call(void)
107 if (cpuidle_curr_governor->reflect) 107 if (cpuidle_curr_governor->reflect)
108 cpuidle_curr_governor->reflect(dev); 108 cpuidle_curr_governor->reflect(dev);
109 trace_power_end(smp_processor_id()); 109 trace_power_end(smp_processor_id());
110 trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
110} 111}
111 112
112/** 113/**
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 15783d5501a8..56ac09d6c930 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -221,6 +221,7 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
221 221
222 stop_critical_timings(); 222 stop_critical_timings();
223 trace_power_start(POWER_CSTATE, (eax >> 4) + 1, cpu); 223 trace_power_start(POWER_CSTATE, (eax >> 4) + 1, cpu);
224 trace_cpu_idle((eax >> 4) + 1, cpu);
224 if (!need_resched()) { 225 if (!need_resched()) {
225 226
226 __monitor((void *)&current_thread_info()->flags, 0, 0); 227 __monitor((void *)&current_thread_info()->flags, 0, 0);
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index 286784d69b8f..1bcc2a8c00e2 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -7,16 +7,67 @@
7#include <linux/ktime.h> 7#include <linux/ktime.h>
8#include <linux/tracepoint.h> 8#include <linux/tracepoint.h>
9 9
10#ifndef _TRACE_POWER_ENUM_ 10DECLARE_EVENT_CLASS(cpu,
11#define _TRACE_POWER_ENUM_ 11
12enum { 12 TP_PROTO(unsigned int state, unsigned int cpu_id),
13 POWER_NONE = 0, 13
14 POWER_CSTATE = 1, /* C-State */ 14 TP_ARGS(state, cpu_id),
15 POWER_PSTATE = 2, /* Fequency change or DVFS */ 15
16 POWER_SSTATE = 3, /* Suspend */ 16 TP_STRUCT__entry(
17}; 17 __field( u32, state )
18 __field( u32, cpu_id )
19 ),
20
21 TP_fast_assign(
22 __entry->state = state;
23 __entry->cpu_id = cpu_id;
24 ),
25
26 TP_printk("state=%lu cpu_id=%lu", (unsigned long)__entry->state,
27 (unsigned long)__entry->cpu_id)
28);
29
30DEFINE_EVENT(cpu, cpu_idle,
31
32 TP_PROTO(unsigned int state, unsigned int cpu_id),
33
34 TP_ARGS(state, cpu_id)
35);
36
37/* This file can get included multiple times, TRACE_HEADER_MULTI_READ at top */
38#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING
39#define _PWR_EVENT_AVOID_DOUBLE_DEFINING
40
41#define PWR_EVENT_EXIT -1
18#endif 42#endif
19 43
44DEFINE_EVENT(cpu, cpu_frequency,
45
46 TP_PROTO(unsigned int frequency, unsigned int cpu_id),
47
48 TP_ARGS(frequency, cpu_id)
49);
50
51TRACE_EVENT(machine_suspend,
52
53 TP_PROTO(unsigned int state),
54
55 TP_ARGS(state),
56
57 TP_STRUCT__entry(
58 __field( u32, state )
59 ),
60
61 TP_fast_assign(
62 __entry->state = state;
63 ),
64
65 TP_printk("state=%lu", (unsigned long)__entry->state)
66);
67
68/* This code will be removed after deprecation time exceeded (2.6.41) */
69#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED
70
20/* 71/*
21 * The power events are used for cpuidle & suspend (power_start, power_end) 72 * The power events are used for cpuidle & suspend (power_start, power_end)
22 * and for cpufreq (power_frequency) 73 * and for cpufreq (power_frequency)
@@ -75,6 +126,36 @@ TRACE_EVENT(power_end,
75 126
76); 127);
77 128
129/* Deprecated dummy functions must be protected against multi-declartion */
130#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
131#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
132
133enum {
134 POWER_NONE = 0,
135 POWER_CSTATE = 1,
136 POWER_PSTATE = 2,
137};
138#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */
139
140#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */
141
142#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
143#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
144enum {
145 POWER_NONE = 0,
146 POWER_CSTATE = 1,
147 POWER_PSTATE = 2,
148};
149
150/* These dummy declaration have to be ripped out when the deprecated
151 events get removed */
152static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {};
153static inline void trace_power_end(u64 cpuid) {};
154static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {};
155#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */
156
157#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */
158
78/* 159/*
79 * The clock events are used for clock enable/disable and for 160 * The clock events are used for clock enable/disable and for
80 * clock rate change 161 * clock rate change
@@ -153,7 +234,6 @@ DEFINE_EVENT(power_domain, power_domain_target,
153 234
154 TP_ARGS(name, state, cpu_id) 235 TP_ARGS(name, state, cpu_id)
155); 236);
156
157#endif /* _TRACE_POWER_H */ 237#endif /* _TRACE_POWER_H */
158 238
159/* This part must be outside protection */ 239/* This part must be outside protection */
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index ea37e2ff4164..14674dce77a6 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -69,6 +69,21 @@ config EVENT_TRACING
69 select CONTEXT_SWITCH_TRACER 69 select CONTEXT_SWITCH_TRACER
70 bool 70 bool
71 71
72config EVENT_POWER_TRACING_DEPRECATED
73 depends on EVENT_TRACING
74 bool "Deprecated power event trace API, to be removed"
75 default y
76 help
77 Provides old power event types:
78 C-state/idle accounting events:
79 power:power_start
80 power:power_end
81 and old cpufreq accounting event:
82 power:power_frequency
83 This is for userspace compatibility
84 and will vanish after 5 kernel iterations,
85 namely 2.6.41.
86
72config CONTEXT_SWITCH_TRACER 87config CONTEXT_SWITCH_TRACER
73 bool 88 bool
74 89
diff --git a/kernel/trace/power-traces.c b/kernel/trace/power-traces.c
index 0e0497d9fade..f55fcf61b223 100644
--- a/kernel/trace/power-traces.c
+++ b/kernel/trace/power-traces.c
@@ -13,5 +13,8 @@
13#define CREATE_TRACE_POINTS 13#define CREATE_TRACE_POINTS
14#include <trace/events/power.h> 14#include <trace/events/power.h>
15 15
16#ifdef EVENT_POWER_TRACING_DEPRECATED
16EXPORT_TRACEPOINT_SYMBOL_GPL(power_start); 17EXPORT_TRACEPOINT_SYMBOL_GPL(power_start);
18#endif
19EXPORT_TRACEPOINT_SYMBOL_GPL(cpu_idle);
17 20