diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 11 | ||||
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 5 | ||||
-rw-r--r-- | arch/i386/kernel/process.c | 17 | ||||
-rw-r--r-- | arch/x86_64/kernel/process.c | 12 | ||||
-rw-r--r-- | arch/x86_64/kernel/setup.c | 6 | ||||
-rw-r--r-- | include/asm-i386/processor.h | 2 | ||||
-rw-r--r-- | include/asm-x86_64/proto.h | 2 |
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 | ||
56 | int force_mwait __cpuinitdata; | ||
57 | |||
56 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 58 | static 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 | ||
280 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) | 285 | static 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 | ||
275 | static int __init idle_setup (char *str) | 275 | static 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 | 292 | early_param("idle", idle_setup); | |
293 | __setup("idle=", idle_setup); | ||
294 | 293 | ||
295 | void show_regs(struct pt_regs * regs) | 294 | void 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 | ||
289 | static int __init idle_setup (char *str) | 289 | static 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 | 302 | early_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 */ |
303 | void __show_regs(struct pt_regs * regs) | 305 | void __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 | ||
80 | unsigned long saved_video_mode; | 80 | unsigned long saved_video_mode; |
81 | 81 | ||
82 | int 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 | ||
609 | static void __cpuinit detect_ht(struct cpuinfo_x86 *c) | 615 | static 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); | |||
779 | extern void cpu_set_gdt(int); | 779 | extern void cpu_set_gdt(int); |
780 | extern void cpu_init(void); | 780 | extern void cpu_init(void); |
781 | 781 | ||
782 | extern 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 | ||
120 | extern void smp_local_timer_interrupt(void); | 120 | extern void smp_local_timer_interrupt(void); |
121 | 121 | ||
122 | extern int force_mwait; | ||
123 | |||
122 | long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); | 124 | long do_arch_prctl(struct task_struct *task, int code, unsigned long addr); |
123 | 125 | ||
124 | void i8254_timer_resume(void); | 126 | void i8254_timer_resume(void); |