diff options
Diffstat (limited to 'arch/x86/kernel/process.c')
-rw-r--r-- | arch/x86/kernel/process.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index b8f3e9dbabd7..e68bb9e30864 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/pm.h> | 9 | #include <linux/pm.h> |
10 | #include <linux/clockchips.h> | 10 | #include <linux/clockchips.h> |
11 | #include <linux/ftrace.h> | ||
11 | #include <asm/system.h> | 12 | #include <asm/system.h> |
12 | #include <asm/apic.h> | 13 | #include <asm/apic.h> |
13 | 14 | ||
@@ -102,6 +103,9 @@ static inline int hlt_use_halt(void) | |||
102 | void default_idle(void) | 103 | void default_idle(void) |
103 | { | 104 | { |
104 | if (hlt_use_halt()) { | 105 | if (hlt_use_halt()) { |
106 | struct power_trace it; | ||
107 | |||
108 | trace_power_start(&it, POWER_CSTATE, 1); | ||
105 | current_thread_info()->status &= ~TS_POLLING; | 109 | current_thread_info()->status &= ~TS_POLLING; |
106 | /* | 110 | /* |
107 | * TS_POLLING-cleared state must be visible before we | 111 | * TS_POLLING-cleared state must be visible before we |
@@ -114,6 +118,7 @@ void default_idle(void) | |||
114 | else | 118 | else |
115 | local_irq_enable(); | 119 | local_irq_enable(); |
116 | current_thread_info()->status |= TS_POLLING; | 120 | current_thread_info()->status |= TS_POLLING; |
121 | trace_power_end(&it); | ||
117 | } else { | 122 | } else { |
118 | local_irq_enable(); | 123 | local_irq_enable(); |
119 | /* loop is done by the caller */ | 124 | /* loop is done by the caller */ |
@@ -171,24 +176,31 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
171 | */ | 176 | */ |
172 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | 177 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) |
173 | { | 178 | { |
179 | struct power_trace it; | ||
180 | |||
181 | trace_power_start(&it, POWER_CSTATE, (ax>>4)+1); | ||
174 | if (!need_resched()) { | 182 | if (!need_resched()) { |
175 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 183 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
176 | smp_mb(); | 184 | smp_mb(); |
177 | if (!need_resched()) | 185 | if (!need_resched()) |
178 | __mwait(ax, cx); | 186 | __mwait(ax, cx); |
179 | } | 187 | } |
188 | trace_power_end(&it); | ||
180 | } | 189 | } |
181 | 190 | ||
182 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ | 191 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ |
183 | static void mwait_idle(void) | 192 | static void mwait_idle(void) |
184 | { | 193 | { |
194 | struct power_trace it; | ||
185 | if (!need_resched()) { | 195 | if (!need_resched()) { |
196 | trace_power_start(&it, POWER_CSTATE, 1); | ||
186 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 197 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
187 | smp_mb(); | 198 | smp_mb(); |
188 | if (!need_resched()) | 199 | if (!need_resched()) |
189 | __sti_mwait(0, 0); | 200 | __sti_mwait(0, 0); |
190 | else | 201 | else |
191 | local_irq_enable(); | 202 | local_irq_enable(); |
203 | trace_power_end(&it); | ||
192 | } else | 204 | } else |
193 | local_irq_enable(); | 205 | local_irq_enable(); |
194 | } | 206 | } |
@@ -200,9 +212,13 @@ static void mwait_idle(void) | |||
200 | */ | 212 | */ |
201 | static void poll_idle(void) | 213 | static void poll_idle(void) |
202 | { | 214 | { |
215 | struct power_trace it; | ||
216 | |||
217 | trace_power_start(&it, POWER_CSTATE, 0); | ||
203 | local_irq_enable(); | 218 | local_irq_enable(); |
204 | while (!need_resched()) | 219 | while (!need_resched()) |
205 | cpu_relax(); | 220 | cpu_relax(); |
221 | trace_power_end(&it); | ||
206 | } | 222 | } |
207 | 223 | ||
208 | /* | 224 | /* |