aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/idle
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/idle
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/idle')
-rw-r--r--drivers/idle/i7300_idle.c1
-rw-r--r--drivers/idle/intel_idle.c174
2 files changed, 134 insertions, 41 deletions
diff --git a/drivers/idle/i7300_idle.c b/drivers/idle/i7300_idle.c
index 15341fc1c68b..c976285d313e 100644
--- a/drivers/idle/i7300_idle.c
+++ b/drivers/idle/i7300_idle.c
@@ -536,6 +536,7 @@ static ssize_t stats_read_ul(struct file *fp, char __user *ubuf, size_t count,
536static const struct file_operations idle_fops = { 536static const struct file_operations idle_fops = {
537 .open = stats_open_generic, 537 .open = stats_open_generic,
538 .read = stats_read_ul, 538 .read = stats_read_ul,
539 .llseek = default_llseek,
539}; 540};
540 541
541struct debugfs_file_info { 542struct debugfs_file_info {
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index c37ef64d1465..a46dddf61078 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -59,18 +59,14 @@
59#include <linux/hrtimer.h> /* ktime_get_real() */ 59#include <linux/hrtimer.h> /* ktime_get_real() */
60#include <trace/events/power.h> 60#include <trace/events/power.h>
61#include <linux/sched.h> 61#include <linux/sched.h>
62#include <linux/notifier.h>
63#include <linux/cpu.h>
64#include <asm/mwait.h>
65#include <asm/msr.h>
62 66
63#define INTEL_IDLE_VERSION "0.4" 67#define INTEL_IDLE_VERSION "0.4"
64#define PREFIX "intel_idle: " 68#define PREFIX "intel_idle: "
65 69
66#define MWAIT_SUBSTATE_MASK (0xf)
67#define MWAIT_CSTATE_MASK (0xf)
68#define MWAIT_SUBSTATE_SIZE (4)
69#define MWAIT_MAX_NUM_CSTATES 8
70#define CPUID_MWAIT_LEAF (5)
71#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
72#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
73
74static struct cpuidle_driver intel_idle_driver = { 70static struct cpuidle_driver intel_idle_driver = {
75 .name = "intel_idle", 71 .name = "intel_idle",
76 .owner = THIS_MODULE, 72 .owner = THIS_MODULE,
@@ -80,8 +76,9 @@ static int max_cstate = MWAIT_MAX_NUM_CSTATES - 1;
80 76
81static unsigned int mwait_substates; 77static unsigned int mwait_substates;
82 78
79#define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF
83/* Reliable LAPIC Timer States, bit 1 for C1 etc. */ 80/* Reliable LAPIC Timer States, bit 1 for C1 etc. */
84static unsigned int lapic_timer_reliable_states; 81static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */
85 82
86static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; 83static struct cpuidle_device __percpu *intel_idle_cpuidle_devices;
87static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state); 84static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
@@ -89,6 +86,20 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state);
89static struct cpuidle_state *cpuidle_state_table; 86static struct cpuidle_state *cpuidle_state_table;
90 87
91/* 88/*
89 * Hardware C-state auto-demotion may not always be optimal.
90 * Indicate which enable bits to clear here.
91 */
92static unsigned long long auto_demotion_disable_flags;
93
94/*
95 * Set this flag for states where the HW flushes the TLB for us
96 * and so we don't need cross-calls to keep it consistent.
97 * If this flag is set, SW flushes the TLB, so even if the
98 * HW doesn't do the flushing, this flag is safe to use.
99 */
100#define CPUIDLE_FLAG_TLB_FLUSHED 0x10000
101
102/*
92 * States are indexed by the cstate number, 103 * States are indexed by the cstate number,
93 * which is also the index into the MWAIT hint array. 104 * which is also the index into the MWAIT hint array.
94 * Thus C0 is a dummy. 105 * Thus C0 is a dummy.
@@ -96,72 +107,101 @@ static struct cpuidle_state *cpuidle_state_table;
96static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = { 107static struct cpuidle_state nehalem_cstates[MWAIT_MAX_NUM_CSTATES] = {
97 { /* MWAIT C0 */ }, 108 { /* MWAIT C0 */ },
98 { /* MWAIT C1 */ 109 { /* MWAIT C1 */
99 .name = "NHM-C1", 110 .name = "C1-NHM",
100 .desc = "MWAIT 0x00", 111 .desc = "MWAIT 0x00",
101 .driver_data = (void *) 0x00, 112 .driver_data = (void *) 0x00,
102 .flags = CPUIDLE_FLAG_TIME_VALID, 113 .flags = CPUIDLE_FLAG_TIME_VALID,
103 .exit_latency = 3, 114 .exit_latency = 3,
104 .power_usage = 1000,
105 .target_residency = 6, 115 .target_residency = 6,
106 .enter = &intel_idle }, 116 .enter = &intel_idle },
107 { /* MWAIT C2 */ 117 { /* MWAIT C2 */
108 .name = "NHM-C3", 118 .name = "C3-NHM",
109 .desc = "MWAIT 0x10", 119 .desc = "MWAIT 0x10",
110 .driver_data = (void *) 0x10, 120 .driver_data = (void *) 0x10,
111 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 121 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
112 .exit_latency = 20, 122 .exit_latency = 20,
113 .power_usage = 500,
114 .target_residency = 80, 123 .target_residency = 80,
115 .enter = &intel_idle }, 124 .enter = &intel_idle },
116 { /* MWAIT C3 */ 125 { /* MWAIT C3 */
117 .name = "NHM-C6", 126 .name = "C6-NHM",
118 .desc = "MWAIT 0x20", 127 .desc = "MWAIT 0x20",
119 .driver_data = (void *) 0x20, 128 .driver_data = (void *) 0x20,
120 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 129 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
121 .exit_latency = 200, 130 .exit_latency = 200,
122 .power_usage = 350,
123 .target_residency = 800, 131 .target_residency = 800,
124 .enter = &intel_idle }, 132 .enter = &intel_idle },
125}; 133};
126 134
135static struct cpuidle_state snb_cstates[MWAIT_MAX_NUM_CSTATES] = {
136 { /* MWAIT C0 */ },
137 { /* MWAIT C1 */
138 .name = "C1-SNB",
139 .desc = "MWAIT 0x00",
140 .driver_data = (void *) 0x00,
141 .flags = CPUIDLE_FLAG_TIME_VALID,
142 .exit_latency = 1,
143 .target_residency = 1,
144 .enter = &intel_idle },
145 { /* MWAIT C2 */
146 .name = "C3-SNB",
147 .desc = "MWAIT 0x10",
148 .driver_data = (void *) 0x10,
149 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
150 .exit_latency = 80,
151 .target_residency = 211,
152 .enter = &intel_idle },
153 { /* MWAIT C3 */
154 .name = "C6-SNB",
155 .desc = "MWAIT 0x20",
156 .driver_data = (void *) 0x20,
157 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
158 .exit_latency = 104,
159 .target_residency = 345,
160 .enter = &intel_idle },
161 { /* MWAIT C4 */
162 .name = "C7-SNB",
163 .desc = "MWAIT 0x30",
164 .driver_data = (void *) 0x30,
165 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
166 .exit_latency = 109,
167 .target_residency = 345,
168 .enter = &intel_idle },
169};
170
127static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = { 171static struct cpuidle_state atom_cstates[MWAIT_MAX_NUM_CSTATES] = {
128 { /* MWAIT C0 */ }, 172 { /* MWAIT C0 */ },
129 { /* MWAIT C1 */ 173 { /* MWAIT C1 */
130 .name = "ATM-C1", 174 .name = "C1-ATM",
131 .desc = "MWAIT 0x00", 175 .desc = "MWAIT 0x00",
132 .driver_data = (void *) 0x00, 176 .driver_data = (void *) 0x00,
133 .flags = CPUIDLE_FLAG_TIME_VALID, 177 .flags = CPUIDLE_FLAG_TIME_VALID,
134 .exit_latency = 1, 178 .exit_latency = 1,
135 .power_usage = 1000,
136 .target_residency = 4, 179 .target_residency = 4,
137 .enter = &intel_idle }, 180 .enter = &intel_idle },
138 { /* MWAIT C2 */ 181 { /* MWAIT C2 */
139 .name = "ATM-C2", 182 .name = "C2-ATM",
140 .desc = "MWAIT 0x10", 183 .desc = "MWAIT 0x10",
141 .driver_data = (void *) 0x10, 184 .driver_data = (void *) 0x10,
142 .flags = CPUIDLE_FLAG_TIME_VALID, 185 .flags = CPUIDLE_FLAG_TIME_VALID,
143 .exit_latency = 20, 186 .exit_latency = 20,
144 .power_usage = 500,
145 .target_residency = 80, 187 .target_residency = 80,
146 .enter = &intel_idle }, 188 .enter = &intel_idle },
147 { /* MWAIT C3 */ }, 189 { /* MWAIT C3 */ },
148 { /* MWAIT C4 */ 190 { /* MWAIT C4 */
149 .name = "ATM-C4", 191 .name = "C4-ATM",
150 .desc = "MWAIT 0x30", 192 .desc = "MWAIT 0x30",
151 .driver_data = (void *) 0x30, 193 .driver_data = (void *) 0x30,
152 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 194 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
153 .exit_latency = 100, 195 .exit_latency = 100,
154 .power_usage = 250,
155 .target_residency = 400, 196 .target_residency = 400,
156 .enter = &intel_idle }, 197 .enter = &intel_idle },
157 { /* MWAIT C5 */ }, 198 { /* MWAIT C5 */ },
158 { /* MWAIT C6 */ 199 { /* MWAIT C6 */
159 .name = "ATM-C6", 200 .name = "C6-ATM",
160 .desc = "MWAIT 0x52", 201 .desc = "MWAIT 0x52",
161 .driver_data = (void *) 0x52, 202 .driver_data = (void *) 0x52,
162 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, 203 .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED,
163 .exit_latency = 140, 204 .exit_latency = 140,
164 .power_usage = 150,
165 .target_residency = 560, 205 .target_residency = 560,
166 .enter = &intel_idle }, 206 .enter = &intel_idle },
167}; 207};
@@ -186,13 +226,10 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
186 local_irq_disable(); 226 local_irq_disable();
187 227
188 /* 228 /*
189 * If the state flag indicates that the TLB will be flushed or if this 229 * leave_mm() to avoid costly and often unnecessary wakeups
190 * is the deepest c-state supported, do a voluntary leave mm to avoid 230 * for flushing the user TLB's associated with the active mm.
191 * costly and mostly unnecessary wakeups for flushing the user TLB's
192 * associated with the active mm.
193 */ 231 */
194 if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED || 232 if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
195 (&dev->states[dev->state_count - 1] == state))
196 leave_mm(cpu); 233 leave_mm(cpu);
197 234
198 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 235 if (!(lapic_timer_reliable_states & (1 << (cstate))))
@@ -201,9 +238,6 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
201 kt_before = ktime_get_real(); 238 kt_before = ktime_get_real();
202 239
203 stop_critical_timings(); 240 stop_critical_timings();
204#ifndef MODULE
205 trace_power_start(POWER_CSTATE, (eax >> 4) + 1, cpu);
206#endif
207 if (!need_resched()) { 241 if (!need_resched()) {
208 242
209 __monitor((void *)&current_thread_info()->flags, 0, 0); 243 __monitor((void *)&current_thread_info()->flags, 0, 0);
@@ -225,6 +259,44 @@ static int intel_idle(struct cpuidle_device *dev, struct cpuidle_state *state)
225 return usec_delta; 259 return usec_delta;
226} 260}
227 261
262static void __setup_broadcast_timer(void *arg)
263{
264 unsigned long reason = (unsigned long)arg;
265 int cpu = smp_processor_id();
266
267 reason = reason ?
268 CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF;
269
270 clockevents_notify(reason, &cpu);
271}
272
273static int setup_broadcast_cpuhp_notify(struct notifier_block *n,
274 unsigned long action, void *hcpu)
275{
276 int hotcpu = (unsigned long)hcpu;
277
278 switch (action & 0xf) {
279 case CPU_ONLINE:
280 smp_call_function_single(hotcpu, __setup_broadcast_timer,
281 (void *)true, 1);
282 break;
283 }
284 return NOTIFY_OK;
285}
286
287static struct notifier_block setup_broadcast_notifier = {
288 .notifier_call = setup_broadcast_cpuhp_notify,
289};
290
291static void auto_demotion_disable(void *dummy)
292{
293 unsigned long long msr_bits;
294
295 rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
296 msr_bits &= ~auto_demotion_disable_flags;
297 wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits);
298}
299
228/* 300/*
229 * intel_idle_probe() 301 * intel_idle_probe()
230 */ 302 */
@@ -254,8 +326,6 @@ static int intel_idle_probe(void)
254 326
255 pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); 327 pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates);
256 328
257 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
258 lapic_timer_reliable_states = 0xFFFFFFFF;
259 329
260 if (boot_cpu_data.x86 != 6) /* family 6 */ 330 if (boot_cpu_data.x86 != 6) /* family 6 */
261 return -ENODEV; 331 return -ENODEV;
@@ -267,22 +337,26 @@ static int intel_idle_probe(void)
267 case 0x1F: /* Core i7 and i5 Processor - Nehalem */ 337 case 0x1F: /* Core i7 and i5 Processor - Nehalem */
268 case 0x2E: /* Nehalem-EX Xeon */ 338 case 0x2E: /* Nehalem-EX Xeon */
269 case 0x2F: /* Westmere-EX Xeon */ 339 case 0x2F: /* Westmere-EX Xeon */
270 lapic_timer_reliable_states = (1 << 1); /* C1 */
271
272 case 0x25: /* Westmere */ 340 case 0x25: /* Westmere */
273 case 0x2C: /* Westmere */ 341 case 0x2C: /* Westmere */
274 cpuidle_state_table = nehalem_cstates; 342 cpuidle_state_table = nehalem_cstates;
343 auto_demotion_disable_flags =
344 (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE);
275 break; 345 break;
276 346
277 case 0x1C: /* 28 - Atom Processor */ 347 case 0x1C: /* 28 - Atom Processor */
348 cpuidle_state_table = atom_cstates;
349 break;
350
278 case 0x26: /* 38 - Lincroft Atom Processor */ 351 case 0x26: /* 38 - Lincroft Atom Processor */
279 lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
280 cpuidle_state_table = atom_cstates; 352 cpuidle_state_table = atom_cstates;
353 auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE;
354 break;
355
356 case 0x2A: /* SNB */
357 case 0x2D: /* SNB Xeon */
358 cpuidle_state_table = snb_cstates;
281 break; 359 break;
282#ifdef FUTURE_USE
283 case 0x17: /* 23 - Core 2 Duo */
284 lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */
285#endif
286 360
287 default: 361 default:
288 pr_debug(PREFIX "does not run on family %d model %d\n", 362 pr_debug(PREFIX "does not run on family %d model %d\n",
@@ -290,6 +364,13 @@ static int intel_idle_probe(void)
290 return -ENODEV; 364 return -ENODEV;
291 } 365 }
292 366
367 if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */
368 lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE;
369 else {
370 smp_call_function(__setup_broadcast_timer, (void *)true, 1);
371 register_cpu_notifier(&setup_broadcast_notifier);
372 }
373
293 pr_debug(PREFIX "v" INTEL_IDLE_VERSION 374 pr_debug(PREFIX "v" INTEL_IDLE_VERSION
294 " model 0x%X\n", boot_cpu_data.x86_model); 375 " model 0x%X\n", boot_cpu_data.x86_model);
295 376
@@ -377,6 +458,8 @@ static int intel_idle_cpuidle_devices_init(void)
377 return -EIO; 458 return -EIO;
378 } 459 }
379 } 460 }
461 if (auto_demotion_disable_flags)
462 smp_call_function(auto_demotion_disable, NULL, 1);
380 463
381 return 0; 464 return 0;
382} 465}
@@ -386,6 +469,10 @@ static int __init intel_idle_init(void)
386{ 469{
387 int retval; 470 int retval;
388 471
472 /* Do not load intel_idle at all for now if idle= is passed */
473 if (boot_option_idle_override != IDLE_NO_OVERRIDE)
474 return -ENODEV;
475
389 retval = intel_idle_probe(); 476 retval = intel_idle_probe();
390 if (retval) 477 if (retval)
391 return retval; 478 return retval;
@@ -411,6 +498,11 @@ static void __exit intel_idle_exit(void)
411 intel_idle_cpuidle_devices_uninit(); 498 intel_idle_cpuidle_devices_uninit();
412 cpuidle_unregister_driver(&intel_idle_driver); 499 cpuidle_unregister_driver(&intel_idle_driver);
413 500
501 if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) {
502 smp_call_function(__setup_broadcast_timer, (void *)false, 1);
503 unregister_cpu_notifier(&setup_broadcast_notifier);
504 }
505
414 return; 506 return;
415} 507}
416 508