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 c622772744d8..c27af49a4ede 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
| 8 | #include <linux/pm.h> | 8 | #include <linux/pm.h> |
| 9 | #include <linux/clockchips.h> | 9 | #include <linux/clockchips.h> |
| 10 | #include <linux/ftrace.h> | ||
| 10 | #include <asm/system.h> | 11 | #include <asm/system.h> |
| 11 | 12 | ||
| 12 | unsigned long idle_halt; | 13 | unsigned long idle_halt; |
| @@ -100,6 +101,9 @@ static inline int hlt_use_halt(void) | |||
| 100 | void default_idle(void) | 101 | void default_idle(void) |
| 101 | { | 102 | { |
| 102 | if (hlt_use_halt()) { | 103 | if (hlt_use_halt()) { |
| 104 | struct power_trace it; | ||
| 105 | |||
| 106 | trace_power_start(&it, POWER_CSTATE, 1); | ||
| 103 | current_thread_info()->status &= ~TS_POLLING; | 107 | current_thread_info()->status &= ~TS_POLLING; |
| 104 | /* | 108 | /* |
| 105 | * TS_POLLING-cleared state must be visible before we | 109 | * TS_POLLING-cleared state must be visible before we |
| @@ -112,6 +116,7 @@ void default_idle(void) | |||
| 112 | else | 116 | else |
| 113 | local_irq_enable(); | 117 | local_irq_enable(); |
| 114 | current_thread_info()->status |= TS_POLLING; | 118 | current_thread_info()->status |= TS_POLLING; |
| 119 | trace_power_end(&it); | ||
| 115 | } else { | 120 | } else { |
| 116 | local_irq_enable(); | 121 | local_irq_enable(); |
| 117 | /* loop is done by the caller */ | 122 | /* loop is done by the caller */ |
| @@ -154,24 +159,31 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); | |||
| 154 | */ | 159 | */ |
| 155 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) | 160 | void mwait_idle_with_hints(unsigned long ax, unsigned long cx) |
| 156 | { | 161 | { |
| 162 | struct power_trace it; | ||
| 163 | |||
| 164 | trace_power_start(&it, POWER_CSTATE, (ax>>4)+1); | ||
| 157 | if (!need_resched()) { | 165 | if (!need_resched()) { |
| 158 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 166 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
| 159 | smp_mb(); | 167 | smp_mb(); |
| 160 | if (!need_resched()) | 168 | if (!need_resched()) |
| 161 | __mwait(ax, cx); | 169 | __mwait(ax, cx); |
| 162 | } | 170 | } |
| 171 | trace_power_end(&it); | ||
| 163 | } | 172 | } |
| 164 | 173 | ||
| 165 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ | 174 | /* Default MONITOR/MWAIT with no hints, used for default C1 state */ |
| 166 | static void mwait_idle(void) | 175 | static void mwait_idle(void) |
| 167 | { | 176 | { |
| 177 | struct power_trace it; | ||
| 168 | if (!need_resched()) { | 178 | if (!need_resched()) { |
| 179 | trace_power_start(&it, POWER_CSTATE, 1); | ||
| 169 | __monitor((void *)¤t_thread_info()->flags, 0, 0); | 180 | __monitor((void *)¤t_thread_info()->flags, 0, 0); |
| 170 | smp_mb(); | 181 | smp_mb(); |
| 171 | if (!need_resched()) | 182 | if (!need_resched()) |
| 172 | __sti_mwait(0, 0); | 183 | __sti_mwait(0, 0); |
| 173 | else | 184 | else |
| 174 | local_irq_enable(); | 185 | local_irq_enable(); |
| 186 | trace_power_end(&it); | ||
| 175 | } else | 187 | } else |
| 176 | local_irq_enable(); | 188 | local_irq_enable(); |
| 177 | } | 189 | } |
| @@ -183,9 +195,13 @@ static void mwait_idle(void) | |||
| 183 | */ | 195 | */ |
| 184 | static void poll_idle(void) | 196 | static void poll_idle(void) |
| 185 | { | 197 | { |
| 198 | struct power_trace it; | ||
| 199 | |||
| 200 | trace_power_start(&it, POWER_CSTATE, 0); | ||
| 186 | local_irq_enable(); | 201 | local_irq_enable(); |
| 187 | while (!need_resched()) | 202 | while (!need_resched()) |
| 188 | cpu_relax(); | 203 | cpu_relax(); |
| 204 | trace_power_end(&it); | ||
| 189 | } | 205 | } |
| 190 | 206 | ||
| 191 | /* | 207 | /* |
