aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt11
-rw-r--r--arch/i386/kernel/cpu/amd.c5
-rw-r--r--arch/i386/kernel/process.c17
-rw-r--r--arch/x86_64/kernel/process.c12
-rw-r--r--arch/x86_64/kernel/setup.c6
-rw-r--r--include/asm-i386/processor.h2
-rw-r--r--include/asm-x86_64/proto.h2
7 files changed, 39 insertions, 16 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 4287696f18dd..94ce0d20253d 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -695,8 +695,15 @@ and is between 256 and 4096 characters. It is defined in the file
695 idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed 695 idebus= [HW] (E)IDE subsystem - VLB/PCI bus speed
696 See Documentation/ide.txt. 696 See Documentation/ide.txt.
697 697
698 idle= [HW] 698 idle= [X86]
699 Format: idle=poll or idle=halt 699 Format: idle=poll or idle=mwait
700 Poll forces a polling idle loop that can slightly improves the performance
701 of waking up a idle CPU, but will use a lot of power and make the system
702 run hot. Not recommended.
703 idle=mwait. On systems which support MONITOR/MWAIT but the kernel chose
704 to not use it because it doesn't save as much power as a normal idle
705 loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same
706 as idle=poll.
700 707
701 ignore_loglevel [KNL] 708 ignore_loglevel [KNL]
702 Ignore loglevel setting - this will print /all/ 709 Ignore loglevel setting - this will print /all/
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 2d47db482972..197cda62caa3 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -53,6 +53,8 @@ static __cpuinit int amd_apic_timer_broken(void)
53 return 0; 53 return 0;
54} 54}
55 55
56int force_mwait __cpuinitdata;
57
56static void __cpuinit init_amd(struct cpuinfo_x86 *c) 58static void __cpuinit init_amd(struct cpuinfo_x86 *c)
57{ 59{
58 u32 l, h; 60 u32 l, h;
@@ -275,6 +277,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
275 277
276 if (amd_apic_timer_broken()) 278 if (amd_apic_timer_broken())
277 set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); 279 set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability);
280
281 if (c->x86 == 0x10 && !force_mwait)
282 clear_bit(X86_FEATURE_MWAIT, c->x86_capability);
278} 283}
279 284
280static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) 285static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 393a67d5d943..7e8e129b3d7d 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -272,25 +272,24 @@ void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
272 } 272 }
273} 273}
274 274
275static int __init idle_setup (char *str) 275static int __init idle_setup(char *str)
276{ 276{
277 if (!strncmp(str, "poll", 4)) { 277 if (!strcmp(str, "poll")) {
278 printk("using polling idle threads.\n"); 278 printk("using polling idle threads.\n");
279 pm_idle = poll_idle; 279 pm_idle = poll_idle;
280#ifdef CONFIG_X86_SMP 280#ifdef CONFIG_X86_SMP
281 if (smp_num_siblings > 1) 281 if (smp_num_siblings > 1)
282 printk("WARNING: polling idle and HT enabled, performance may degrade.\n"); 282 printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
283#endif 283#endif
284 } else if (!strncmp(str, "halt", 4)) { 284 } else if (!strcmp(str, "mwait"))
285 printk("using halt in idle threads.\n"); 285 force_mwait = 1;
286 pm_idle = default_idle; 286 else
287 } 287 return -1;
288 288
289 boot_option_idle_override = 1; 289 boot_option_idle_override = 1;
290 return 1; 290 return 0;
291} 291}
292 292early_param("idle", idle_setup);
293__setup("idle=", idle_setup);
294 293
295void show_regs(struct pt_regs * regs) 294void show_regs(struct pt_regs * regs)
296{ 295{
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index d8d5ccc245c8..4f21765078b7 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -288,16 +288,18 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
288 288
289static int __init idle_setup (char *str) 289static int __init idle_setup (char *str)
290{ 290{
291 if (!strncmp(str, "poll", 4)) { 291 if (!strcmp(str, "poll")) {
292 printk("using polling idle threads.\n"); 292 printk("using polling idle threads.\n");
293 pm_idle = poll_idle; 293 pm_idle = poll_idle;
294 } 294 } else if (!strcmp(str, "mwait"))
295 force_mwait = 1;
296 else
297 return -1;
295 298
296 boot_option_idle_override = 1; 299 boot_option_idle_override = 1;
297 return 1; 300 return 0;
298} 301}
299 302early_param("idle", idle_setup);
300__setup("idle=", idle_setup);
301 303
302/* Prints also some state that isn't saved in the pt_regs */ 304/* Prints also some state that isn't saved in the pt_regs */
303void __show_regs(struct pt_regs * regs) 305void __show_regs(struct pt_regs * regs)
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 0a1d539149df..db30b5bcef61 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -79,6 +79,8 @@ int bootloader_type;
79 79
80unsigned long saved_video_mode; 80unsigned long saved_video_mode;
81 81
82int force_mwait __cpuinitdata;
83
82/* 84/*
83 * Early DMI memory 85 * Early DMI memory
84 */ 86 */
@@ -604,6 +606,10 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
604 606
605 /* RDTSC can be speculated around */ 607 /* RDTSC can be speculated around */
606 clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); 608 clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
609
610 /* Family 10 doesn't support C states in MWAIT so don't use it */
611 if (c->x86 == 0x10 && !force_mwait)
612 clear_bit(X86_FEATURE_MWAIT, &c->x86_capability);
607} 613}
608 614
609static void __cpuinit detect_ht(struct cpuinfo_x86 *c) 615static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h
index 9d895cc2f312..882d3f8fbbac 100644
--- a/include/asm-i386/processor.h
+++ b/include/asm-i386/processor.h
@@ -779,4 +779,6 @@ extern int sysenter_setup(void);
779extern void cpu_set_gdt(int); 779extern void cpu_set_gdt(int);
780extern void cpu_init(void); 780extern void cpu_init(void);
781 781
782extern int force_mwait;
783
782#endif /* __ASM_I386_PROCESSOR_H */ 784#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h
index 3f8f285138d2..98063bcb3b33 100644
--- a/include/asm-x86_64/proto.h
+++ b/include/asm-x86_64/proto.h
@@ -119,6 +119,8 @@ extern int gsi_irq_sharing(int gsi);
119 119
120extern void smp_local_timer_interrupt(void); 120extern void smp_local_timer_interrupt(void);
121 121
122extern int force_mwait;
123
122long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); 124long do_arch_prctl(struct task_struct *task, int code, unsigned long addr);
123 125
124void i8254_timer_resume(void); 126void i8254_timer_resume(void);