A bit of Spring-cleaning in the x86 idle code,
so that we don't need to maintain this baggage
through upcoming cpuidle changes.
cheers,
-Len
From: Len Brown <[email protected]>
no functional change
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 5 -----
arch/x86/kernel/process.c | 3 +--
2 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b5c83f1..8776232 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -147,11 +147,6 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
extern const struct seq_operations cpuinfo_op;
-static inline int hlt_works(int cpu)
-{
- return 1;
-}
-
#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
extern void cpu_detect(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4966c7e..cd461c3 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -414,8 +414,7 @@ void stop_this_cpu(void *dummy)
disable_local_APIC();
for (;;) {
- if (hlt_works(smp_processor_id()))
- halt();
+ halt();
}
}
--
1.7.4.1.343.ga91df
From: Len Brown <[email protected]>
The X86_32-only disable_hlt/enable_hlt mechanism was used
by the 32-bit floppy driver. Its effect was to replace
the use of the HLT instruction inside default_idle() with
cpu_relax().
Unlcear why this workaround was ever needed, it was commented:
floppy.c said:
"disable hlt during certain critical i/o operations"
x86/kernel/process.c said:
"This halt magic was a workaround for ancient floppy DMA
wreckage. It should be safe to remove."
So remove it, as it allows us to simplify the x86 idle code.
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/system.h | 7 -------
arch/x86/kernel/process.c | 24 ------------------------
drivers/block/floppy.c | 35 -----------------------------------
3 files changed, 0 insertions(+), 66 deletions(-)
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 33ecc3e..013dd42 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -93,10 +93,6 @@ do { \
"memory"); \
} while (0)
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
#else
#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
@@ -337,9 +333,6 @@ static inline void clflush(volatile void *__p)
#define nop() asm volatile ("nop")
-void disable_hlt(void);
-void enable_hlt(void);
-
void cpu_idle_wait(void);
extern unsigned long arch_align_stack(unsigned long sp);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index cd461c3..8688ade 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -342,34 +342,10 @@ EXPORT_SYMBOL(boot_option_idle_override);
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
-#ifdef CONFIG_X86_32
-/*
- * This halt magic was a workaround for ancient floppy DMA
- * wreckage. It should be safe to remove.
- */
-static int hlt_counter;
-void disable_hlt(void)
-{
- hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
- hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
-static inline int hlt_use_halt(void)
-{
- return (!hlt_counter);
-}
-#else
static inline int hlt_use_halt(void)
{
return 1;
}
-#endif
/*
* We use this if we don't have any better
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 77fc76f..9a4e006 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1032,36 +1032,6 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
return 0;
}
-static DEFINE_SPINLOCK(floppy_hlt_lock);
-static int hlt_disabled;
-static void floppy_disable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (!hlt_disabled) {
- hlt_disabled = 1;
-#ifdef HAVE_DISABLE_HLT
- disable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
-static void floppy_enable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (hlt_disabled) {
- hlt_disabled = 0;
-#ifdef HAVE_DISABLE_HLT
- enable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
static void setup_DMA(void)
{
unsigned long f;
@@ -1106,7 +1076,6 @@ static void setup_DMA(void)
fd_enable_dma();
release_dma_lock(f);
#endif
- floppy_disable_hlt();
}
static void show_floppy(void);
@@ -1708,7 +1677,6 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
fd_disable_dma();
release_dma_lock(f);
- floppy_enable_hlt();
do_floppy = NULL;
if (fdc >= N_FDC || FDCS->address == -1) {
/* we don't even know which FDC is the culprit */
@@ -1857,8 +1825,6 @@ static void floppy_shutdown(unsigned long data)
show_floppy();
cancel_activity();
- floppy_enable_hlt();
-
flags = claim_dma_lock();
fd_disable_dma();
release_dma_lock(flags);
@@ -4503,7 +4469,6 @@ static void floppy_release_irq_and_dma(void)
#if N_FDC > 1
set_dor(1, ~8, 0);
#endif
- floppy_enable_hlt();
if (floppy_track_buffer && max_buffer_sectors) {
tmpsize = max_buffer_sectors * 1024;
--
1.7.4.1.343.ga91df
From: Len Brown <[email protected]>
The X86_32-only "no-hlt" option was the functional equivalent of
"idle=poll" for the idle loop.
It would also set the X86_32-only "hlt_bug" line in the /proc/cpuinfo,
and cause halt to be skipped in stop_this_cpu().
Signed-off-by: Len Brown <[email protected]>
---
Documentation/kernel-parameters.txt | 4 ----
arch/x86/kernel/cpu/bugs.c | 8 --------
2 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f4a04c0..e6b4843 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1666,10 +1666,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
wfi(ARM) instruction doesn't work correctly and not to
use it. This is also useful when using JTAG debugger.
- no-hlt [BUGS=X86-32] Tells the kernel that the hlt
- instruction doesn't work correctly and not to
- use it.
-
no_file_caps Tells the kernel not to honor file capabilities. The
only way then for a file to be executed with privilege
is to be setuid root or executed by root.
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c39576c..4c91631 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -17,14 +17,6 @@
#include <asm/paravirt.h>
#include <asm/alternative.h>
-static int __init no_halt(char *s)
-{
- boot_cpu_data.hlt_works_ok = 0;
- return 1;
-}
-
-__setup("no-hlt", no_halt);
-
static int __init no_387(char *s)
{
boot_cpu_data.hard_math = 0;
--
1.7.4.1.343.ga91df
From: Len Brown <[email protected]>
hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 5 -----
arch/x86/kernel/cpu/bugs.c | 5 +----
arch/x86/kernel/cpu/proc.c | 2 --
arch/x86/kernel/process.c | 2 +-
arch/x86/kernel/setup.c | 4 ++--
arch/x86/xen/setup.c | 3 ---
6 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 45636ce..b5c83f1 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -67,7 +67,6 @@ struct cpuinfo_x86 {
char wp_works_ok; /* It doesn't on 386's */
/* Problems on some 486Dx4's and old 386's: */
- char hlt_works_ok;
char hard_math;
char rfu;
char fdiv_bug;
@@ -150,11 +149,7 @@ extern const struct seq_operations cpuinfo_op;
static inline int hlt_works(int cpu)
{
-#ifdef CONFIG_X86_32
- return cpu_data(cpu).hlt_works_ok;
-#else
return 1;
-#endif
}
#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 4c91631..b5e2910 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -82,10 +82,7 @@ static void __init check_hlt(void)
return;
printk(KERN_INFO "Checking 'hlt' instruction... ");
- if (!boot_cpu_data.hlt_works_ok) {
- printk("disabled\n");
- return;
- }
+
halt();
halt();
halt();
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 62ac8cb..203feb7 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -33,7 +33,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
seq_printf(m,
"fdiv_bug\t: %s\n"
- "hlt_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
"coma_bug\t: %s\n"
"fpu\t\t: %s\n"
@@ -41,7 +40,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
"cpuid level\t: %d\n"
"wp\t\t: %s\n",
c->fdiv_bug ? "yes" : "no",
- c->hlt_works_ok ? "no" : "yes",
c->f00f_bug ? "yes" : "no",
c->coma_bug ? "yes" : "no",
c->hard_math ? "yes" : "no",
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ff45541..4966c7e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(enable_hlt);
static inline int hlt_use_halt(void)
{
- return (!hlt_counter && boot_cpu_data.hlt_works_ok);
+ return (!hlt_counter);
}
#else
static inline int hlt_use_halt(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3cfe26..fab5631 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -175,9 +175,9 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 0, 0, -1};
/* common cpu data for all cpus */
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 0, 0, -1};
EXPORT_SYMBOL(boot_cpu_data);
static void set_mca_bus(int x)
{
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index a8a66a5..97d2fbd 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -351,9 +351,6 @@ void __init xen_arch_setup(void)
COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
/* Set up idle, making sure it calls safe_halt() pvop */
-#ifdef CONFIG_X86_32
- boot_cpu_data.hlt_works_ok = 1;
-#endif
pm_idle = default_idle;
boot_option_idle_override = IDLE_HALT;
--
1.7.4.1.343.ga91df
From: Len Brown <[email protected]>
hlt_use_halt() no longer has any effect,
except to complicate the indentation in default_idle().
no functional change.
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/kernel/process.c | 39 ++++++++++++++-------------------------
1 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 8688ade..094d4ac 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -342,39 +342,28 @@ EXPORT_SYMBOL(boot_option_idle_override);
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
-static inline int hlt_use_halt(void)
-{
- return 1;
-}
-
/*
* We use this if we don't have any better
* idle routine..
*/
void default_idle(void)
{
- if (hlt_use_halt()) {
- trace_power_start(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle(1, smp_processor_id());
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
+ trace_power_start(POWER_CSTATE, 1, smp_processor_id());
+ trace_cpu_idle(1, smp_processor_id());
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
- if (!need_resched())
- safe_halt(); /* enables interrupts racelessly */
- else
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
- trace_power_end(smp_processor_id());
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
- } else {
+ if (!need_resched())
+ safe_halt(); /* enables interrupts racelessly */
+ else
local_irq_enable();
- /* loop is done by the caller */
- cpu_relax();
- }
+ current_thread_info()->status |= TS_POLLING;
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(default_idle);
--
1.7.4.1.343.ga91df
Len Brown <[email protected]> writes:
>
> floppy.c said:
>
> "disable hlt during certain critical i/o operations"
>
> x86/kernel/process.c said:
>
> "This halt magic was a workaround for ancient floppy DMA
> wreckage. It should be safe to remove."
AFAIK it was used on some 386/486s. I suspect it's safe to remove now.
-Andi
--
[email protected] -- Speaking for myself only
* Len Brown <[email protected]> [2011-03-24 03:08:28]:
> From: Len Brown <[email protected]>
>
> hlt_use_halt() no longer has any effect,
> except to complicate the indentation in default_idle().
>
> no functional change.
>
> Signed-off-by: Len Brown <[email protected]>
> ---
> arch/x86/kernel/process.c | 39 ++++++++++++++-------------------------
> 1 files changed, 14 insertions(+), 25 deletions(-)
>
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 8688ade..094d4ac 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -342,39 +342,28 @@ EXPORT_SYMBOL(boot_option_idle_override);
> void (*pm_idle)(void);
> EXPORT_SYMBOL(pm_idle);
>
> -static inline int hlt_use_halt(void)
> -{
> - return 1;
> -}
> -
> /*
> * We use this if we don't have any better
> * idle routine..
> */
> void default_idle(void)
> {
> - if (hlt_use_halt()) {
> - trace_power_start(POWER_CSTATE, 1, smp_processor_id());
> - trace_cpu_idle(1, smp_processor_id());
> - current_thread_info()->status &= ~TS_POLLING;
> - /*
> - * TS_POLLING-cleared state must be visible before we
> - * test NEED_RESCHED:
> - */
> - smp_mb();
> + trace_power_start(POWER_CSTATE, 1, smp_processor_id());
> + trace_cpu_idle(1, smp_processor_id());
> + current_thread_info()->status &= ~TS_POLLING;
> + /*
> + * TS_POLLING-cleared state must be visible before we
> + * test NEED_RESCHED:
> + */
> + smp_mb();
>
> - if (!need_resched())
> - safe_halt(); /* enables interrupts racelessly */
> - else
> - local_irq_enable();
> - current_thread_info()->status |= TS_POLLING;
> - trace_power_end(smp_processor_id());
> - trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
> - } else {
> + if (!need_resched())
> + safe_halt(); /* enables interrupts racelessly */
> + else
> local_irq_enable();
> - /* loop is done by the caller */
> - cpu_relax();
> - }
> + current_thread_info()->status |= TS_POLLING;
> + trace_power_end(smp_processor_id());
> + trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
> }
> #ifdef CONFIG_APM_MODULE
> EXPORT_SYMBOL(default_idle);
Hi Len,
The cleanup looks good.
--Vaidy
From: Len Brown <[email protected]>
hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 5 -----
arch/x86/kernel/cpu/bugs.c | 5 +----
arch/x86/kernel/cpu/proc.c | 2 --
arch/x86/kernel/process.c | 2 +-
arch/x86/kernel/setup.c | 4 ++--
arch/x86/xen/setup.c | 3 ---
6 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 45636ce..b5c83f1 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -67,7 +67,6 @@ struct cpuinfo_x86 {
char wp_works_ok; /* It doesn't on 386's */
/* Problems on some 486Dx4's and old 386's: */
- char hlt_works_ok;
char hard_math;
char rfu;
char fdiv_bug;
@@ -150,11 +149,7 @@ extern const struct seq_operations cpuinfo_op;
static inline int hlt_works(int cpu)
{
-#ifdef CONFIG_X86_32
- return cpu_data(cpu).hlt_works_ok;
-#else
return 1;
-#endif
}
#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 4c91631..b5e2910 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -82,10 +82,7 @@ static void __init check_hlt(void)
return;
printk(KERN_INFO "Checking 'hlt' instruction... ");
- if (!boot_cpu_data.hlt_works_ok) {
- printk("disabled\n");
- return;
- }
+
halt();
halt();
halt();
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 62ac8cb..203feb7 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -33,7 +33,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
seq_printf(m,
"fdiv_bug\t: %s\n"
- "hlt_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
"coma_bug\t: %s\n"
"fpu\t\t: %s\n"
@@ -41,7 +40,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
"cpuid level\t: %d\n"
"wp\t\t: %s\n",
c->fdiv_bug ? "yes" : "no",
- c->hlt_works_ok ? "no" : "yes",
c->f00f_bug ? "yes" : "no",
c->coma_bug ? "yes" : "no",
c->hard_math ? "yes" : "no",
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ff45541..4966c7e 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -362,7 +362,7 @@ EXPORT_SYMBOL(enable_hlt);
static inline int hlt_use_halt(void)
{
- return (!hlt_counter && boot_cpu_data.hlt_works_ok);
+ return (!hlt_counter);
}
#else
static inline int hlt_use_halt(void)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3cfe26..fab5631 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -175,9 +175,9 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 0, 0, -1};
/* common cpu data for all cpus */
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 0, 0, -1};
EXPORT_SYMBOL(boot_cpu_data);
static void set_mca_bus(int x)
{
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index a8a66a5..97d2fbd 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -351,9 +351,6 @@ void __init xen_arch_setup(void)
COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
/* Set up idle, making sure it calls safe_halt() pvop */
-#ifdef CONFIG_X86_32
- boot_cpu_data.hlt_works_ok = 1;
-#endif
pm_idle = default_idle;
boot_option_idle_override = IDLE_HALT;
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
no functional change
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 5 -----
arch/x86/kernel/process.c | 3 +--
2 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b5c83f1..8776232 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -147,11 +147,6 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
extern const struct seq_operations cpuinfo_op;
-static inline int hlt_works(int cpu)
-{
- return 1;
-}
-
#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
extern void cpu_detect(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 4966c7e..cd461c3 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -414,8 +414,7 @@ void stop_this_cpu(void *dummy)
disable_local_APIC();
for (;;) {
- if (hlt_works(smp_processor_id()))
- halt();
+ halt();
}
}
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
The X86_32-only "no-hlt" option was the functional equivalent of
"idle=poll" for the idle loop.
It would also set the X86_32-only "hlt_bug" line in the /proc/cpuinfo,
and cause halt to be skipped in stop_this_cpu().
Signed-off-by: Len Brown <[email protected]>
---
Documentation/kernel-parameters.txt | 4 ----
arch/x86/kernel/cpu/bugs.c | 8 --------
2 files changed, 0 insertions(+), 12 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f4a04c0..e6b4843 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1666,10 +1666,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
wfi(ARM) instruction doesn't work correctly and not to
use it. This is also useful when using JTAG debugger.
- no-hlt [BUGS=X86-32] Tells the kernel that the hlt
- instruction doesn't work correctly and not to
- use it.
-
no_file_caps Tells the kernel not to honor file capabilities. The
only way then for a file to be executed with privilege
is to be setuid root or executed by root.
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c39576c..4c91631 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -17,14 +17,6 @@
#include <asm/paravirt.h>
#include <asm/alternative.h>
-static int __init no_halt(char *s)
-{
- boot_cpu_data.hlt_works_ok = 0;
- return 1;
-}
-
-__setup("no-hlt", no_halt);
-
static int __init no_387(char *s)
{
boot_cpu_data.hard_math = 0;
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
There is some doubt whether the APM idle feature
to call into the BIOS from the idle loop is reliable.
Certainly it was known to fail on some machines,
but more importantly, APM machines have not shipped
for a decade and so finding machines to test the code
is problematic.
After this patch, systems running in APM mode will
simply run default_idle() and HALT without calling
into the BIOS from their idle loop.
This deletes modular use use of (pm_idle)() and default_idle().
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/Kconfig | 11 --
arch/x86/kernel/apm_32.c | 232 ----------------------------------------------
2 files changed, 0 insertions(+), 243 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d5ed94d..681bb25 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1809,17 +1809,6 @@ config APM_DO_ENABLE
T400CDT. This is off by default since most machines do fine without
this feature.
-config APM_CPU_IDLE
- bool "Make CPU Idle calls when idle"
- ---help---
- Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
- On some machines, this can activate improved power savings, such as
- a slowed CPU clock rate, when the machine is idle. These idle calls
- are made after the idle loop has run for some length of time (e.g.,
- 333 mS). On some machines, this will cause a hang at boot time or
- whenever the CPU becomes idle. (On machines with more than one CPU,
- this option does nothing.)
-
config APM_DISPLAY_BLANK
bool "Enable console blanking using APM"
---help---
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 0e4f24c..5bc37aa 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -175,8 +175,6 @@
* Ignore first resume after we generate our own resume event
* after a suspend (Thomas Hood)
* Daemonize now gets rid of our controlling terminal (sfr).
- * CONFIG_APM_CPU_IDLE now just affects the default value of
- * idle_threshold (sfr).
* Change name of kernel apm daemon (as it no longer idles) (sfr).
* 1.16ac: Fix up SMP support somewhat. You can now force SMP on and we
* make _all_ APM calls on the CPU#0. Fix unsafe sign bug.
@@ -261,12 +259,6 @@ extern int (*console_blank_hook)(int);
* [no-]smp Use apm even on an SMP box
* bounce[-_]interval=<n> number of ticks to ignore suspend
* bounces
- * idle[-_]threshold=<n> System idle percentage above which to
- * make APM BIOS idle calls. Set it to
- * 100 to disable.
- * idle[-_]period=<n> Period (in 1/100s of a second) over
- * which the idle percentage is
- * calculated.
*/
/* KNOWN PROBLEM MACHINES:
@@ -356,26 +348,12 @@ struct apm_user {
#define APM_BIOS_MAGIC 0x4101
/*
- * idle percentage above which bios idle calls are done
- */
-#ifdef CONFIG_APM_CPU_IDLE
-#define DEFAULT_IDLE_THRESHOLD 95
-#else
-#define DEFAULT_IDLE_THRESHOLD 100
-#endif
-#define DEFAULT_IDLE_PERIOD (100 / 3)
-
-/*
* Local variables
*/
static struct {
unsigned long offset;
unsigned short segment;
} apm_bios_entry;
-static int clock_slowed;
-static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
-static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
-static int set_pm_idle;
static int suspends_pending;
static int standbys_pending;
static int ignore_sys_suspend;
@@ -805,165 +783,6 @@ static int set_system_power_state(u_short state)
}
/**
- * apm_do_idle - perform power saving
- *
- * This function notifies the BIOS that the processor is (in the view
- * of the OS) idle. It returns -1 in the event that the BIOS refuses
- * to handle the idle request. On a success the function returns 1
- * if the BIOS did clock slowing or 0 otherwise.
- */
-
-static int apm_do_idle(void)
-{
- u32 eax;
- u8 ret = 0;
- int idled = 0;
- int polling;
- int err = 0;
-
- polling = !!(current_thread_info()->status & TS_POLLING);
- if (polling) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- }
- if (!need_resched()) {
- idled = 1;
- ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
- }
- if (polling)
- current_thread_info()->status |= TS_POLLING;
-
- if (!idled)
- return 0;
-
- if (ret) {
- static unsigned long t;
-
- /* This always fails on some SMP boards running UP kernels.
- * Only report the failure the first 5 times.
- */
- if (++t < 5) {
- printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
- t = jiffies;
- }
- return -1;
- }
- clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
- return clock_slowed;
-}
-
-/**
- * apm_do_busy - inform the BIOS the CPU is busy
- *
- * Request that the BIOS brings the CPU back to full performance.
- */
-
-static void apm_do_busy(void)
-{
- u32 dummy;
- int err;
-
- if (clock_slowed || ALWAYS_CALL_BUSY) {
- (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
- clock_slowed = 0;
- }
-}
-
-/*
- * If no process has really been interested in
- * the CPU for some time, we want to call BIOS
- * power management - we probably want
- * to conserve power.
- */
-#define IDLE_CALC_LIMIT (HZ * 100)
-#define IDLE_LEAKY_MAX 16
-
-static void (*original_pm_idle)(void) __read_mostly;
-
-/**
- * apm_cpu_idle - cpu idling for APM capable Linux
- *
- * This is the idling function the kernel executes when APM is available. It
- * tries to do BIOS powermanagement based on the average system idle time.
- * Furthermore it calls the system default idle routine.
- */
-
-static void apm_cpu_idle(void)
-{
- static int use_apm_idle; /* = 0 */
- static unsigned int last_jiffies; /* = 0 */
- static unsigned int last_stime; /* = 0 */
-
- int apm_idle_done = 0;
- unsigned int jiffies_since_last_check = jiffies - last_jiffies;
- unsigned int bucket;
-
-recalc:
- if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- } else if (jiffies_since_last_check > idle_period) {
- unsigned int idle_percentage;
-
- idle_percentage = current->stime - last_stime;
- idle_percentage *= 100;
- idle_percentage /= jiffies_since_last_check;
- use_apm_idle = (idle_percentage > idle_threshold);
- if (apm_info.forbid_idle)
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- }
-
- bucket = IDLE_LEAKY_MAX;
-
- while (!need_resched()) {
- if (use_apm_idle) {
- unsigned int t;
-
- t = jiffies;
- switch (apm_do_idle()) {
- case 0:
- apm_idle_done = 1;
- if (t != jiffies) {
- if (bucket) {
- bucket = IDLE_LEAKY_MAX;
- continue;
- }
- } else if (bucket) {
- bucket--;
- continue;
- }
- break;
- case 1:
- apm_idle_done = 1;
- break;
- default: /* BIOS refused */
- break;
- }
- }
- if (original_pm_idle)
- original_pm_idle();
- else
- default_idle();
- local_irq_disable();
- jiffies_since_last_check = jiffies - last_jiffies;
- if (jiffies_since_last_check > idle_period)
- goto recalc;
- }
-
- if (apm_idle_done)
- apm_do_busy();
-
- local_irq_enable();
-}
-
-/**
* apm_power_off - ask the BIOS to power off
*
* Handle the power off sequence. This is the one piece of code we
@@ -1881,12 +1700,6 @@ static int __init apm_setup(char *str)
if ((strncmp(str, "bounce-interval=", 16) == 0) ||
(strncmp(str, "bounce_interval=", 16) == 0))
bounce_interval = simple_strtol(str + 16, NULL, 0);
- if ((strncmp(str, "idle-threshold=", 15) == 0) ||
- (strncmp(str, "idle_threshold=", 15) == 0))
- idle_threshold = simple_strtol(str + 15, NULL, 0);
- if ((strncmp(str, "idle-period=", 12) == 0) ||
- (strncmp(str, "idle_period=", 12) == 0))
- idle_period = simple_strtol(str + 12, NULL, 0);
invert = (strncmp(str, "no-", 3) == 0) ||
(strncmp(str, "no_", 3) == 0);
if (invert)
@@ -1898,7 +1711,6 @@ static int __init apm_setup(char *str)
power_off = !invert;
if (strncmp(str, "smp", 3) == 0) {
smp = !invert;
- idle_threshold = 100;
}
if ((strncmp(str, "allow-ints", 10) == 0) ||
(strncmp(str, "allow_ints", 10) == 0))
@@ -1999,17 +1811,6 @@ static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
return 0;
}
-/* Some APM bioses hang on APM idle calls */
-static int __init apm_likes_to_melt(const struct dmi_system_id *d)
-{
- if (apm_info.forbid_idle == 0) {
- apm_info.forbid_idle = 1;
- printk(KERN_INFO "%s machine detected. "
- "Disabling APM idle calls.\n", d->ident);
- }
- return 0;
-}
-
/*
* Check for clue free BIOS implementations who use
* the following QA technique
@@ -2150,16 +1951,6 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
},
- { /* APM idle hangs */
- apm_likes_to_melt, "Jabil AMD",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
- },
- { /* APM idle hangs */
- apm_likes_to_melt, "AMI Bios",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
- },
{ /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
swab_apm_power_in_minutes, "Sony VAIO",
{ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -2390,14 +2181,6 @@ static int __init apm_init(void)
if (misc_register(&apm_device))
printk(KERN_WARNING "apm: Could not register misc device.\n");
- if (HZ != 100)
- idle_period = (idle_period * HZ) / 100;
- if (idle_threshold < 100) {
- original_pm_idle = pm_idle;
- pm_idle = apm_cpu_idle;
- set_pm_idle = 1;
- }
-
return 0;
}
@@ -2405,15 +2188,6 @@ static void __exit apm_exit(void)
{
int error;
- if (set_pm_idle) {
- pm_idle = original_pm_idle;
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- cpu_idle_wait();
- }
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0);
@@ -2451,12 +2225,6 @@ MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
module_param(realmode_power_off, bool, 0444);
MODULE_PARM_DESC(realmode_power_off,
"Switch to real mode before powering off");
-module_param(idle_threshold, int, 0444);
-MODULE_PARM_DESC(idle_threshold,
- "System idle percentage above which to make APM BIOS idle calls");
-module_param(idle_period, int, 0444);
-MODULE_PARM_DESC(idle_period,
- "Period (in sec/100) over which to caculate the idle percentage");
module_param(smp, bool, 0444);
MODULE_PARM_DESC(smp,
"Set this to enable APM use on an SMP platform. Use with caution on older systems");
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
For ACPI mode, mwait_with_hints() in cstate.c is used instead of
process.c's mwait_idle().
For INTEL_IDLE mode, the mwait in intel_idle() is used instead of
process.c's mwait_idle().
So delete process.c's mwait_idle().
This will change the behaviour of SMP sysgtems that are
running !ACPI and !INTEL_IDLE kernels -- they will use
HALT instead of MWAIT.
This deletes the "idle=mwait" parameter, and thus the
boot_option_idle_override == IDLE_FORCE_MWAIT flag.
Signed-off-by: Len Brown <[email protected]>
---
Documentation/kernel-parameters.txt | 7 +------
arch/x86/include/asm/processor.h | 2 +-
arch/x86/kernel/process.c | 34 +---------------------------------
drivers/acpi/processor_idle.c | 1 -
4 files changed, 3 insertions(+), 41 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index e6b4843..ce9624a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -917,16 +917,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Claim all unknown PCI IDE storage controllers.
idle= [X86]
- Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
+ Format: idle=poll, idle=halt, idle=nomwait
Poll forces a polling idle loop that can slightly
improve the performance of waking up a idle CPU, but
will use a lot of power and make the system run hot.
Not recommended.
- idle=mwait: On systems which support MONITOR/MWAIT but
- the kernel chose to not use it because it doesn't save
- as much power as a normal idle loop, use the
- MONITOR/MWAIT idle loop anyways. Performance should be
- the same as idle=poll.
idle=halt: Halt is forced to be used for CPU idle.
In such case C2/C3 won't be used again.
idle=nomwait: Disable mwait for CPU C-states
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 3b288ca..0d8d2a4 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -752,7 +752,7 @@ extern unsigned long boot_option_idle_override;
extern bool c1e_detected;
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
- IDLE_POLL, IDLE_FORCE_MWAIT};
+ IDLE_POLL};
extern void enable_sep_cpu(void);
extern int sysenter_setup(void);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 9f08e7b..4b93d50 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -399,27 +399,6 @@ void cpu_idle_wait(void)
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
-/* Default MONITOR/MWAIT with no hints, used for default C1 state */
-static void mwait_idle(void)
-{
- if (!need_resched()) {
- trace_power_start(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle(1, smp_processor_id());
- if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
- clflush((void *)¤t_thread_info()->flags);
-
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
- smp_mb();
- if (!need_resched())
- __sti_mwait(0, 0);
- else
- local_irq_enable();
- trace_power_end(smp_processor_id());
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
- } else
- local_irq_enable();
-}
-
/*
* On SMP it's slightly faster (but much more power-consuming!)
* to poll the ->work.need_resched flag instead of waiting for the
@@ -457,9 +436,6 @@ int mwait_usable(const struct cpuinfo_x86 *c)
{
u32 eax, ebx, ecx, edx;
- if (boot_option_idle_override == IDLE_FORCE_MWAIT)
- return 1;
-
if (c->cpuid_level < MWAIT_INFO)
return 0;
@@ -548,13 +524,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
if (pm_idle)
return;
- if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
- /*
- * One CPU supports mwait => All CPUs supports mwait
- */
- printk(KERN_INFO "using mwait in idle threads.\n");
- pm_idle = mwait_idle;
- } else if (cpu_has_amd_erratum(amd_erratum_400)) {
+ if (cpu_has_amd_erratum(amd_erratum_400)) {
/* E400: APIC timer interrupt does not wake up CPU from C1e */
printk(KERN_INFO "using C1E aware idle routine\n");
pm_idle = c1e_idle;
@@ -578,8 +548,6 @@ static int __init idle_setup(char *str)
printk("using polling idle threads.\n");
pm_idle = poll_idle;
boot_option_idle_override = IDLE_POLL;
- } else if (!strcmp(str, "mwait")) {
- boot_option_idle_override = IDLE_FORCE_MWAIT;
} else if (!strcmp(str, "halt")) {
/*
* When the boot option of idle=halt is added, halt is
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index d615b7d..a15390c 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -82,7 +82,6 @@ module_param(latency_factor, uint, 0644);
static int disabled_by_idle_boot_param(void)
{
return boot_option_idle_override == IDLE_POLL ||
- boot_option_idle_override == IDLE_FORCE_MWAIT ||
boot_option_idle_override == IDLE_HALT;
}
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
no functional change
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 2 --
arch/x86/kernel/acpi/cstate.c | 24 ++++++++++++++++++++++++
arch/x86/kernel/process.c | 23 -----------------------
3 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 8776232..3b288ca 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -745,8 +745,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
:: "a" (eax), "c" (ecx));
}
-extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
-
extern void select_idle_routine(const struct cpuinfo_x86 *c);
extern void init_c1e_mask(void);
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 5812404..c49281e 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -149,6 +149,30 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
}
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
+/*
+ * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
+ * which can obviate IPI to trigger checking of need_resched.
+ * We execute MONITOR against need_resched and enter optimized wait state
+ * through MWAIT. Whenever someone changes need_resched, we would be woken
+ * up from MWAIT (without an IPI).
+ *
+ * New with Core Duo processors, MWAIT can take some hints based on CPU
+ * capability.
+ */
+static void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
+{
+ if (!need_resched()) {
+ if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
+ clflush((void *)¤t_thread_info()->flags);
+
+ __monitor((void *)¤t_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (!need_resched())
+ __mwait(ax, cx);
+ }
+}
+
+
void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
{
unsigned int cpu = smp_processor_id();
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 9d485d9..9f08e7b 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -399,29 +399,6 @@ void cpu_idle_wait(void)
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
-/*
- * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
- * which can obviate IPI to trigger checking of need_resched.
- * We execute MONITOR against need_resched and enter optimized wait state
- * through MWAIT. Whenever someone changes need_resched, we would be woken
- * up from MWAIT (without an IPI).
- *
- * New with Core Duo processors, MWAIT can take some hints based on CPU
- * capability.
- */
-void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
-{
- if (!need_resched()) {
- if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
- clflush((void *)¤t_thread_info()->flags);
-
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
- smp_mb();
- if (!need_resched())
- __mwait(ax, cx);
- }
-}
-
/* Default MONITOR/MWAIT with no hints, used for default C1 state */
static void mwait_idle(void)
{
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
APM was the only potential modular user of pm_idle,
and default_idle(), and that use is now gone.
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/kernel/process.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 094d4ac..9d485d9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -340,7 +340,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
-EXPORT_SYMBOL(pm_idle);
/*
* We use this if we don't have any better
@@ -365,9 +364,6 @@ void default_idle(void)
trace_power_end(smp_processor_id());
trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
}
-#ifdef CONFIG_APM_MODULE
-EXPORT_SYMBOL(default_idle);
-#endif
void stop_this_cpu(void *dummy)
{
--
1.7.4.2.406.gbe91
unchanged:
[PATCH 1/9] x86 idle: remove "no-hlt" cmdline param
[PATCH 2/9] x86 idle: remove NOP cpuinfo_x86.hlt_works_ok flag
[PATCH 3/9] x86 idle: remove NOP halt_works()
[PATCH 4/9] x86 idle floppy: delete disable_hlt()/enable_hlt()
[PATCH 5/9] x86 idle: remove NOP hlt_use_halt()
new:
[PATCH 6/9] x86 idle APM: delete apm_cpu_idle(), and its use of pm_idle
[PATCH 7/9] x86 idle: do not EXPORT_SYMBOL pm_idle and default_idle
[PATCH 8/9] x86 idle: move mwait_idle_with_hints() to where it is used
[PATCH 9/9] x86 idle: delete mwait_idle()
Documentation/kernel-parameters.txt | 11 +--
arch/x86/Kconfig | 11 --
arch/x86/include/asm/processor.h | 14 +--
arch/x86/include/asm/system.h | 7 -
arch/x86/kernel/acpi/cstate.c | 24 ++++
arch/x86/kernel/apm_32.c | 232 -----------------------------------
arch/x86/kernel/cpu/bugs.c | 13 +--
arch/x86/kernel/cpu/proc.c | 2 -
arch/x86/kernel/process.c | 127 +++-----------------
arch/x86/kernel/setup.c | 4 +-
arch/x86/xen/setup.c | 3 -
drivers/acpi/processor_idle.c | 1 -
drivers/block/floppy.c | 35 ------
13 files changed, 45 insertions(+), 439 deletions(-)
What is next:
handle c1e_idle() vs default_idle()
run-time check for AMD workaround enable as part of default_idle?
give xen_arch_setup default_idle() w/o having it touch pm_idle
perhaps it can simply set a flag to disable cpuidle...
which is what would run if the xen kernel were
booted on raw iron. Or can we handle this
at compile time?
delete pm_idle
x86 will then use default_idle or cpuidle
allow cpuidle to use default_idle to handle the period
where it polls because cpus have not yet registered
From: Len Brown <[email protected]>
The X86_32-only disable_hlt/enable_hlt mechanism was used
by the 32-bit floppy driver. Its effect was to replace
the use of the HLT instruction inside default_idle() with
cpu_relax().
Unlcear why this workaround was ever needed, it was commented:
floppy.c said:
"disable hlt during certain critical i/o operations"
x86/kernel/process.c said:
"This halt magic was a workaround for ancient floppy DMA
wreckage. It should be safe to remove."
So remove it, as it allows us to simplify the x86 idle code.
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/system.h | 7 -------
arch/x86/kernel/process.c | 24 ------------------------
drivers/block/floppy.c | 35 -----------------------------------
3 files changed, 0 insertions(+), 66 deletions(-)
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 33ecc3e..013dd42 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -93,10 +93,6 @@ do { \
"memory"); \
} while (0)
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
#else
#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
@@ -337,9 +333,6 @@ static inline void clflush(volatile void *__p)
#define nop() asm volatile ("nop")
-void disable_hlt(void);
-void enable_hlt(void);
-
void cpu_idle_wait(void);
extern unsigned long arch_align_stack(unsigned long sp);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index cd461c3..8688ade 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -342,34 +342,10 @@ EXPORT_SYMBOL(boot_option_idle_override);
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
-#ifdef CONFIG_X86_32
-/*
- * This halt magic was a workaround for ancient floppy DMA
- * wreckage. It should be safe to remove.
- */
-static int hlt_counter;
-void disable_hlt(void)
-{
- hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
- hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
-static inline int hlt_use_halt(void)
-{
- return (!hlt_counter);
-}
-#else
static inline int hlt_use_halt(void)
{
return 1;
}
-#endif
/*
* We use this if we don't have any better
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 77fc76f..9a4e006 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1032,36 +1032,6 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
return 0;
}
-static DEFINE_SPINLOCK(floppy_hlt_lock);
-static int hlt_disabled;
-static void floppy_disable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (!hlt_disabled) {
- hlt_disabled = 1;
-#ifdef HAVE_DISABLE_HLT
- disable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
-static void floppy_enable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (hlt_disabled) {
- hlt_disabled = 0;
-#ifdef HAVE_DISABLE_HLT
- enable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
static void setup_DMA(void)
{
unsigned long f;
@@ -1106,7 +1076,6 @@ static void setup_DMA(void)
fd_enable_dma();
release_dma_lock(f);
#endif
- floppy_disable_hlt();
}
static void show_floppy(void);
@@ -1708,7 +1677,6 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
fd_disable_dma();
release_dma_lock(f);
- floppy_enable_hlt();
do_floppy = NULL;
if (fdc >= N_FDC || FDCS->address == -1) {
/* we don't even know which FDC is the culprit */
@@ -1857,8 +1825,6 @@ static void floppy_shutdown(unsigned long data)
show_floppy();
cancel_activity();
- floppy_enable_hlt();
-
flags = claim_dma_lock();
fd_disable_dma();
release_dma_lock(flags);
@@ -4503,7 +4469,6 @@ static void floppy_release_irq_and_dma(void)
#if N_FDC > 1
set_dor(1, ~8, 0);
#endif
- floppy_enable_hlt();
if (floppy_track_buffer && max_buffer_sectors) {
tmpsize = max_buffer_sectors * 1024;
--
1.7.4.2.406.gbe91
From: Len Brown <[email protected]>
hlt_use_halt() no longer has any effect,
except to complicate the indentation in default_idle().
no functional change.
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/kernel/process.c | 39 ++++++++++++++-------------------------
1 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 8688ade..094d4ac 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -342,39 +342,28 @@ EXPORT_SYMBOL(boot_option_idle_override);
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
-static inline int hlt_use_halt(void)
-{
- return 1;
-}
-
/*
* We use this if we don't have any better
* idle routine..
*/
void default_idle(void)
{
- if (hlt_use_halt()) {
- trace_power_start(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle(1, smp_processor_id());
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
+ trace_power_start(POWER_CSTATE, 1, smp_processor_id());
+ trace_cpu_idle(1, smp_processor_id());
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
- if (!need_resched())
- safe_halt(); /* enables interrupts racelessly */
- else
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
- trace_power_end(smp_processor_id());
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
- } else {
+ if (!need_resched())
+ safe_halt(); /* enables interrupts racelessly */
+ else
local_irq_enable();
- /* loop is done by the caller */
- cpu_relax();
- }
+ current_thread_info()->status |= TS_POLLING;
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL(default_idle);
--
1.7.4.2.406.gbe91
* Len Brown <[email protected]> wrote:
> From: Len Brown <[email protected]>
>
> hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
>
> On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
I think you missed the valid usecase where an old CPU with broken halt is
booted with the no-hlt boot parameter and does not want to crash in the HLT
instruction.
That "no-hlt" boot parameter does:
arch/x86/kernel/cpu/bugs.c: boot_cpu_data.hlt_works_ok = 0;
We can restrict compatibility, but *please* lets do it *explicitly*, not under
some 'remove unused code' pretense ...
Could you please list all CPU models that are affected?
Thanks,
Ingo
On 03/31/2011 11:33 AM, Len Brown wrote:
> unchanged:
>
> [PATCH 1/9] x86 idle: remove "no-hlt" cmdline param
> [PATCH 2/9] x86 idle: remove NOP cpuinfo_x86.hlt_works_ok flag
> [PATCH 3/9] x86 idle: remove NOP halt_works()
> [PATCH 4/9] x86 idle floppy: delete disable_hlt()/enable_hlt()
> [PATCH 5/9] x86 idle: remove NOP hlt_use_halt()
>
> new:
>
> [PATCH 6/9] x86 idle APM: delete apm_cpu_idle(), and its use of pm_idle
> [PATCH 7/9] x86 idle: do not EXPORT_SYMBOL pm_idle and default_idle
> [PATCH 8/9] x86 idle: move mwait_idle_with_hints() to where it is used
> [PATCH 9/9] x86 idle: delete mwait_idle()
>
>
> Documentation/kernel-parameters.txt | 11 +--
> arch/x86/Kconfig | 11 --
> arch/x86/include/asm/processor.h | 14 +--
> arch/x86/include/asm/system.h | 7 -
> arch/x86/kernel/acpi/cstate.c | 24 ++++
> arch/x86/kernel/apm_32.c | 232 -----------------------------------
> arch/x86/kernel/cpu/bugs.c | 13 +--
> arch/x86/kernel/cpu/proc.c | 2 -
> arch/x86/kernel/process.c | 127 +++-----------------
> arch/x86/kernel/setup.c | 4 +-
> arch/x86/xen/setup.c | 3 -
> drivers/acpi/processor_idle.c | 1 -
> drivers/block/floppy.c | 35 ------
> 13 files changed, 45 insertions(+), 439 deletions(-)
>
> What is next:
>
> handle c1e_idle() vs default_idle()
> run-time check for AMD workaround enable as part of default_idle?
> give xen_arch_setup default_idle() w/o having it touch pm_idle
> perhaps it can simply set a flag to disable cpuidle...
> which is what would run if the xen kernel were
> booted on raw iron. Or can we handle this
> at compile time?
I guess it may be good to have a method to override cpuidle and
force it to call default_idle from inside cpuidle_idle_call(). This
could be useful for users other than xen in future. Ofcourse this
override should not touch pm_idle (which would be removed anyway).
Provision is already there to call default_idle from inside
cpuidle_idle_call(); we can use that after checking a flag?? Can
we use something like boot_option_idle_override? Or set/unset
flag through an API?
> delete pm_idle
> x86 will then use default_idle or cpuidle
> allow cpuidle to use default_idle to handle the period
> where it polls because cpus have not yet registered
If we remove pm_idle and directly call cpuidle, the
check already exists to call default_idle until a cpuidle
driver (and cpus) is registered.
-Trinabh
> > hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
> >
> > On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
>
> I think you missed the valid usecase where an old CPU with broken halt is
> booted with the no-hlt boot parameter and does not want to crash in the HLT
> instruction.
>
> That "no-hlt" boot parameter does:
>
> arch/x86/kernel/cpu/bugs.c: boot_cpu_data.hlt_works_ok = 0;
>
> We can restrict compatibility, but *please* lets do it *explicitly*, not under
> some 'remove unused code' pretense ...
>
> Could you please list all CPU models that are affected?
"no-hlt" existed only for 32-bit, and there were exactly zero
automatic invocations of it.
"idle=poll" does the same thing -- sans change a line
in /proc/cpuinfo.
Do we really need both?
thanks,
-Len
> > What is next:
> >
> > handle c1e_idle() vs default_idle()
> > run-time check for AMD workaround enable as part of default_idle?
> > give xen_arch_setup default_idle() w/o having it touch pm_idle
> > perhaps it can simply set a flag to disable cpuidle...
> > which is what would run if the xen kernel were
> > booted on raw iron. Or can we handle this
> > at compile time?
>
> I guess it may be good to have a method to override cpuidle and
> force it to call default_idle from inside cpuidle_idle_call(). This
> could be useful for users other than xen in future. Ofcourse this override
> should not touch pm_idle (which would be removed anyway).
Actually what I was thinking was the ability to disable cpuidle
altogether via cmdline. ie a run-time equivalent of CONFIG_CPU_IDLE=n.
eg. "cpuidle=0" In that case cpu_idle_call() would return error
and we'd have:
cpu_idle()
if (cpu_idle_call())
default_idle()
This is also a clean way for CONFIG_CPU_IDLE=n to work.
> Provision is already there to call default_idle from inside
> cpuidle_idle_call(); we can use that after checking a flag?? Can
> we use something like boot_option_idle_override? Or set/unset
> flag through an API?
I think it is strange for cpuidle to turn around and
call back to default_idle(). I'd like to see if we can
keep knowledge of default_idle() inside process.c.
If cpuidle can't do better than default_idle()
then it sholdn't be running...
> > delete pm_idle
> > x86 will then use default_idle or cpuidle
> > allow cpuidle to use default_idle to handle the period
> > where it polls because cpus have not yet registered
>
> If we remove pm_idle and directly call cpuidle, the
> check already exists to call default_idle until a cpuidle
> driver (and cpus) is registered.
it isn't working.
If it were, then we'd not see any polling in the cpuidle stats.
cheers,
-Len
* Len Brown <[email protected]> wrote:
> > > hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
> > >
> > > On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
> >
> > I think you missed the valid usecase where an old CPU with broken halt is
> > booted with the no-hlt boot parameter and does not want to crash in the HLT
> > instruction.
> >
> > That "no-hlt" boot parameter does:
> >
> > arch/x86/kernel/cpu/bugs.c: boot_cpu_data.hlt_works_ok = 0;
> >
> > We can restrict compatibility, but *please* lets do it *explicitly*, not under
> > some 'remove unused code' pretense ...
> >
> > Could you please list all CPU models that are affected?
>
> "no-hlt" existed only for 32-bit, and there were exactly zero
> automatic invocations of it.
Do we know whether a distro adds this to the boot line? Do we know about users
relying on it.
> "idle=poll" does the same thing -- sans change a line
> in /proc/cpuinfo.
It also has an effect on halt/poweroff, right?
> Do we really need both?
Probably not, as i said i do not disagree - i just think it should be more
explicit. Make it a: "users of CPU models X beware" commit title, not 'remove
inactive code' ...
So please list the affected hardware and list the affected boot parameter
explicitly, in a well-titled commit that phases out this (very likely unused)
compatibility hack and *document* the idle=poll workaround for ancient
hardware.
There's still i386DX CPUs being manufactured these days - a 20+ years old CPU
design is surprisingly resilient to spurious patent claims, for obvious
reasons.
Really, there's no need to do things by stealth. There's few things worse than
doing the right thing for the wrong reason - it becomes a bad habit of subtly
broken thinking quickly.
Thanks,
Ingo
> Do we know whether a distro adds this to the boot line? Do we know about users
> relying on it.
I certainly had hardware that needed it. Don't any more but this is more
trying to rip out stuff without letting nature take its course.
It's a trivial feature item.
> > Do we really need both?
>
> Probably not, as i said i do not disagree - i just think it should be more
> explicit. Make it a: "users of CPU models X beware" commit title, not 'remove
> inactive code' ...
Just make the one config variable respond to both boot configuration
options. The parser is __init code anyway so discarded so the actual code
cost of compatibility is exactly NIL.
Alan
* Alan Cox <[email protected]> wrote:
> > Do we know whether a distro adds this to the boot line? Do we know about users
> > relying on it.
>
> I certainly had hardware that needed it. Don't any more but this is more
> trying to rip out stuff without letting nature take its course.
>
> It's a trivial feature item.
Yes.
> > > Do we really need both?
> >
> > Probably not, as i said i do not disagree - i just think it should be more
> > explicit. Make it a: "users of CPU models X beware" commit title, not 'remove
> > inactive code' ...
>
> Just make the one config variable respond to both boot configuration
> options. The parser is __init code anyway so discarded so the actual code
> cost of compatibility is exactly NIL.
Yeah, agreed.
Btw., we used to auto-detect broken HLT systems IIRC - but that got lost
already. We should at least honor the boot parameter.
Thanks,
Ingo
* Alan Cox <[email protected]> wrote:
> > Btw., we used to auto-detect broken HLT systems IIRC - but that got lost
> > already. We should at least honor the boot parameter.
>
> I don't believe we ever auto detected them or found a way to do so. That
> was why the HLT message was printed before hlt was executed.
Yeah - the CPU hang was unrecoverably deep so no auto-detection was possible.
That's seriously ancient stuff - still, keeping the boot option around (<10
lines of code) does not hurt anyone.
Thanks,
Ingo
> Btw., we used to auto-detect broken HLT systems IIRC - but that got lost
> already. We should at least honor the boot parameter.
I don't believe we ever auto detected them or found a way to do so. That
was why the HLT message was printed before hlt was executed.
> [PATCH 6/9] x86 idle APM: delete apm_cpu_idle(), and its use of pm_idle
> [PATCH 7/9] x86 idle: do not EXPORT_SYMBOL pm_idle and default_idle
I thought someone had agreed to look after APM ?
I'm also curious why you write
"There is some doubt whether the APM idle feature
to call into the BIOS from the idle loop is reliable.
Certainly it was known to fail on some machines,
but more importantly, APM machines have not shipped
for a decade and so finding machines to test the code
is problematic."
We don't care if it doesn't work on a few machines (in fact we have
a table to avoid that), we care that it *DOES* work on lots.
Removing it probably isn't a bad thing long term, but it's not appeared in
the deprecated list and has not been there for several releases so it is
not eligible for removal at this point.
People spent years getting Linux to support all this hardware and
throwing bits out left right and centre to tidy up your current project
is not the way it should be done.
So can we do this properly please. We have a process for good reason.
Deprecate it properly
Add a printk/WARN_ON() indicating to the user it is deprecated but we
will continue, and then give it a couple of releaes. Kerneloops.org will
help answer whether that WARN_ON was hit.
And in the meantime just progress the rest of the work with it present.
If you break APM support by accident doing that then either
a) someone will jump up and down and yell regression - and debug it for
you
or
b) there will be silence because nobody noticed it broke
Alan
* Alan Cox <[email protected]> wrote:
> We don't care if it doesn't work on a few machines (in fact we have
> a table to avoid that), we care that it *DOES* work on lots.
>
> Removing it probably isn't a bad thing long term, but it's not appeared in
> the deprecated list and has not been there for several releases so it is
> not eligible for removal at this point.
>
> People spent years getting Linux to support all this hardware and
> throwing bits out left right and centre to tidy up your current project
> is not the way it should be done.
>
> So can we do this properly please. We have a process for good reason.
>
> Deprecate it properly
Ok, agreed. Len, mind delaying this patch for a few releases?
> Add a printk/WARN_ON() indicating to the user it is deprecated but we
> will continue, and then give it a couple of releaes. Kerneloops.org will
> help answer whether that WARN_ON was hit.
Yeah, also add a -stable backport so that older kernel users have a chance to
notice faster.
Thanks,
Ingo
On 03/31/2011 02:35 AM, Ingo Molnar wrote:
>
> * Alan Cox <[email protected]> wrote:
>
>>> Btw., we used to auto-detect broken HLT systems IIRC - but that got lost
>>> already. We should at least honor the boot parameter.
>>
>> I don't believe we ever auto detected them or found a way to do so. That
>> was why the HLT message was printed before hlt was executed.
>
> Yeah - the CPU hang was unrecoverably deep so no auto-detection was possible.
>
> That's seriously ancient stuff - still, keeping the boot option around (<10
> lines of code) does not hurt anyone.
>
What it was was bad power supplies or low-capacitance, high-inductance
power distribution that happened to work with MS-DOS which always burned
the CPU at 100% and therefore left the power draw relatively consistent
current. A proper OS putting the CPU in HLT produced a lot more high
frequency noise on the power busses, with disastrous results without
proper bypass.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
On Thu, 31 Mar 2011 07:19:50 -0700
"H. Peter Anvin" <[email protected]> wrote:
> On 03/31/2011 02:35 AM, Ingo Molnar wrote:
> >
> > * Alan Cox <[email protected]> wrote:
> >
> >>> Btw., we used to auto-detect broken HLT systems IIRC - but that got lost
> >>> already. We should at least honor the boot parameter.
> >>
> >> I don't believe we ever auto detected them or found a way to do so. That
> >> was why the HLT message was printed before hlt was executed.
> >
> > Yeah - the CPU hang was unrecoverably deep so no auto-detection was possible.
> >
> > That's seriously ancient stuff - still, keeping the boot option around (<10
> > lines of code) does not hurt anyone.
> >
>
> What it was was bad power supplies or low-capacitance, high-inductance
> power distribution that happened to work with MS-DOS which always burned
> the CPU at 100% and therefore left the power draw relatively consistent
> current. A proper OS putting the CPU in HLT produced a lot more high
> frequency noise on the power busses, with disastrous results without
> proper bypass.
And also chipset errata in some cases - eg some revisions of the CS5510
hung the box solid if a CPU hlt occurred during an IDE transfer. I don't
think any CS5510s are still around although I've had mail from someone
with a CS5520 in use not that long ago so who knows!
The joy of ancient history.
On 03/31/2011 07:41 AM, Alan Cox wrote:
>>
>> What it was was bad power supplies or low-capacitance, high-inductance
>> power distribution that happened to work with MS-DOS which always burned
>> the CPU at 100% and therefore left the power draw relatively consistent
>> current. A proper OS putting the CPU in HLT produced a lot more high
>> frequency noise on the power busses, with disastrous results without
>> proper bypass.
>
> And also chipset errata in some cases - eg some revisions of the CS5510
> hung the box solid if a CPU hlt occurred during an IDE transfer. I don't
> think any CS5510s are still around although I've had mail from someone
> with a CS5520 in use not that long ago so who knows!
>
> The joy of ancient history.
Ah, yes, I guess there was a special cycle on the bus which the chipset
could misinterpret.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
> > > > hlt_works_ok was X86_32 only, initialized to 1, and never cleared.
> > > >
> > > > On 32-bit kernels, this deletes a line from /proc/cpuinfo: "hlt_bug : no"
> > >
> > > I think you missed the valid usecase where an old CPU with broken halt is
> > > booted with the no-hlt boot parameter and does not want to crash in the HLT
> > > instruction.
> > >
> > > That "no-hlt" boot parameter does:
> > >
> > > arch/x86/kernel/cpu/bugs.c: boot_cpu_data.hlt_works_ok = 0;
> > >
> > > We can restrict compatibility, but *please* lets do it *explicitly*, not under
> > > some 'remove unused code' pretense ...
> > >
> > > Could you please list all CPU models that are affected?
> >
> > "no-hlt" existed only for 32-bit, and there were exactly zero
> > automatic invocations of it.
>
> Do we know whether a distro adds this to the boot line? Do we know about users
> relying on it.
Impossible to know.
> > "idle=poll" does the same thing -- sans change a line
> > in /proc/cpuinfo.
>
> It also has an effect on halt/poweroff, right?
Yes, if somebody invokes kernel_halt(), then it
uses stop_this_cpu(), which uses HLT unless this flag is cleared.
The functional change of deleting "no-hlt", which was the only
way to clear this flag, was in the previous patch, and so
I should have mentioned it here.
stop_this_cpu() is not in the poweroff path.
It is a different topic, but I'd be curious to know why
any users of the latest kernel on x86 might be invoking
kernel_halt() instead of kernel_power_off().
> > Do we really need both?
>
> Probably not, as i said i do not disagree - i just think it should be more
> explicit. Make it a: "users of CPU models X beware" commit title, not 'remove
> inactive code' ...
My intent was to make the functional change in 1/9
and the NOP cleanup in 2/9.
> So please list the affected hardware and list the affected boot parameter
> explicitly, in a well-titled commit that phases out this (very likely unused)
> compatibility hack and *document* the idle=poll workaround for ancient
> hardware.
There is no known list of affected hardware.
> There's still i386DX CPUs being manufactured these days - a 20+ years old CPU
> design is surprisingly resilient to spurious patent claims, for obvious
> reasons.
>
> Really, there's no need to do things by stealth. There's few things worse than
> doing the right thing for the wrong reason - it becomes a bad habit of subtly
> broken thinking quickly.
I agree completely, which is why I've sent this patch -- twice, so far --
to 5000 of my closest friends, including you:-)
thanks,
-Len
On 03/31/2011 11:07 AM, Len Brown wrote:
>>
>> Do we know whether a distro adds this to the boot line? Do we know about users
>> relying on it.
>
> Impossible to know.
>
The first would be insanely unlikely, as the machines with HLT problems
were already getting old by the time Linux distributions started
appearing in significant numbers.
Users relying on it is another issue.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
Thanks for the review feedback that this change is too sudden.
How about this plan with a 4-month delay?
cheers,
-Len Brown, Intel Open Source Technology Center
2.6.39-rc1
----------
x86 idle: deprecate floppy disable_hlt
feature-removal.txt for 2.6.40 (4 months)
WARN_ONCE on use
cc: [email protected]
x86 idle APM: deprecate apm_cpu_idle
feature-removal.txt for 2.6.40 (4 months)
#warning on CONFIG_APM_CPU_IDLE remove in 2.6.40
WARN_ONCE in apm_cpu_idle()
cc: [email protected]
x86 idle: export pm_idle only for CONFIG_APM_MODULE
like we do for default_idle(),
EXPORT_SYMBOL(pm_idle) only on CONFIG_APM_MODULE
x86 idle: deprecate "no-hlt" cmdline param
feature-removal.txt for 2.6.40 (4 months)
cc [email protected]
WARN_ONCE if used, ask if idle=poll is sufficient
same as idle=poll, except no-hlt also disables
HLT in machine_halt().
x86 idle: deprecate "idle=mwait"
feature-removal.txt for 2.6.40 (4 months)
cc [email protected]
WARN_ONCE on invocation
x86 idle: re-name ce1_idle
rename for clarity, no functional change
2.6.40-merge
------
x86 idle: move mwait_idle_with_hints()
out of process.c to cstate.c, make static
x86 idle floppy: remove deprecated disable_hlt/enable_hlt
x86 idle: delete deprecated idle=mwait
default_idle() can use HLT
cpuidle: add cmdline "cpuidle=off"
allow falling back to native default_idle
x86 idle xen: stop touching pm_idle and default_idle
Xen Dom0 kernel only needs HLT, but include
CPU_IDLE, ACPI etc for running on bare hardware.
So when running in Xen Dom0 mode, disable cpuidle
to fall back to default_idle.
x86 idle APM: remove deprecated apm_cpu_idle()
and its use of pm_idle
x86 idle cpuidle: delete public use of pm_idle
make pm_idle and default_idle static to process.c
add return value from cpu_idle_call()
invoke cpu_idle_call from cpu_idle() rather than via pm_idle
cpu_idle() {
...
if (cpu_idle_call())
pm_idle(); /* non cpuidle default */
}
x86 idle: remove "no-hlt" cmdline param
remove deprecated "no-hlt"
use idle=poll instead
x86 idle: remove cpuinfo_x86.hlt_works_ok flag
it became a NOP when "no-hlt" was removed
x86 idle: remove hlt_works()
it became a NOP when cpuinfo_x86.hlt_works_ok was removed
> 2.6.39-rc1
> ----------
>
> x86 idle: deprecate floppy disable_hlt
> feature-removal.txt for 2.6.40 (4 months)
> WARN_ONCE on use
> cc: [email protected]
>
> x86 idle APM: deprecate apm_cpu_idle
> feature-removal.txt for 2.6.40 (4 months)
> #warning on CONFIG_APM_CPU_IDLE remove in 2.6.40
> WARN_ONCE in apm_cpu_idle()
> cc: [email protected]
>
> x86 idle: export pm_idle only for CONFIG_APM_MODULE
> like we do for default_idle(),
> EXPORT_SYMBOL(pm_idle) only on CONFIG_APM_MODULE
>
> x86 idle: deprecate "no-hlt" cmdline param
> feature-removal.txt for 2.6.40 (4 months)
> cc [email protected]
> WARN_ONCE if used, ask if idle=poll is sufficient
> same as idle=poll, except no-hlt also disables
> HLT in machine_halt().
>
> x86 idle: deprecate "idle=mwait"
> feature-removal.txt for 2.6.40 (4 months)
> cc [email protected]
> WARN_ONCE on invocation
>
> x86 idle: re-name ce1_idle
> rename for clarity, no functional change
>
> 2.6.40-merge
> ------
> x86 idle: move mwait_idle_with_hints()
> out of process.c to cstate.c, make static
>
> x86 idle floppy: remove deprecated disable_hlt/enable_hlt
>
> x86 idle: delete deprecated idle=mwait
> default_idle() can use HLT
>
> cpuidle: add cmdline "cpuidle=off"
> allow falling back to native default_idle
>
> x86 idle xen: stop touching pm_idle and default_idle
> Xen Dom0 kernel only needs HLT, but include
> CPU_IDLE, ACPI etc for running on bare hardware.
> So when running in Xen Dom0 mode, disable cpuidle
> to fall back to default_idle.
>
> x86 idle APM: remove deprecated apm_cpu_idle()
> and its use of pm_idle
>
> x86 idle cpuidle: delete public use of pm_idle
> make pm_idle and default_idle static to process.c
Hi Len,
I guess this would eliminate the problems caused by pm_idle.
In that case I also think we need not implement a default
driver (like the one I had done https://lkml.org/lkml/2011/3/22/154)
to handle the case when acpi_idle and intel_idle may not register.
Additionally, we may not need to support multiple cpuidle driver
registration as now there would be only acpi_idle and intel_idle
and mechanism already exists to select between the two.
Thanks,
-Trinabh
> add return value from cpu_idle_call()
> invoke cpu_idle_call from cpu_idle() rather than via pm_idle
>
> cpu_idle() {
> ...
> if (cpu_idle_call())
> pm_idle(); /* non cpuidle default */
> }
>
On Thu, Mar 31, 2011 at 02:03:24AM -0400, Len Brown wrote:
> From: Len Brown <[email protected]>
>
> For ACPI mode, mwait_with_hints() in cstate.c is used instead of
> process.c's mwait_idle().
>
> For INTEL_IDLE mode, the mwait in intel_idle() is used instead of
> process.c's mwait_idle().
>
> So delete process.c's mwait_idle().
> This will change the behaviour of SMP sysgtems that are
> running !ACPI and !INTEL_IDLE kernels -- they will use
> HALT instead of MWAIT.
>
> This deletes the "idle=mwait" parameter, and thus the
> boot_option_idle_override == IDLE_FORCE_MWAIT flag.
>
> Signed-off-by: Len Brown <[email protected]>
Acked-by: Andreas Herrmann <[email protected]>
Regards,
Andreas
> I guess this would eliminate the problems caused by pm_idle.
Right.
...at least we can contain it inside process.c
where we still need to be able to handle halt/amd-bug/poll.
Probably I'll re-name it to better reflect its function,
say x86_default_idle, in this case.
> In that case I also think we need not implement a default
> driver (like the one I had done https://lkml.org/lkml/2011/3/22/154)
> to handle the case when acpi_idle and intel_idle may not register.
Right.
the stuff in process.c should handle the !cpuidle
and !CPU_IDLE cases, and in the typical case it will
handle idle during boot before cpuidle initializes.
> Additionally, we may not need to support multiple cpuidle driver registration
> as now there would be only acpi_idle and intel_idle
> and mechanism already exists to select between the two.
Right.
I think multiple driver registration is over-kill, though
I have no real opposition to it should a real need for it emerge.
The only need I could come up with is that it would save me
a reboot when I want to compare drivers -- but we should optimize
for real-world-use, not lab use, and simpler is better.
thanks,
Len Brown, Intel Open Source Technology Center
Thanks for the reviews, tests & Acks -- keep 'em coming!
By the end of this series, pm_idle is removed as a public
x86 idle-loop registration mechanism. A few other things are
cleaned up in the process.
thanks,
Len Brown - Intel Open Source Technology Center
The first 11 are staged here:
git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git idle-release
I would like to see it make 2.6.39, and some for .stable
[PATCH 01/18] cpuidle: menu: fixed wrapping timers at 4.294 seconds
[PATCH 02/18] x86 idle floppy: deprecate disable_hlt()
[PATCH 03/18] x86 idle APM: deprecate CONFIG_APM_CPU_IDLE
[PATCH 04/18] x86 idle: EXPORT_SYMBOL(default_idle, pm_idle) only
[PATCH 05/18] x86 idle: deprecate "no-hlt" cmdline param
[PATCH 06/18] x86 idle: deprecate mwait_idle() and "idle=mwait"
[PATCH 07/18] x86 idle: clarify AMD erratum 400 workaround
[PATCH 08/18] cpuidle: create bootparam "cpuidle.off=1"
[PATCH 09/18] cpuidle: replace xen access to x86 pm_idle and default_idle
[PATCH 10/18] x86 idle: move mwait_idle_with_hints() to where it is used
[PATCH 11/18] cpuidle: stop using pm_idle
Documentation/feature-removal-schedule.txt | 36 +++++++++++++++
Documentation/kernel-parameters.txt | 3 +
arch/arm/kernel/process.c | 4 +-
arch/sh/kernel/idle.c | 6 ++-
arch/x86/include/asm/acpi.h | 2 +-
arch/x86/include/asm/idle.h | 2 +-
arch/x86/include/asm/processor.h | 6 +--
arch/x86/kernel/acpi/cstate.c | 24 ++++++++++
arch/x86/kernel/apm_32.c | 2 +
arch/x86/kernel/cpu/bugs.c | 1 +
arch/x86/kernel/cpu/common.c | 2 +-
arch/x86/kernel/process.c | 66 ++++++++++------------------
arch/x86/kernel/process_32.c | 4 +-
arch/x86/kernel/process_64.c | 4 +-
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/xen/setup.c | 3 +-
drivers/acpi/processor_idle.c | 2 +-
drivers/block/floppy.c | 1 +
drivers/cpuidle/cpuidle.c | 50 +++++++++++++--------
drivers/cpuidle/cpuidle.h | 1 +
drivers/cpuidle/driver.c | 3 +
drivers/cpuidle/governor.c | 3 +
drivers/cpuidle/governors/menu.c | 4 +-
include/linux/cpuidle.h | 4 ++
24 files changed, 157 insertions(+), 78 deletions(-)
The rest are staged here:
git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-idle-2.6.git idle-test
which is a super-set of the above. These will wait for 2.6.40.
[PATCH 12/18] 2.6.40: x86 idle: remove deprecated "no-hlt" cmdline
[PATCH 13/18] 2.6.40: x86 idle: remove deprecated "hlt_bug: no" in
[PATCH 14/18] 2.6.40: x86 idle floppy: remove deprecated disalbe_hlt
[PATCH 15/18] 2.6.40: x86 idle: remove deprecated hlt_use_halt()
[PATCH 16/18] 2.6.40: x86 idle APM: remove deprecated apm_cpu_idle()
[PATCH 17/18] 2.6.40: x86 idle: do not export default_idle() and
[PATCH 18/18] 2.6.40: x86 idle: remove deprecated mwait_idle()
Documentation/feature-removal-schedule.txt | 36 -----
Documentation/kernel-parameters.txt | 11 +--
arch/x86/Kconfig | 11 --
arch/x86/include/asm/processor.h | 12 +--
arch/x86/include/asm/system.h | 9 -
arch/x86/kernel/apm_32.c | 234 ----------------------------
arch/x86/kernel/cpu/bugs.c | 14 +--
arch/x86/kernel/cpu/proc.c | 2 -
arch/x86/kernel/process.c | 109 ++-----------
arch/x86/kernel/setup.c | 4 +-
arch/x86/xen/setup.c | 3 -
drivers/acpi/processor_idle.c | 1 -
drivers/block/floppy.c | 36 -----
13 files changed, 22 insertions(+), 460 deletions(-)
From: Len Brown <[email protected]>
Plan to remove floppy_disable_hlt in 2.6.40, an ancient
workaround with comments that it should be removed.
This allows us to remove clutter and a run-time branch
from the idle code.
WARN_ONCE() on invocation until it is removed.
cc: [email protected]
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 8 ++++++++
drivers/block/floppy.c | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index b3f35e5..54db467 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,6 +6,14 @@ be removed from this file.
---------------------------
+What: x86 floppy disable_hlt
+When: 2.6.40
+Why: ancient workaround of dubious utility clutters the
+ code used by everybody else.
+Who: Len Brown <[email protected]>
+
+---------------------------
+
What: PRISM54
When: 2.6.34
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 77fc76f..41ea03f 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1038,6 +1038,7 @@ static void floppy_disable_hlt(void)
{
unsigned long flags;
+ WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2.6.40");
spin_lock_irqsave(&floppy_hlt_lock, flags);
if (!hlt_disabled) {
hlt_disabled = 1;
--
1.7.5.rc0
From: Len Brown <[email protected]>
In the long run, we don't want default_idle() or (pm_idle)() to
be exported outside of process.c. Start by not exporting them
to modules, unless the APM build demands it.
cc: [email protected]
cc: Jiri Kosina <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/kernel/process.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index ff45541..17b8771 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -340,7 +340,9 @@ EXPORT_SYMBOL(boot_option_idle_override);
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
+#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
EXPORT_SYMBOL(pm_idle);
+#endif
#ifdef CONFIG_X86_32
/*
@@ -400,7 +402,7 @@ void default_idle(void)
cpu_relax();
}
}
-#ifdef CONFIG_APM_MODULE
+#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
EXPORT_SYMBOL(default_idle);
#endif
--
1.7.5.rc0
From: Len Brown <[email protected]>
We'd rather that modern machines not check if HLT works on
every entry into idle, for the benefit of machines that had
marginal electricals 15-years ago. If those machines are still running
the upstream kernel, they can use "idle=poll". The only difference
will be that they'll now invoke HLT in machine_hlt().
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 11 +++++++++++
arch/x86/kernel/cpu/bugs.c | 1 +
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index bab1acb..f587159 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -24,6 +24,17 @@ Who: Len Brown <[email protected]>
----------------------------
+What: x86_32 "no-hlt" cmdline param
+When: 2.6.40
+Why: remove a branch from idle path, simplify code used by everybody.
+ This option disabled the use of HLT in idle and machine_halt()
+ for hardware that was flakey 15-years ago. Today we have
+ "idle=poll" that removed HLT from idle, and so if such a machine
+ is still running the upstream kernel, "idle=poll" is likely sufficient.
+Who: Len Brown <[email protected]>
+
+----------------------------
+
What: PRISM54
When: 2.6.34
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index c39576c..525514c 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -19,6 +19,7 @@
static int __init no_halt(char *s)
{
+ WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n");
boot_cpu_data.hlt_works_ok = 0;
return 1;
}
--
1.7.5.rc0
From: Tero Kristo <[email protected]>
Cpuidle menu governor is using u32 as a temporary datatype for storing
nanosecond values which wrap around at 4.294 seconds. This causes errors
in predicted sleep times resulting in higher than should be C state
selection and increased power consumption. This also breaks cpuidle
state residency statistics.
cc: [email protected]
Signed-off-by: Tero Kristo <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
drivers/cpuidle/governors/menu.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index f508690..c47f3d0 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -237,6 +237,7 @@ static int menu_select(struct cpuidle_device *dev)
unsigned int power_usage = -1;
int i;
int multiplier;
+ struct timespec t;
if (data->needs_update) {
menu_update(dev);
@@ -251,8 +252,9 @@ static int menu_select(struct cpuidle_device *dev)
return 0;
/* determine the expected residency time, round up */
+ t = ktime_to_timespec(tick_nohz_get_sleep_length());
data->expected_us =
- DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000);
+ t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC;
data->bucket = which_bucket(data->expected_us);
--
1.7.5.rc0
From: Len Brown <[email protected]>
When a Xen Dom0 kernel boots on a hypervisor, it gets access
to the raw-hardware ACPI tables. While it parses the idle tables
for the hypervisor's beneift, it uses HLT for its own idle.
Rather than have xen scribble on pm_idle and access default_idle,
have it simply disable_cpuidle() so acpi_idle will not load and
architecture default HLT will be used.
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/xen/setup.c | 3 ++-
drivers/cpuidle/cpuidle.c | 4 ++++
include/linux/cpuidle.h | 2 ++
3 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index a8a66a5..aa02cce 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -9,6 +9,7 @@
#include <linux/mm.h>
#include <linux/pm.h>
#include <linux/memblock.h>
+#include <linux/cpuidle.h>
#include <asm/elf.h>
#include <asm/vdso.h>
@@ -354,7 +355,7 @@ void __init xen_arch_setup(void)
#ifdef CONFIG_X86_32
boot_cpu_data.hlt_works_ok = 1;
#endif
- pm_idle = default_idle;
+ disable_cpuidle();
boot_option_idle_override = IDLE_HALT;
fiddle_vdso();
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index faae2c3..041df0b 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -34,6 +34,10 @@ int cpuidle_disabled(void)
{
return off;
}
+void disable_cpuidle(void)
+{
+ off = 1;
+}
#if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT)
static void cpuidle_kick_cpus(void)
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index 36719ea..b89f67d 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -122,6 +122,7 @@ struct cpuidle_driver {
};
#ifdef CONFIG_CPU_IDLE
+extern void disable_cpuidle(void);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
struct cpuidle_driver *cpuidle_get_driver(void);
@@ -135,6 +136,7 @@ extern int cpuidle_enable_device(struct cpuidle_device *dev);
extern void cpuidle_disable_device(struct cpuidle_device *dev);
#else
+static inline void disable_cpuidle(void) { }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
--
1.7.5.rc0
From: Len Brown <[email protected]>
mwait_idle() is a C1-only idle loop intended to be more efficient
than HLT on SMP hardware that supports it.
But mwait_idle() has been replaced by the more general
mwait_idle_with_hints(), which handles both C1 and deeper C-states.
ACPI uses only mwait_idle_with_hints(), and never uses mwait_idle().
Deprecate mwait_idle() and the "idle=mwait" cmdline param
to simplify the x86 idle code.
After this change, kernels configured with
(!CONFIG_ACPI=n && !CONFIG_INTEL_IDLE=n) when run on hardware
that support MWAIT will simply use HLT. If MWAIT is desired
on those systems, cpuidle and the cpuidle drivers above
will support it.
cc: [email protected]
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 7 +++++++
arch/x86/kernel/process.c | 1 +
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index f587159..9ee4a2c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -35,6 +35,13 @@ Who: Len Brown <[email protected]>
----------------------------
+What: x86 "idle=mwait" cmdline param
+When: 2.6.40
+Why: simplify x86 idle code
+Who: Len Brown <[email protected]>
+
+----------------------------
+
What: PRISM54
When: 2.6.34
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 17b8771..1f64501 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -645,6 +645,7 @@ static int __init idle_setup(char *str)
boot_option_idle_override = IDLE_POLL;
} else if (!strcmp(str, "mwait")) {
boot_option_idle_override = IDLE_FORCE_MWAIT;
+ WARN_ONCE(1, "\idle=mwait\" will be removed in 2.6.40\"\n");
} else if (!strcmp(str, "halt")) {
/*
* When the boot option of idle=halt is added, halt is
--
1.7.5.rc0
From: Len Brown <[email protected]>
useful for disabling cpuidle to fall back
to architecture-default idle loop
cpuidle drivers and governors will fail to register.
on x86 they'll say so:
intel_idle: intel_idle yielding to (null)
ACPI: acpi_idle yielding to (null)
Signed-off-by: Len Brown <[email protected]>
---
Documentation/kernel-parameters.txt | 3 +++
drivers/cpuidle/cpuidle.c | 10 ++++++++++
drivers/cpuidle/cpuidle.h | 1 +
drivers/cpuidle/driver.c | 3 +++
drivers/cpuidle/governor.c | 3 +++
5 files changed, 20 insertions(+), 0 deletions(-)
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f4a04c0..08e8a22 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -546,6 +546,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
/proc/<pid>/coredump_filter.
See also Documentation/filesystems/proc.txt.
+ cpuidle.off=1 [CPU_IDLE]
+ disable the cpuidle sub-system
+
cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver
Format:
<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index bf50924..faae2c3 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -28,6 +28,12 @@ LIST_HEAD(cpuidle_detected_devices);
static void (*pm_idle_old)(void);
static int enabled_devices;
+static int off __read_mostly;
+
+int cpuidle_disabled(void)
+{
+ return off;
+}
#if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT)
static void cpuidle_kick_cpus(void)
@@ -427,6 +433,9 @@ static int __init cpuidle_init(void)
{
int ret;
+ if (cpuidle_disabled())
+ return -ENODEV;
+
pm_idle_old = pm_idle;
ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
@@ -438,4 +447,5 @@ static int __init cpuidle_init(void)
return 0;
}
+module_param(off, int, 0444);
core_initcall(cpuidle_init);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
index 33e50d5..38c3fd8 100644
--- a/drivers/cpuidle/cpuidle.h
+++ b/drivers/cpuidle/cpuidle.h
@@ -13,6 +13,7 @@ extern struct list_head cpuidle_governors;
extern struct list_head cpuidle_detected_devices;
extern struct mutex cpuidle_lock;
extern spinlock_t cpuidle_driver_lock;
+extern int cpuidle_disabled(void);
/* idle loop */
extern void cpuidle_install_idle_handler(void);
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
index fd1601e..3f7e3ce 100644
--- a/drivers/cpuidle/driver.c
+++ b/drivers/cpuidle/driver.c
@@ -26,6 +26,9 @@ int cpuidle_register_driver(struct cpuidle_driver *drv)
if (!drv)
return -EINVAL;
+ if (cpuidle_disabled())
+ return -ENODEV;
+
spin_lock(&cpuidle_driver_lock);
if (cpuidle_curr_driver) {
spin_unlock(&cpuidle_driver_lock);
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
index 724c164..ea2f8e7 100644
--- a/drivers/cpuidle/governor.c
+++ b/drivers/cpuidle/governor.c
@@ -81,6 +81,9 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
if (!gov || !gov->select)
return -EINVAL;
+ if (cpuidle_disabled())
+ return -ENODEV;
+
mutex_lock(&cpuidle_lock);
if (__cpuidle_find_governor(gov->name) == NULL) {
ret = 0;
--
1.7.5.rc0
From: Len Brown <[email protected]>
The workaround for AMD erratum 400 uses the term "c1e" suggesting:
1. All AMD processors with AMD C1E are involved
2. Any Intel processors with Intel C1E are involved.
Both are false.
Replace occurrences if "c1e" with "amd_e400" in the code to
clarify that it is specific to AMD processors with AMD erratum 400.
This patch is text-substitution only, with no functional change.
cc: [email protected]
cc: Hans Rosenfeld <[email protected]>
cc: Andreas Herrmann <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/acpi.h | 2 +-
arch/x86/include/asm/idle.h | 2 +-
arch/x86/include/asm/processor.h | 4 ++--
arch/x86/kernel/cpu/common.c | 2 +-
arch/x86/kernel/process.c | 38 +++++++++++++++++++-------------------
arch/x86/kernel/smpboot.c | 2 +-
drivers/acpi/processor_idle.c | 2 +-
7 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 4ea15ca..ae5bc1a 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -138,7 +138,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
boot_cpu_data.x86_model <= 0x05 &&
boot_cpu_data.x86_mask < 0x0A)
return 1;
- else if (c1e_detected)
+ else if (amd_e400_detected)
return 1;
else
return max_cstate;
diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h
index 38d8737..f49253d7 100644
--- a/arch/x86/include/asm/idle.h
+++ b/arch/x86/include/asm/idle.h
@@ -16,6 +16,6 @@ static inline void enter_idle(void) { }
static inline void exit_idle(void) { }
#endif /* CONFIG_X86_64 */
-void c1e_remove_cpu(int cpu);
+void amd_e400_remove_cpu(int cpu);
#endif /* _ASM_X86_IDLE_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 45636ce..a8c5fed 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -758,10 +758,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
extern void select_idle_routine(const struct cpuinfo_x86 *c);
-extern void init_c1e_mask(void);
+extern void init_amd_e400_mask(void);
extern unsigned long boot_option_idle_override;
-extern bool c1e_detected;
+extern bool amd_e400_detected;
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
IDLE_POLL, IDLE_FORCE_MWAIT};
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1d59834..30ce74c 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -887,7 +887,7 @@ static void vgetcpu_set_mode(void)
void __init identify_boot_cpu(void)
{
identify_cpu(&boot_cpu_data);
- init_c1e_mask();
+ init_amd_e400_mask();
#ifdef CONFIG_X86_32
sysenter_setup();
enable_sep_cpu();
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1f64501..1c45a9c 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -540,45 +540,45 @@ int mwait_usable(const struct cpuinfo_x86 *c)
return (edx & MWAIT_EDX_C1);
}
-bool c1e_detected;
-EXPORT_SYMBOL(c1e_detected);
+bool amd_e400_detected;
+EXPORT_SYMBOL(amd_e400_detected);
-static cpumask_var_t c1e_mask;
+static cpumask_var_t amd_e400_mask;
-void c1e_remove_cpu(int cpu)
+void amd_e400_remove_cpu(int cpu)
{
- if (c1e_mask != NULL)
- cpumask_clear_cpu(cpu, c1e_mask);
+ if (amd_e400_mask != NULL)
+ cpumask_clear_cpu(cpu, amd_e400_mask);
}
/*
- * C1E aware idle routine. We check for C1E active in the interrupt
+ * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt
* pending message MSR. If we detect C1E, then we handle it the same
* way as C3 power states (local apic timer and TSC stop)
*/
-static void c1e_idle(void)
+static void amd_e400_idle(void)
{
if (need_resched())
return;
- if (!c1e_detected) {
+ if (!amd_e400_detected) {
u32 lo, hi;
rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
if (lo & K8_INTP_C1E_ACTIVE_MASK) {
- c1e_detected = true;
+ amd_e400_detected = true;
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
mark_tsc_unstable("TSC halt in AMD C1E");
printk(KERN_INFO "System has AMD C1E enabled\n");
}
}
- if (c1e_detected) {
+ if (amd_e400_detected) {
int cpu = smp_processor_id();
- if (!cpumask_test_cpu(cpu, c1e_mask)) {
- cpumask_set_cpu(cpu, c1e_mask);
+ if (!cpumask_test_cpu(cpu, amd_e400_mask)) {
+ cpumask_set_cpu(cpu, amd_e400_mask);
/*
* Force broadcast so ACPI can not interfere.
*/
@@ -621,17 +621,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
pm_idle = mwait_idle;
} else if (cpu_has_amd_erratum(amd_erratum_400)) {
/* E400: APIC timer interrupt does not wake up CPU from C1e */
- printk(KERN_INFO "using C1E aware idle routine\n");
- pm_idle = c1e_idle;
+ printk(KERN_INFO "using E400 aware idle routine\n");
+ pm_idle = amd_e400_idle;
} else
pm_idle = default_idle;
}
-void __init init_c1e_mask(void)
+void __init init_amd_e400_mask(void)
{
- /* If we're using c1e_idle, we need to allocate c1e_mask. */
- if (pm_idle == c1e_idle)
- zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+ /* If we're using amd_e400_idle, we need to allocate amd_e400_mask. */
+ if (pm_idle == amd_e400_idle)
+ zalloc_cpumask_var(&amd_e400_mask, GFP_KERNEL);
}
static int __init idle_setup(char *str)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 08776a9..2c33633 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1379,7 +1379,7 @@ void play_dead_common(void)
{
idle_task_exit();
reset_lazy_tlbstate();
- c1e_remove_cpu(raw_smp_processor_id());
+ amd_e400_remove_cpu(raw_smp_processor_id());
mb();
/* Ack it */
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index d615b7d..53d9f10 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
return;
- if (c1e_detected)
+ if (amd_e400_detected)
type = ACPI_STATE_C1;
/*
--
1.7.5.rc0
From: Len Brown <[email protected]>
We don't want to export the pm_idle function pointer to modules.
Currently CONFIG_APM_CPU_IDLE w/ CONFIG_APM_MODULE forces us to.
CONFIG_APM_CPU_IDLE is of dubious value, it runs only on 32-bit
uniprocessor laptops that are over 10 years old. It calls into
the BIOS during idle, and is known to cause a number of machines
to fail.
Removing CONFIG_APM_CPU_IDLE and will allow us to stop exporting
pm_idle. Any systems that were calling into the APM BIOS
at run-time will simply use HLT instead.
cc: [email protected]
cc: Jiri Kosina <[email protected]>
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 10 ++++++++++
arch/x86/kernel/apm_32.c | 2 ++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 54db467..bab1acb 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -14,6 +14,16 @@ Who: Len Brown <[email protected]>
---------------------------
+What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
+When: 2.6.40
+Why: This optional sub-feature of APM is of dubious reliability,
+ and ancient APM laptops are likely better served by calling HLT.
+ Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
+ the pm_idle function pointer to modules.
+Who: Len Brown <[email protected]>
+
+----------------------------
+
What: PRISM54
When: 2.6.34
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 0e4f24c..072546c 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -359,6 +359,7 @@ struct apm_user {
* idle percentage above which bios idle calls are done
*/
#ifdef CONFIG_APM_CPU_IDLE
+#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2.6.40
#define DEFAULT_IDLE_THRESHOLD 95
#else
#define DEFAULT_IDLE_THRESHOLD 100
@@ -902,6 +903,7 @@ static void apm_cpu_idle(void)
unsigned int jiffies_since_last_check = jiffies - last_jiffies;
unsigned int bucket;
+ WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2.6.40");
recalc:
if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
use_apm_idle = 0;
--
1.7.5.rc0
From: Len Brown <[email protected]>
There is some doubt whether the APM idle feature
to call into the BIOS from the idle loop is reliable.
Certainly it was known to fail on some machines,
but more importantly, APM machines have not shipped
for a decade and so finding machines to test the code
is problematic.
After this patch, systems running in APM mode will
simply run default_idle() and HALT without calling
into the BIOS from their idle loop.
This deletes modular use use of (pm_idle)() and default_idle().
Acked-by: Ingo Molnar <[email protected]>
Acked-by: Jiri Kosina <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 10 --
arch/x86/Kconfig | 11 --
arch/x86/kernel/apm_32.c | 234 ----------------------------
3 files changed, 0 insertions(+), 255 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index e1e9bf8..9b84b1a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -4,16 +4,6 @@ exactly is going away, why it is happening, and who is going to be doing
the work. When the feature is removed from the kernel, it should also
be removed from this file.
----------------------------
-
-What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
-When: 2.6.40
-Why: This optional sub-feature of APM is of dubious reliability,
- and ancient APM laptops are likely better served by calling HLT.
- Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
- the pm_idle function pointer to modules.
-Who: Len Brown <[email protected]>
-
----------------------------
What: x86 "idle=mwait" cmdline param
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d5ed94d..681bb25 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1809,17 +1809,6 @@ config APM_DO_ENABLE
T400CDT. This is off by default since most machines do fine without
this feature.
-config APM_CPU_IDLE
- bool "Make CPU Idle calls when idle"
- ---help---
- Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
- On some machines, this can activate improved power savings, such as
- a slowed CPU clock rate, when the machine is idle. These idle calls
- are made after the idle loop has run for some length of time (e.g.,
- 333 mS). On some machines, this will cause a hang at boot time or
- whenever the CPU becomes idle. (On machines with more than one CPU,
- this option does nothing.)
-
config APM_DISPLAY_BLANK
bool "Enable console blanking using APM"
---help---
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 072546c..5bc37aa 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -175,8 +175,6 @@
* Ignore first resume after we generate our own resume event
* after a suspend (Thomas Hood)
* Daemonize now gets rid of our controlling terminal (sfr).
- * CONFIG_APM_CPU_IDLE now just affects the default value of
- * idle_threshold (sfr).
* Change name of kernel apm daemon (as it no longer idles) (sfr).
* 1.16ac: Fix up SMP support somewhat. You can now force SMP on and we
* make _all_ APM calls on the CPU#0. Fix unsafe sign bug.
@@ -261,12 +259,6 @@ extern int (*console_blank_hook)(int);
* [no-]smp Use apm even on an SMP box
* bounce[-_]interval=<n> number of ticks to ignore suspend
* bounces
- * idle[-_]threshold=<n> System idle percentage above which to
- * make APM BIOS idle calls. Set it to
- * 100 to disable.
- * idle[-_]period=<n> Period (in 1/100s of a second) over
- * which the idle percentage is
- * calculated.
*/
/* KNOWN PROBLEM MACHINES:
@@ -356,27 +348,12 @@ struct apm_user {
#define APM_BIOS_MAGIC 0x4101
/*
- * idle percentage above which bios idle calls are done
- */
-#ifdef CONFIG_APM_CPU_IDLE
-#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2.6.40
-#define DEFAULT_IDLE_THRESHOLD 95
-#else
-#define DEFAULT_IDLE_THRESHOLD 100
-#endif
-#define DEFAULT_IDLE_PERIOD (100 / 3)
-
-/*
* Local variables
*/
static struct {
unsigned long offset;
unsigned short segment;
} apm_bios_entry;
-static int clock_slowed;
-static int idle_threshold __read_mostly = DEFAULT_IDLE_THRESHOLD;
-static int idle_period __read_mostly = DEFAULT_IDLE_PERIOD;
-static int set_pm_idle;
static int suspends_pending;
static int standbys_pending;
static int ignore_sys_suspend;
@@ -806,166 +783,6 @@ static int set_system_power_state(u_short state)
}
/**
- * apm_do_idle - perform power saving
- *
- * This function notifies the BIOS that the processor is (in the view
- * of the OS) idle. It returns -1 in the event that the BIOS refuses
- * to handle the idle request. On a success the function returns 1
- * if the BIOS did clock slowing or 0 otherwise.
- */
-
-static int apm_do_idle(void)
-{
- u32 eax;
- u8 ret = 0;
- int idled = 0;
- int polling;
- int err = 0;
-
- polling = !!(current_thread_info()->status & TS_POLLING);
- if (polling) {
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
- }
- if (!need_resched()) {
- idled = 1;
- ret = apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax, &err);
- }
- if (polling)
- current_thread_info()->status |= TS_POLLING;
-
- if (!idled)
- return 0;
-
- if (ret) {
- static unsigned long t;
-
- /* This always fails on some SMP boards running UP kernels.
- * Only report the failure the first 5 times.
- */
- if (++t < 5) {
- printk(KERN_DEBUG "apm_do_idle failed (%d)\n", err);
- t = jiffies;
- }
- return -1;
- }
- clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
- return clock_slowed;
-}
-
-/**
- * apm_do_busy - inform the BIOS the CPU is busy
- *
- * Request that the BIOS brings the CPU back to full performance.
- */
-
-static void apm_do_busy(void)
-{
- u32 dummy;
- int err;
-
- if (clock_slowed || ALWAYS_CALL_BUSY) {
- (void)apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy, &err);
- clock_slowed = 0;
- }
-}
-
-/*
- * If no process has really been interested in
- * the CPU for some time, we want to call BIOS
- * power management - we probably want
- * to conserve power.
- */
-#define IDLE_CALC_LIMIT (HZ * 100)
-#define IDLE_LEAKY_MAX 16
-
-static void (*original_pm_idle)(void) __read_mostly;
-
-/**
- * apm_cpu_idle - cpu idling for APM capable Linux
- *
- * This is the idling function the kernel executes when APM is available. It
- * tries to do BIOS powermanagement based on the average system idle time.
- * Furthermore it calls the system default idle routine.
- */
-
-static void apm_cpu_idle(void)
-{
- static int use_apm_idle; /* = 0 */
- static unsigned int last_jiffies; /* = 0 */
- static unsigned int last_stime; /* = 0 */
-
- int apm_idle_done = 0;
- unsigned int jiffies_since_last_check = jiffies - last_jiffies;
- unsigned int bucket;
-
- WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2.6.40");
-recalc:
- if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- } else if (jiffies_since_last_check > idle_period) {
- unsigned int idle_percentage;
-
- idle_percentage = current->stime - last_stime;
- idle_percentage *= 100;
- idle_percentage /= jiffies_since_last_check;
- use_apm_idle = (idle_percentage > idle_threshold);
- if (apm_info.forbid_idle)
- use_apm_idle = 0;
- last_jiffies = jiffies;
- last_stime = current->stime;
- }
-
- bucket = IDLE_LEAKY_MAX;
-
- while (!need_resched()) {
- if (use_apm_idle) {
- unsigned int t;
-
- t = jiffies;
- switch (apm_do_idle()) {
- case 0:
- apm_idle_done = 1;
- if (t != jiffies) {
- if (bucket) {
- bucket = IDLE_LEAKY_MAX;
- continue;
- }
- } else if (bucket) {
- bucket--;
- continue;
- }
- break;
- case 1:
- apm_idle_done = 1;
- break;
- default: /* BIOS refused */
- break;
- }
- }
- if (original_pm_idle)
- original_pm_idle();
- else
- default_idle();
- local_irq_disable();
- jiffies_since_last_check = jiffies - last_jiffies;
- if (jiffies_since_last_check > idle_period)
- goto recalc;
- }
-
- if (apm_idle_done)
- apm_do_busy();
-
- local_irq_enable();
-}
-
-/**
* apm_power_off - ask the BIOS to power off
*
* Handle the power off sequence. This is the one piece of code we
@@ -1883,12 +1700,6 @@ static int __init apm_setup(char *str)
if ((strncmp(str, "bounce-interval=", 16) == 0) ||
(strncmp(str, "bounce_interval=", 16) == 0))
bounce_interval = simple_strtol(str + 16, NULL, 0);
- if ((strncmp(str, "idle-threshold=", 15) == 0) ||
- (strncmp(str, "idle_threshold=", 15) == 0))
- idle_threshold = simple_strtol(str + 15, NULL, 0);
- if ((strncmp(str, "idle-period=", 12) == 0) ||
- (strncmp(str, "idle_period=", 12) == 0))
- idle_period = simple_strtol(str + 12, NULL, 0);
invert = (strncmp(str, "no-", 3) == 0) ||
(strncmp(str, "no_", 3) == 0);
if (invert)
@@ -1900,7 +1711,6 @@ static int __init apm_setup(char *str)
power_off = !invert;
if (strncmp(str, "smp", 3) == 0) {
smp = !invert;
- idle_threshold = 100;
}
if ((strncmp(str, "allow-ints", 10) == 0) ||
(strncmp(str, "allow_ints", 10) == 0))
@@ -2001,17 +1811,6 @@ static int __init apm_is_horked_d850md(const struct dmi_system_id *d)
return 0;
}
-/* Some APM bioses hang on APM idle calls */
-static int __init apm_likes_to_melt(const struct dmi_system_id *d)
-{
- if (apm_info.forbid_idle == 0) {
- apm_info.forbid_idle = 1;
- printk(KERN_INFO "%s machine detected. "
- "Disabling APM idle calls.\n", d->ident);
- }
- return 0;
-}
-
/*
* Check for clue free BIOS implementations who use
* the following QA technique
@@ -2152,16 +1951,6 @@ static struct dmi_system_id __initdata apm_dmi_table[] = {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION, "A11"), },
},
- { /* APM idle hangs */
- apm_likes_to_melt, "Jabil AMD",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
- },
- { /* APM idle hangs */
- apm_likes_to_melt, "AMI Bios",
- { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
- },
{ /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
swab_apm_power_in_minutes, "Sony VAIO",
{ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
@@ -2392,14 +2181,6 @@ static int __init apm_init(void)
if (misc_register(&apm_device))
printk(KERN_WARNING "apm: Could not register misc device.\n");
- if (HZ != 100)
- idle_period = (idle_period * HZ) / 100;
- if (idle_threshold < 100) {
- original_pm_idle = pm_idle;
- pm_idle = apm_cpu_idle;
- set_pm_idle = 1;
- }
-
return 0;
}
@@ -2407,15 +2188,6 @@ static void __exit apm_exit(void)
{
int error;
- if (set_pm_idle) {
- pm_idle = original_pm_idle;
- /*
- * We are about to unload the current idle thread pm callback
- * (pm_idle), Wait for all processors to update cached/local
- * copies of pm_idle before proceeding.
- */
- cpu_idle_wait();
- }
if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
&& (apm_info.connection_version > 0x0100)) {
error = apm_engage_power_management(APM_DEVICE_ALL, 0);
@@ -2453,12 +2225,6 @@ MODULE_PARM_DESC(broken_psr, "BIOS has a broken GetPowerStatus call");
module_param(realmode_power_off, bool, 0444);
MODULE_PARM_DESC(realmode_power_off,
"Switch to real mode before powering off");
-module_param(idle_threshold, int, 0444);
-MODULE_PARM_DESC(idle_threshold,
- "System idle percentage above which to make APM BIOS idle calls");
-module_param(idle_period, int, 0444);
-MODULE_PARM_DESC(idle_period,
- "Period (in sec/100) over which to caculate the idle percentage");
module_param(smp, bool, 0444);
MODULE_PARM_DESC(smp,
"Set this to enable APM use on an SMP platform. Use with caution on older systems");
--
1.7.5.rc0
From: Len Brown <[email protected]>
pm_idle does not scale as an idle handler registration mechanism.
Don't use it for cpuidle. Instead, call cpuidle directly, and
allow architectures to use pm_idle as an arch-specific default
if they need it. ie.
cpu_idle()
...
if(cpuidle_call_idle())
pm_idle();
cc: [email protected]
cc: Kevin Hilman <[email protected]>
cc: Paul Mundt <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
arch/arm/kernel/process.c | 4 +++-
arch/sh/kernel/idle.c | 6 ++++--
arch/x86/kernel/process_32.c | 4 +++-
arch/x86/kernel/process_64.c | 4 +++-
drivers/cpuidle/cpuidle.c | 38 ++++++++++++++++++--------------------
include/linux/cpuidle.h | 2 ++
6 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 94bbedb..dc9d685 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -30,6 +30,7 @@
#include <linux/uaccess.h>
#include <linux/random.h>
#include <linux/hw_breakpoint.h>
+#include <linux/cpuidle.h>
#include <asm/cacheflush.h>
#include <asm/leds.h>
@@ -196,7 +197,8 @@ void cpu_idle(void)
cpu_relax();
} else {
stop_critical_timings();
- pm_idle();
+ if (cpuidle_call_idle())
+ pm_idle();
start_critical_timings();
/*
* This will eventually be removed - pm_idle
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 425d604..9c7099e 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -16,12 +16,13 @@
#include <linux/thread_info.h>
#include <linux/irqflags.h>
#include <linux/smp.h>
+#include <linux/cpuidle.h>
#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/smp.h>
-void (*pm_idle)(void) = NULL;
+static void (*pm_idle)(void);
static int hlt_counter;
@@ -100,7 +101,8 @@ void cpu_idle(void)
local_irq_disable();
/* Don't trace irqs off for idle */
stop_critical_timings();
- pm_idle();
+ if (cpuidle_call_idle())
+ pm_idle();
/*
* Sanity check to ensure that pm_idle() returns
* with IRQs enabled
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 8d12878..61fadbe 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -38,6 +38,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/kdebug.h>
+#include <linux/cpuidle.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -109,7 +110,8 @@ void cpu_idle(void)
local_irq_disable();
/* Don't trace irqs off for idle */
stop_critical_timings();
- pm_idle();
+ if (cpuidle_idle_call())
+ pm_idle();
start_critical_timings();
}
tick_nohz_restart_sched_tick();
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index bd387e8..210641a 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -37,6 +37,7 @@
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/ftrace.h>
+#include <linux/cpuidle.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -136,7 +137,8 @@ void cpu_idle(void)
enter_idle();
/* Don't trace irqs off for idle */
stop_critical_timings();
- pm_idle();
+ if (cpuidle_idle_call())
+ pm_idle();
start_critical_timings();
/* In many cases the interrupt that ended idle
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 041df0b..d4c5423 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -25,10 +25,10 @@ DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
DEFINE_MUTEX(cpuidle_lock);
LIST_HEAD(cpuidle_detected_devices);
-static void (*pm_idle_old)(void);
static int enabled_devices;
static int off __read_mostly;
+static int initialized __read_mostly;
int cpuidle_disabled(void)
{
@@ -56,25 +56,23 @@ static int __cpuidle_register_device(struct cpuidle_device *dev);
* cpuidle_idle_call - the main idle loop
*
* NOTE: no locks or semaphores should be used here
+ * return non-zero on failure
*/
-static void cpuidle_idle_call(void)
+int cpuidle_idle_call(void)
{
struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
struct cpuidle_state *target_state;
int next_state;
+ if (off)
+ return -ENODEV;
+
+ if (!initialized)
+ return -ENODEV;
+
/* check if the device is ready */
- if (!dev || !dev->enabled) {
- if (pm_idle_old)
- pm_idle_old();
- else
-#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE)
- default_idle();
-#else
- local_irq_enable();
-#endif
- return;
- }
+ if (!dev || !dev->enabled)
+ return -EBUSY;
#if 0
/* shows regressions, re-enable for 2.6.29 */
@@ -99,7 +97,7 @@ static void cpuidle_idle_call(void)
next_state = cpuidle_curr_governor->select(dev);
if (need_resched()) {
local_irq_enable();
- return;
+ return 0;
}
target_state = &dev->states[next_state];
@@ -124,6 +122,8 @@ static void cpuidle_idle_call(void)
/* give the governor an opportunity to reflect on the outcome */
if (cpuidle_curr_governor->reflect)
cpuidle_curr_governor->reflect(dev);
+
+ return 0;
}
/**
@@ -131,10 +131,10 @@ static void cpuidle_idle_call(void)
*/
void cpuidle_install_idle_handler(void)
{
- if (enabled_devices && (pm_idle != cpuidle_idle_call)) {
+ if (enabled_devices) {
/* Make sure all changes finished before we switch to new idle */
smp_wmb();
- pm_idle = cpuidle_idle_call;
+ initialized = 1;
}
}
@@ -143,8 +143,8 @@ void cpuidle_install_idle_handler(void)
*/
void cpuidle_uninstall_idle_handler(void)
{
- if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) {
- pm_idle = pm_idle_old;
+ if (enabled_devices) {
+ initialized = 0;
cpuidle_kick_cpus();
}
}
@@ -440,8 +440,6 @@ static int __init cpuidle_init(void)
if (cpuidle_disabled())
return -ENODEV;
- pm_idle_old = pm_idle;
-
ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
if (ret)
return ret;
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
index b89f67d..b51629e 100644
--- a/include/linux/cpuidle.h
+++ b/include/linux/cpuidle.h
@@ -123,6 +123,7 @@ struct cpuidle_driver {
#ifdef CONFIG_CPU_IDLE
extern void disable_cpuidle(void);
+extern int cpuidle_idle_call(void);
extern int cpuidle_register_driver(struct cpuidle_driver *drv);
struct cpuidle_driver *cpuidle_get_driver(void);
@@ -137,6 +138,7 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev);
#else
static inline void disable_cpuidle(void) { }
+static inline int cpuidle_idle_call(void) { return -ENODEV; }
static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
{return -ENODEV; }
--
1.7.5.rc0
From: Len Brown <[email protected]>
With the removal of apm_cpu_idle(), we can now remove
EXPORT_SYMBOL() for both default_idle() and (pm_idle)().
Further, make default_idle() static.
(pm_idle)() is still global b/c it is used by cpu_idle().
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/system.h | 2 --
arch/x86/kernel/process.c | 8 +-------
2 files changed, 1 insertions(+), 9 deletions(-)
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 013dd42..a3379bc 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -338,8 +338,6 @@ void cpu_idle_wait(void);
extern unsigned long arch_align_stack(unsigned long sp);
extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
-void default_idle(void);
-
void stop_this_cpu(void *dummy);
/*
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 53fb569..8daa323 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -340,15 +340,12 @@ EXPORT_SYMBOL(boot_option_idle_override);
* Powermanagement idle function, if any..
*/
void (*pm_idle)(void);
-#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
-EXPORT_SYMBOL(pm_idle);
-#endif
/*
* We use this if we don't have any better
* idle routine..
*/
-void default_idle(void)
+static void default_idle(void)
{
trace_power_start(POWER_CSTATE, 1, smp_processor_id());
trace_cpu_idle(1, smp_processor_id());
@@ -367,9 +364,6 @@ void default_idle(void)
trace_power_end(smp_processor_id());
trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
}
-#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
-EXPORT_SYMBOL(default_idle);
-#endif
void stop_this_cpu(void *dummy)
{
--
1.7.5.rc0
From: Len Brown <[email protected]>
...and make it static
no functional change
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 2 --
arch/x86/kernel/acpi/cstate.c | 24 ++++++++++++++++++++++++
arch/x86/kernel/process.c | 23 -----------------------
3 files changed, 24 insertions(+), 25 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index a8c5fed..fd02787 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -755,8 +755,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
:: "a" (eax), "c" (ecx));
}
-extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
-
extern void select_idle_routine(const struct cpuinfo_x86 *c);
extern void init_amd_e400_mask(void);
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 5812404..c49281e 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -149,6 +149,30 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
}
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
+/*
+ * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
+ * which can obviate IPI to trigger checking of need_resched.
+ * We execute MONITOR against need_resched and enter optimized wait state
+ * through MWAIT. Whenever someone changes need_resched, we would be woken
+ * up from MWAIT (without an IPI).
+ *
+ * New with Core Duo processors, MWAIT can take some hints based on CPU
+ * capability.
+ */
+static void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
+{
+ if (!need_resched()) {
+ if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
+ clflush((void *)¤t_thread_info()->flags);
+
+ __monitor((void *)¤t_thread_info()->flags, 0, 0);
+ smp_mb();
+ if (!need_resched())
+ __mwait(ax, cx);
+ }
+}
+
+
void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
{
unsigned int cpu = smp_processor_id();
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1c45a9c..579c78f 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -441,29 +441,6 @@ void cpu_idle_wait(void)
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
-/*
- * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
- * which can obviate IPI to trigger checking of need_resched.
- * We execute MONITOR against need_resched and enter optimized wait state
- * through MWAIT. Whenever someone changes need_resched, we would be woken
- * up from MWAIT (without an IPI).
- *
- * New with Core Duo processors, MWAIT can take some hints based on CPU
- * capability.
- */
-void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
-{
- if (!need_resched()) {
- if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
- clflush((void *)¤t_thread_info()->flags);
-
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
- smp_mb();
- if (!need_resched())
- __mwait(ax, cx);
- }
-}
-
/* Default MONITOR/MWAIT with no hints, used for default C1 state */
static void mwait_idle(void)
{
--
1.7.5.rc0
From: Len Brown <[email protected]>
The X86_32-only disable_hlt/enable_hlt mechanism was used
by the 32-bit floppy driver. Its effect was to replace
the use of the HLT instruction inside default_idle() with
cpu_relax().
This workaround was commented:
"disable hlt during certain critical i/o operations"
"This halt magic was a workaround for ancient floppy DMA
wreckage. It should be safe to remove."
Remove the workaround to simplify the idle loop.
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 8 ------
arch/x86/include/asm/system.h | 7 -----
arch/x86/kernel/process.c | 24 ------------------
drivers/block/floppy.c | 36 ----------------------------
4 files changed, 0 insertions(+), 75 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 720e698..e1e9bf8 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,14 +6,6 @@ be removed from this file.
---------------------------
-What: x86 floppy disable_hlt
-When: 2.6.40
-Why: ancient workaround of dubious utility clutters the
- code used by everybody else.
-Who: Len Brown <[email protected]>
-
----------------------------
-
What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
When: 2.6.40
Why: This optional sub-feature of APM is of dubious reliability,
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 33ecc3e..013dd42 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -93,10 +93,6 @@ do { \
"memory"); \
} while (0)
-/*
- * disable hlt during certain critical i/o operations
- */
-#define HAVE_DISABLE_HLT
#else
#define __SAVE(reg, offset) "movq %%" #reg ",(14-" #offset ")*8(%%rsp)\n\t"
#define __RESTORE(reg, offset) "movq (14-" #offset ")*8(%%rsp),%%" #reg "\n\t"
@@ -337,9 +333,6 @@ static inline void clflush(volatile void *__p)
#define nop() asm volatile ("nop")
-void disable_hlt(void);
-void enable_hlt(void);
-
void cpu_idle_wait(void);
extern unsigned long arch_align_stack(unsigned long sp);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index c485629..09bd118 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -344,34 +344,10 @@ void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
#endif
-#ifdef CONFIG_X86_32
-/*
- * This halt magic was a workaround for ancient floppy DMA
- * wreckage. It should be safe to remove.
- */
-static int hlt_counter;
-void disable_hlt(void)
-{
- hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
- hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
-static inline int hlt_use_halt(void)
-{
- return !hlt_counter;
-}
-#else
static inline int hlt_use_halt(void)
{
return 1;
}
-#endif
/*
* We use this if we don't have any better
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 41ea03f..9a4e006 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -1032,37 +1032,6 @@ static int fd_wait_for_completion(unsigned long delay, timeout_fn function)
return 0;
}
-static DEFINE_SPINLOCK(floppy_hlt_lock);
-static int hlt_disabled;
-static void floppy_disable_hlt(void)
-{
- unsigned long flags;
-
- WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2.6.40");
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (!hlt_disabled) {
- hlt_disabled = 1;
-#ifdef HAVE_DISABLE_HLT
- disable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
-static void floppy_enable_hlt(void)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&floppy_hlt_lock, flags);
- if (hlt_disabled) {
- hlt_disabled = 0;
-#ifdef HAVE_DISABLE_HLT
- enable_hlt();
-#endif
- }
- spin_unlock_irqrestore(&floppy_hlt_lock, flags);
-}
-
static void setup_DMA(void)
{
unsigned long f;
@@ -1107,7 +1076,6 @@ static void setup_DMA(void)
fd_enable_dma();
release_dma_lock(f);
#endif
- floppy_disable_hlt();
}
static void show_floppy(void);
@@ -1709,7 +1677,6 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id)
fd_disable_dma();
release_dma_lock(f);
- floppy_enable_hlt();
do_floppy = NULL;
if (fdc >= N_FDC || FDCS->address == -1) {
/* we don't even know which FDC is the culprit */
@@ -1858,8 +1825,6 @@ static void floppy_shutdown(unsigned long data)
show_floppy();
cancel_activity();
- floppy_enable_hlt();
-
flags = claim_dma_lock();
fd_disable_dma();
release_dma_lock(flags);
@@ -4504,7 +4469,6 @@ static void floppy_release_irq_and_dma(void)
#if N_FDC > 1
set_dor(1, ~8, 0);
#endif
- floppy_enable_hlt();
if (floppy_track_buffer && max_buffer_sectors) {
tmpsize = max_buffer_sectors * 1024;
--
1.7.5.rc0
From: Len Brown <[email protected]>
The X86_32-only "no-hlt" cmdline option was used to disable
the HLT instruction in the idle loop for the beneift of
systems with flakey power issues 15 years ago.
It would also set the "hlt_bug" line in /proc/cpuinfo
and disable HLT in machine_halt().
If such a system is still running the upstream kernel,
"idle=poll" is available to disable HLT in the idle loop.
The kernel will, however, still use HLT in machine_halt().
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 11 -----------
Documentation/kernel-parameters.txt | 4 ----
arch/x86/kernel/cpu/bugs.c | 9 ---------
3 files changed, 0 insertions(+), 24 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9ee4a2c..720e698 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -24,17 +24,6 @@ Who: Len Brown <[email protected]>
----------------------------
-What: x86_32 "no-hlt" cmdline param
-When: 2.6.40
-Why: remove a branch from idle path, simplify code used by everybody.
- This option disabled the use of HLT in idle and machine_halt()
- for hardware that was flakey 15-years ago. Today we have
- "idle=poll" that removed HLT from idle, and so if such a machine
- is still running the upstream kernel, "idle=poll" is likely sufficient.
-Who: Len Brown <[email protected]>
-
-----------------------------
-
What: x86 "idle=mwait" cmdline param
When: 2.6.40
Why: simplify x86 idle code
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 08e8a22..a9db94e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1669,10 +1669,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
wfi(ARM) instruction doesn't work correctly and not to
use it. This is also useful when using JTAG debugger.
- no-hlt [BUGS=X86-32] Tells the kernel that the hlt
- instruction doesn't work correctly and not to
- use it.
-
no_file_caps Tells the kernel not to honor file capabilities. The
only way then for a file to be executed with privilege
is to be setuid root or executed by root.
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 525514c..4c91631 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -17,15 +17,6 @@
#include <asm/paravirt.h>
#include <asm/alternative.h>
-static int __init no_halt(char *s)
-{
- WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n");
- boot_cpu_data.hlt_works_ok = 0;
- return 1;
-}
-
-__setup("no-hlt", no_halt);
-
static int __init no_387(char *s)
{
boot_cpu_data.hard_math = 0;
--
1.7.5.rc0
From: Len Brown <[email protected]>
For ACPI mode, mwait_with_hints() in cstate.c is used instead of
mwait_idle().
For INTEL_IDLE mode, the mwait in intel_idle() is used instead of
mwait_idle().
So mwait_idle() is used only on hardware that supports MWAIT,
but is running a !ACPI && !INTEL_IDLE kernel.
Such a system will run HLT instead of MWAIT after this change.
cc: [email protected]
Acked-by: Andreas Herrmann <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
Documentation/feature-removal-schedule.txt | 7 -----
Documentation/kernel-parameters.txt | 7 +----
arch/x86/include/asm/processor.h | 2 +-
arch/x86/kernel/process.c | 35 +---------------------------
drivers/acpi/processor_idle.c | 1 -
5 files changed, 3 insertions(+), 49 deletions(-)
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 9b84b1a..f55ba2c 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -6,13 +6,6 @@ be removed from this file.
----------------------------
-What: x86 "idle=mwait" cmdline param
-When: 2.6.40
-Why: simplify x86 idle code
-Who: Len Brown <[email protected]>
-
-----------------------------
-
What: PRISM54
When: 2.6.34
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a9db94e..52c956a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -920,16 +920,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Claim all unknown PCI IDE storage controllers.
idle= [X86]
- Format: idle=poll, idle=mwait, idle=halt, idle=nomwait
+ Format: idle=poll, idle=halt, idle=nomwait
Poll forces a polling idle loop that can slightly
improve the performance of waking up a idle CPU, but
will use a lot of power and make the system run hot.
Not recommended.
- idle=mwait: On systems which support MONITOR/MWAIT but
- the kernel chose to not use it because it doesn't save
- as much power as a normal idle loop, use the
- MONITOR/MWAIT idle loop anyways. Performance should be
- the same as idle=poll.
idle=halt: Halt is forced to be used for CPU idle.
In such case C2/C3 won't be used again.
idle=nomwait: Disable mwait for CPU C-states
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 10cdee8..3424009 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -752,7 +752,7 @@ extern unsigned long boot_option_idle_override;
extern bool amd_e400_detected;
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
- IDLE_POLL, IDLE_FORCE_MWAIT};
+ IDLE_POLL};
extern void enable_sep_cpu(void);
extern int sysenter_setup(void);
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 8daa323..4ab4bba 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -399,27 +399,6 @@ void cpu_idle_wait(void)
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
-/* Default MONITOR/MWAIT with no hints, used for default C1 state */
-static void mwait_idle(void)
-{
- if (!need_resched()) {
- trace_power_start(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle(1, smp_processor_id());
- if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
- clflush((void *)¤t_thread_info()->flags);
-
- __monitor((void *)¤t_thread_info()->flags, 0, 0);
- smp_mb();
- if (!need_resched())
- __sti_mwait(0, 0);
- else
- local_irq_enable();
- trace_power_end(smp_processor_id());
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
- } else
- local_irq_enable();
-}
-
/*
* On SMP it's slightly faster (but much more power-consuming!)
* to poll the ->work.need_resched flag instead of waiting for the
@@ -457,9 +436,6 @@ int mwait_usable(const struct cpuinfo_x86 *c)
{
u32 eax, ebx, ecx, edx;
- if (boot_option_idle_override == IDLE_FORCE_MWAIT)
- return 1;
-
if (c->cpuid_level < MWAIT_INFO)
return 0;
@@ -548,13 +524,7 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
if (pm_idle)
return;
- if (cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)) {
- /*
- * One CPU supports mwait => All CPUs supports mwait
- */
- printk(KERN_INFO "using mwait in idle threads.\n");
- pm_idle = mwait_idle;
- } else if (cpu_has_amd_erratum(amd_erratum_400)) {
+ if (cpu_has_amd_erratum(amd_erratum_400)) {
/* E400: APIC timer interrupt does not wake up CPU from C1e */
printk(KERN_INFO "using E400 aware idle routine\n");
pm_idle = amd_e400_idle;
@@ -578,9 +548,6 @@ static int __init idle_setup(char *str)
printk("using polling idle threads.\n");
pm_idle = poll_idle;
boot_option_idle_override = IDLE_POLL;
- } else if (!strcmp(str, "mwait")) {
- boot_option_idle_override = IDLE_FORCE_MWAIT;
- WARN_ONCE(1, "\idle=mwait\" will be removed in 2.6.40\"\n");
} else if (!strcmp(str, "halt")) {
/*
* When the boot option of idle=halt is added, halt is
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 53d9f10..954a9d3 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -82,7 +82,6 @@ module_param(latency_factor, uint, 0644);
static int disabled_by_idle_boot_param(void)
{
return boot_option_idle_override == IDLE_POLL ||
- boot_option_idle_override == IDLE_FORCE_MWAIT ||
boot_option_idle_override == IDLE_HALT;
}
--
1.7.5.rc0
From: Len Brown <[email protected]>
Now that the "no-hlt" cmdline param is gone...
cpuinfo_x86.hlt_works_ok, halt_works() and the
"hlt_bug: no" line in 32-bit /proc/cpuinfo are NOPS.
remove them.
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/processor.h | 10 ----------
arch/x86/kernel/cpu/bugs.c | 5 +----
arch/x86/kernel/cpu/proc.c | 2 --
arch/x86/kernel/process.c | 5 ++---
arch/x86/kernel/setup.c | 4 ++--
arch/x86/xen/setup.c | 3 ---
6 files changed, 5 insertions(+), 24 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index fd02787..10cdee8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -67,7 +67,6 @@ struct cpuinfo_x86 {
char wp_works_ok; /* It doesn't on 386's */
/* Problems on some 486Dx4's and old 386's: */
- char hlt_works_ok;
char hard_math;
char rfu;
char fdiv_bug;
@@ -148,15 +147,6 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
extern const struct seq_operations cpuinfo_op;
-static inline int hlt_works(int cpu)
-{
-#ifdef CONFIG_X86_32
- return cpu_data(cpu).hlt_works_ok;
-#else
- return 1;
-#endif
-}
-
#define cache_line_size() (boot_cpu_data.x86_cache_alignment)
extern void cpu_detect(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 4c91631..b5e2910 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -82,10 +82,7 @@ static void __init check_hlt(void)
return;
printk(KERN_INFO "Checking 'hlt' instruction... ");
- if (!boot_cpu_data.hlt_works_ok) {
- printk("disabled\n");
- return;
- }
+
halt();
halt();
halt();
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 62ac8cb..203feb7 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -33,7 +33,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu);
seq_printf(m,
"fdiv_bug\t: %s\n"
- "hlt_bug\t\t: %s\n"
"f00f_bug\t: %s\n"
"coma_bug\t: %s\n"
"fpu\t\t: %s\n"
@@ -41,7 +40,6 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c)
"cpuid level\t: %d\n"
"wp\t\t: %s\n",
c->fdiv_bug ? "yes" : "no",
- c->hlt_works_ok ? "no" : "yes",
c->f00f_bug ? "yes" : "no",
c->coma_bug ? "yes" : "no",
c->hard_math ? "yes" : "no",
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 579c78f..c485629 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -364,7 +364,7 @@ EXPORT_SYMBOL(enable_hlt);
static inline int hlt_use_halt(void)
{
- return (!hlt_counter && boot_cpu_data.hlt_works_ok);
+ return !hlt_counter;
}
#else
static inline int hlt_use_halt(void)
@@ -416,8 +416,7 @@ void stop_this_cpu(void *dummy)
disable_local_APIC();
for (;;) {
- if (hlt_works(smp_processor_id()))
- halt();
+ halt();
}
}
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index d3cfe26..fab5631 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -175,9 +175,9 @@ static struct resource bss_resource = {
#ifdef CONFIG_X86_32
/* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 0, 0, -1};
/* common cpu data for all cpus */
-struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1};
+struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 0, 0, -1};
EXPORT_SYMBOL(boot_cpu_data);
static void set_mca_bus(int x)
{
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index aa02cce..32069fb 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -352,9 +352,6 @@ void __init xen_arch_setup(void)
COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE);
/* Set up idle, making sure it calls safe_halt() pvop */
-#ifdef CONFIG_X86_32
- boot_cpu_data.hlt_works_ok = 1;
-#endif
disable_cpuidle();
boot_option_idle_override = IDLE_HALT;
--
1.7.5.rc0
From: Len Brown <[email protected]>
Removing the floppy workaround made hlt_use_halt() constant.
So we can now remove it, and we no longer need to test it
in default_idle().
no functional change.
cc: [email protected]
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/kernel/process.c | 39 ++++++++++++++-------------------------
1 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 09bd118..53fb569 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -344,39 +344,28 @@ void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);
#endif
-static inline int hlt_use_halt(void)
-{
- return 1;
-}
-
/*
* We use this if we don't have any better
* idle routine..
*/
void default_idle(void)
{
- if (hlt_use_halt()) {
- trace_power_start(POWER_CSTATE, 1, smp_processor_id());
- trace_cpu_idle(1, smp_processor_id());
- current_thread_info()->status &= ~TS_POLLING;
- /*
- * TS_POLLING-cleared state must be visible before we
- * test NEED_RESCHED:
- */
- smp_mb();
+ trace_power_start(POWER_CSTATE, 1, smp_processor_id());
+ trace_cpu_idle(1, smp_processor_id());
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
- if (!need_resched())
- safe_halt(); /* enables interrupts racelessly */
- else
- local_irq_enable();
- current_thread_info()->status |= TS_POLLING;
- trace_power_end(smp_processor_id());
- trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
- } else {
+ if (!need_resched())
+ safe_halt(); /* enables interrupts racelessly */
+ else
local_irq_enable();
- /* loop is done by the caller */
- cpu_relax();
- }
+ current_thread_info()->status |= TS_POLLING;
+ trace_power_end(smp_processor_id());
+ trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());
}
#if defined(CONFIG_APM_MODULE) && defined(CONFIG_APM_CPU_IDLE)
EXPORT_SYMBOL(default_idle);
--
1.7.5.rc0
On Sat, Apr 02, 2011 at 02:22:49AM -0400, Len Brown wrote:
> From: Len Brown <[email protected]>
>
> The workaround for AMD erratum 400 uses the term "c1e" suggesting:
> 1. All AMD processors with AMD C1E are involved
> 2. Any Intel processors with Intel C1E are involved.
>
> Both are false.
>
> Replace occurrences if "c1e" with "amd_e400" in the code to
> clarify that it is specific to AMD processors with AMD erratum 400.
>
> This patch is text-substitution only, with no functional change.
>
> cc: [email protected]
> cc: Hans Rosenfeld <[email protected]>
> cc: Andreas Herrmann <[email protected]>
> Signed-off-by: Len Brown <[email protected]>
> ---
> arch/x86/include/asm/acpi.h | 2 +-
> arch/x86/include/asm/idle.h | 2 +-
> arch/x86/include/asm/processor.h | 4 ++--
> arch/x86/kernel/cpu/common.c | 2 +-
> arch/x86/kernel/process.c | 38 +++++++++++++++++++-------------------
> arch/x86/kernel/smpboot.c | 2 +-
> drivers/acpi/processor_idle.c | 2 +-
> 7 files changed, 26 insertions(+), 26 deletions(-)
>
> diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
> index 4ea15ca..ae5bc1a 100644
> --- a/arch/x86/include/asm/acpi.h
> +++ b/arch/x86/include/asm/acpi.h
> @@ -138,7 +138,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
> boot_cpu_data.x86_model <= 0x05 &&
> boot_cpu_data.x86_mask < 0x0A)
> return 1;
> - else if (c1e_detected)
> + else if (amd_e400_detected)
> return 1;
> else
> return max_cstate;
> diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h
> index 38d8737..f49253d7 100644
> --- a/arch/x86/include/asm/idle.h
> +++ b/arch/x86/include/asm/idle.h
> @@ -16,6 +16,6 @@ static inline void enter_idle(void) { }
> static inline void exit_idle(void) { }
> #endif /* CONFIG_X86_64 */
>
> -void c1e_remove_cpu(int cpu);
> +void amd_e400_remove_cpu(int cpu);
>
> #endif /* _ASM_X86_IDLE_H */
> diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
> index 45636ce..a8c5fed 100644
> --- a/arch/x86/include/asm/processor.h
> +++ b/arch/x86/include/asm/processor.h
> @@ -758,10 +758,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
> extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
>
> extern void select_idle_routine(const struct cpuinfo_x86 *c);
> -extern void init_c1e_mask(void);
> +extern void init_amd_e400_mask(void);
>
> extern unsigned long boot_option_idle_override;
> -extern bool c1e_detected;
> +extern bool amd_e400_detected;
>
> enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
> IDLE_POLL, IDLE_FORCE_MWAIT};
> diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
> index 1d59834..30ce74c 100644
> --- a/arch/x86/kernel/cpu/common.c
> +++ b/arch/x86/kernel/cpu/common.c
> @@ -887,7 +887,7 @@ static void vgetcpu_set_mode(void)
> void __init identify_boot_cpu(void)
> {
> identify_cpu(&boot_cpu_data);
> - init_c1e_mask();
> + init_amd_e400_mask();
> #ifdef CONFIG_X86_32
> sysenter_setup();
> enable_sep_cpu();
> diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
> index 1f64501..1c45a9c 100644
> --- a/arch/x86/kernel/process.c
> +++ b/arch/x86/kernel/process.c
> @@ -540,45 +540,45 @@ int mwait_usable(const struct cpuinfo_x86 *c)
> return (edx & MWAIT_EDX_C1);
> }
>
> -bool c1e_detected;
> -EXPORT_SYMBOL(c1e_detected);
> +bool amd_e400_detected;
> +EXPORT_SYMBOL(amd_e400_detected);
>
> -static cpumask_var_t c1e_mask;
> +static cpumask_var_t amd_e400_mask;
Actually, the correct name should be IMHO
amd_e400_c1e_mask
>
> -void c1e_remove_cpu(int cpu)
> +void amd_e400_remove_cpu(int cpu)
> {
> - if (c1e_mask != NULL)
> - cpumask_clear_cpu(cpu, c1e_mask);
> + if (amd_e400_mask != NULL)
> + cpumask_clear_cpu(cpu, amd_e400_mask);
> }
>
> /*
> - * C1E aware idle routine. We check for C1E active in the interrupt
> + * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt
> * pending message MSR. If we detect C1E, then we handle it the same
> * way as C3 power states (local apic timer and TSC stop)
> */
> -static void c1e_idle(void)
> +static void amd_e400_idle(void)
> {
> if (need_resched())
> return;
>
> - if (!c1e_detected) {
> + if (!amd_e400_detected) {
> u32 lo, hi;
>
> rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
>
> if (lo & K8_INTP_C1E_ACTIVE_MASK) {
> - c1e_detected = true;
> + amd_e400_detected = true;
Hmm, c1e_detected is still the correct name since those two bits in
the INT_PENDING MSR mean simply that the system can either generate an
IO read or an SMI to enter C1E irrespective of E400. So I'd leave it
c1e_detected.
The function name amd_e400_idle() OTOH looks fine to me since we denote
that this is a special idle routine for CPUs affected by E400.
> if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
> mark_tsc_unstable("TSC halt in AMD C1E");
> printk(KERN_INFO "System has AMD C1E enabled\n");
> }
> }
>
> - if (c1e_detected) {
> + if (amd_e400_detected) {
> int cpu = smp_processor_id();
>
> - if (!cpumask_test_cpu(cpu, c1e_mask)) {
> - cpumask_set_cpu(cpu, c1e_mask);
> + if (!cpumask_test_cpu(cpu, amd_e400_mask)) {
> + cpumask_set_cpu(cpu, amd_e400_mask);
> /*
> * Force broadcast so ACPI can not interfere.
> */
> @@ -621,17 +621,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
> pm_idle = mwait_idle;
> } else if (cpu_has_amd_erratum(amd_erratum_400)) {
> /* E400: APIC timer interrupt does not wake up CPU from C1e */
> - printk(KERN_INFO "using C1E aware idle routine\n");
> - pm_idle = c1e_idle;
> + printk(KERN_INFO "using E400 aware idle routine\n");
> + pm_idle = amd_e400_idle;
> } else
> pm_idle = default_idle;
> }
>
> -void __init init_c1e_mask(void)
> +void __init init_amd_e400_mask(void)
Same here, init_amd_e400_c1e_mask.
> {
> - /* If we're using c1e_idle, we need to allocate c1e_mask. */
> - if (pm_idle == c1e_idle)
> - zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
> + /* If we're using amd_e400_idle, we need to allocate amd_e400_mask. */
> + if (pm_idle == amd_e400_idle)
> + zalloc_cpumask_var(&amd_e400_mask, GFP_KERNEL);
> }
>
> static int __init idle_setup(char *str)
> diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
> index 08776a9..2c33633 100644
> --- a/arch/x86/kernel/smpboot.c
> +++ b/arch/x86/kernel/smpboot.c
> @@ -1379,7 +1379,7 @@ void play_dead_common(void)
> {
> idle_task_exit();
> reset_lazy_tlbstate();
> - c1e_remove_cpu(raw_smp_processor_id());
> + amd_e400_remove_cpu(raw_smp_processor_id());
>
> mb();
> /* Ack it */
> diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
> index d615b7d..53d9f10 100644
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
> if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
> return;
>
> - if (c1e_detected)
> + if (amd_e400_detected)
> type = ACPI_STATE_C1;
>
> /*
> --
> 1.7.5.rc0
Thanks.
--
Regards/Gruss,
Boris.
> We don't want to export the pm_idle function pointer to modules.
> Currently CONFIG_APM_CPU_IDLE w/ CONFIG_APM_MODULE forces us to.
So you could jsut compile it in ...
> CONFIG_APM_CPU_IDLE is of dubious value, it runs only on 32-bit
> uniprocessor laptops that are over 10 years old. It calls into
> the BIOS during idle, and is known to cause a number of machines
> to fail.
It also works on lots of desktops from that era, more of which are still
around.
>
> Removing CONFIG_APM_CPU_IDLE and will allow us to stop exporting
> pm_idle. Any systems that were calling into the APM BIOS
> at run-time will simply use HLT instead.
(which is btw what quite a few later APM implementations seem to do ;))
> +What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
> +When: 2.6.40
One release isn't enough time - it won't propagate out - you keep
rushing, hurrying and pushing at this trying to do it fast.
Why - its a sigle symbol export of minor ugliness, it doesn't justify the
amount of hatred you are expending upon it.
Give it a year, it doesn't cause any complexities I can see.
On Sat, 02 Apr 2011 02:22:46 -0400
Len Brown <[email protected]> wrote:
> From: Len Brown <[email protected]>
>
> In the long run, we don't want default_idle() or (pm_idle)() to
> be exported outside of process.c. Start by not exporting them
> to modules, unless the APM build demands it.
Pointless added complexity. Why are you so determined to minimise this -
it makes no odds to anyone.
On Sat, 02 Apr 2011 02:22:58 -0400
Len Brown <[email protected]> wrote:
> From: Len Brown <[email protected]>
>
> There is some doubt whether the APM idle feature
> to call into the BIOS from the idle loop is reliable.
> Certainly it was known to fail on some machines,
And it was known to work on lots - a point that despite repeated
reminding you seem keen to ignore.
The fundamental problem I have with this patch set is this
You've provided no architectural overall justification for all this
effort. What is the big picture around your crusade here ? What is the
grand plan ?
> but more importantly, APM machines have not shipped
> for a decade and so finding machines to test the code
> is problematic.
So don't test it - if it's wrong someone will let you know, believe me 8)
And 2.6.40 is far too soon - it takes about a year for stuff to rattle
through to leading edge distro users in bulk
Alan
On 04/02/2011 04:58 PM, Alan Cox wrote:
> On Sat, 02 Apr 2011 02:22:46 -0400
> Len Brown<[email protected]> wrote:
>
>> From: Len Brown<[email protected]>
>>
>> In the long run, we don't want default_idle() or (pm_idle)() to
>> be exported outside of process.c. Start by not exporting them
>> to modules, unless the APM build demands it.
>
> Pointless added complexity. Why are you so determined to minimise this -
> it makes no odds to anyone.
Hi Alan,
I am not sure if I have understood you correctly but
I think one problem is that modules such as APM
save the value of pm_idle pointer, set it and restore it back.
At module init:
original_pm_idle = pm_idle;
pm_idle = apm_cpu_idle;
At module exit:
pm_idle = original_pm_idle;
There is no guarantee that the pointer stored
is still valid. I think people have problem with such
usage; see http://lkml.org/lkml/2009/8/28/50
Thanks,
-Trinabh
> Give it a year, it doesn't cause any complexities I can see.
I'd rather not create a new an APM cpuilde driver,
since there is nobody volunteering to test it.
If you have the time and the hardware, please speak up.
thanks,
-Len Brown, Intel Open Source Technolgy Center
> > -static cpumask_var_t c1e_mask;
> > +static cpumask_var_t amd_e400_mask;
>
> Actually, the correct name should be IMHO
>
> amd_e400_c1e_mask
okay.
> > - c1e_detected = true;
> > + amd_e400_detected = true;
>
> Hmm, c1e_detected is still the correct name since those two bits in
> the INT_PENDING MSR mean simply that the system can either generate an
> IO read or an SMI to enter C1E irrespective of E400. So I'd leave it
> c1e_detected.
We don't run the code that sets this flag unless
cpu_has_amd_erratum(amd_erratum_400)
so how about this?:
- c1e_detected
+ amd_e400_c1e_detected
> > -void __init init_c1e_mask(void)
> > +void __init init_amd_e400_mask(void)
>
> Same here, init_amd_e400_c1e_mask.
done.
thanks,
Len Brown, Intel Open Source Technology Center
From: Len Brown <[email protected]>
The workaround for AMD erratum 400 uses the term "c1e" falsely suggesting:
1. Intel C1E is somehow involved
2. All AMD processors with C1E are involved
Use the string "amd_c1e" instead of simply "c1e" to clarify that
this workaround is specific to AMD's version of C1E.
Use the string "e400" to clarify that the workaround is specific
to AMD processors with Erratum 400.
This patch is text-substitution only, with no functional change.
cc: [email protected]
cc: Hans Rosenfeld <[email protected]>
cc: Andreas Herrmann <[email protected]>
Signed-off-by: Len Brown <[email protected]>
---
arch/x86/include/asm/acpi.h | 2 +-
arch/x86/include/asm/idle.h | 2 +-
arch/x86/include/asm/processor.h | 4 ++--
arch/x86/kernel/cpu/common.c | 2 +-
arch/x86/kernel/process.c | 38 +++++++++++++++++++-------------------
arch/x86/kernel/smpboot.c | 2 +-
drivers/acpi/processor_idle.c | 2 +-
7 files changed, 26 insertions(+), 26 deletions(-)
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 4ea15ca..52fd57f 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -138,7 +138,7 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
boot_cpu_data.x86_model <= 0x05 &&
boot_cpu_data.x86_mask < 0x0A)
return 1;
- else if (c1e_detected)
+ else if (amd_e400_c1e_detected)
return 1;
else
return max_cstate;
diff --git a/arch/x86/include/asm/idle.h b/arch/x86/include/asm/idle.h
index 38d8737..f49253d7 100644
--- a/arch/x86/include/asm/idle.h
+++ b/arch/x86/include/asm/idle.h
@@ -16,6 +16,6 @@ static inline void enter_idle(void) { }
static inline void exit_idle(void) { }
#endif /* CONFIG_X86_64 */
-void c1e_remove_cpu(int cpu);
+void amd_e400_remove_cpu(int cpu);
#endif /* _ASM_X86_IDLE_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 45636ce..03d38f7 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -758,10 +758,10 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
extern void select_idle_routine(const struct cpuinfo_x86 *c);
-extern void init_c1e_mask(void);
+extern void init_amd_e400_mask(void);
extern unsigned long boot_option_idle_override;
-extern bool c1e_detected;
+extern bool amd_e400_c1e_detected;
enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
IDLE_POLL, IDLE_FORCE_MWAIT};
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 1d59834..30ce74c 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -887,7 +887,7 @@ static void vgetcpu_set_mode(void)
void __init identify_boot_cpu(void)
{
identify_cpu(&boot_cpu_data);
- init_c1e_mask();
+ init_amd_e400_mask();
#ifdef CONFIG_X86_32
sysenter_setup();
enable_sep_cpu();
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 1f64501..38b3f5d 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -540,45 +540,45 @@ int mwait_usable(const struct cpuinfo_x86 *c)
return (edx & MWAIT_EDX_C1);
}
-bool c1e_detected;
-EXPORT_SYMBOL(c1e_detected);
+bool amd_e400_c1e_detected;
+EXPORT_SYMBOL(amd_e400_c1e_detected);
-static cpumask_var_t c1e_mask;
+static cpumask_var_t amd_e400_c1e_mask;
-void c1e_remove_cpu(int cpu)
+void amd_e400_remove_cpu(int cpu)
{
- if (c1e_mask != NULL)
- cpumask_clear_cpu(cpu, c1e_mask);
+ if (amd_e400_c1e_mask != NULL)
+ cpumask_clear_cpu(cpu, amd_e400_c1e_mask);
}
/*
- * C1E aware idle routine. We check for C1E active in the interrupt
+ * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt
* pending message MSR. If we detect C1E, then we handle it the same
* way as C3 power states (local apic timer and TSC stop)
*/
-static void c1e_idle(void)
+static void amd_e400_idle(void)
{
if (need_resched())
return;
- if (!c1e_detected) {
+ if (!amd_e400_c1e_detected) {
u32 lo, hi;
rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
if (lo & K8_INTP_C1E_ACTIVE_MASK) {
- c1e_detected = true;
+ amd_e400_c1e_detected = true;
if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
mark_tsc_unstable("TSC halt in AMD C1E");
printk(KERN_INFO "System has AMD C1E enabled\n");
}
}
- if (c1e_detected) {
+ if (amd_e400_c1e_detected) {
int cpu = smp_processor_id();
- if (!cpumask_test_cpu(cpu, c1e_mask)) {
- cpumask_set_cpu(cpu, c1e_mask);
+ if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
+ cpumask_set_cpu(cpu, amd_e400_c1e_mask);
/*
* Force broadcast so ACPI can not interfere.
*/
@@ -621,17 +621,17 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
pm_idle = mwait_idle;
} else if (cpu_has_amd_erratum(amd_erratum_400)) {
/* E400: APIC timer interrupt does not wake up CPU from C1e */
- printk(KERN_INFO "using C1E aware idle routine\n");
- pm_idle = c1e_idle;
+ printk(KERN_INFO "using AMD E400 aware idle routine\n");
+ pm_idle = amd_e400_idle;
} else
pm_idle = default_idle;
}
-void __init init_c1e_mask(void)
+void __init init_amd_e400_c1e_mask(void)
{
- /* If we're using c1e_idle, we need to allocate c1e_mask. */
- if (pm_idle == c1e_idle)
- zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+ /* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */
+ if (pm_idle == amd_e400_idle)
+ zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL);
}
static int __init idle_setup(char *str)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 08776a9..2c33633 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1379,7 +1379,7 @@ void play_dead_common(void)
{
idle_task_exit();
reset_lazy_tlbstate();
- c1e_remove_cpu(raw_smp_processor_id());
+ amd_e400_remove_cpu(raw_smp_processor_id());
mb();
/* Ack it */
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index d615b7d..431ab11 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -161,7 +161,7 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,
if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
return;
- if (c1e_detected)
+ if (amd_e400_c1e_detected)
type = ACPI_STATE_C1;
/*
--
1.7.5.rc0
On Sat, 02 Apr 2011 14:28:31 -0400 (EDT)
Len Brown <[email protected]> wrote:
> > Give it a year, it doesn't cause any complexities I can see.
>
> I'd rather not create a new an APM cpuilde driver
In which case don't remove the existing one - as far as bugzilla shows it
seems to be working fine.
> > There is some doubt whether the APM idle feature
> > to call into the BIOS from the idle loop is reliable.
> > Certainly it was known to fail on some machines,
>
> And it was known to work on lots - a point that despite repeated
> reminding you seem keen to ignore.
>
> The fundamental problem I have with this patch set is this
>
> You've provided no architectural overall justification for all this
> effort. What is the big picture around your crusade here ? What is the
> grand plan ?
This patch series was posted in reply to a table of contents
https://lkml.org/lkml/2011/4/2/8
"By the end of this series, pm_idle is removed as a public
x86 idle-loop registration mechanism. A few other things are
cleaned up in the process."
I labeled it "idle cleanup - v3" -- I'm sorry if it went un-noticed
because I neglected to put the [PATCH 0/18] on it.
Trinabh also replied to you, pointing one of the previous
LKML discussions about the mis-use of pm_idle.
> > but more importantly, APM machines have not shipped
> > for a decade and so finding machines to test the code
> > is problematic.
>
> So don't test it - if it's wrong someone will let you know, believe me 8)
>
> And 2.6.40 is far too soon - it takes about a year for stuff to rattle
> through to leading edge distro users in bulk
If you insist.
We'll create a new APM cpuidle driver in Linux (Trinabh prototyped one),
and at the same time, schedule it for removal in a year. Personally,
I think it is make-work, and in real-life it is more likely to do
more harm than removing apm_idle, but I don't want to stand in the
way of process.
thanks,
-Len
> This patch series was posted in reply to a table of contents
>
> https://lkml.org/lkml/2011/4/2/8
>
> "By the end of this series, pm_idle is removed as a public
> x86 idle-loop registration mechanism. A few other things are
> cleaned up in the process."
Ok so lets rewind a bit - why do we want to remove pm_idle rather than
just fix up the way registration occurs. It's just a symbol, one trivial
interface that is exported and perhaps wants the export method tidying up.
> Trinabh also replied to you, pointing one of the previous
> LKML discussions about the mis-use of pm_idle.
And there are misuses of just about every kernel symbol - kmalloc for
example causes some people a lot of trouble !
> We'll create a new APM cpuidle driver in Linux (Trinabh prototyped one),
> and at the same time, schedule it for removal in a year. Personally,
> I think it is make-work, and in real-life it is more likely to do
> more harm than removing apm_idle, but I don't want to stand in the
> way of process.
So you could just leave it alone - that's less work, less disruption and
doesn't do any harm at all.
As I read this the plan at the moment otherwise is
- churn up all the code
- remove PM idle hook
- rewrite the APM code
- replace the APM code
whereas you could just leave the symbol exported or even just a hook to
make people to do it right using:
int register_pm_idle(function);
Simples yes ?
and then wait a year
For that matter instead of writing a new driver you could just stuff APM
into same hooks we have for virtualisation !
This whole patch series appears to be a giant piece of pointless makework.
Alan
On 04/03/2011 02:30 AM, Alan Cox wrote:
>> This patch series was posted in reply to a table of contents
>>
>> https://lkml.org/lkml/2011/4/2/8
>>
>> "By the end of this series, pm_idle is removed as a public
>> x86 idle-loop registration mechanism. A few other things are
>> cleaned up in the process."
>
> Ok so lets rewind a bit - why do we want to remove pm_idle rather than
> just fix up the way registration occurs. It's just a symbol, one trivial
> interface that is exported and perhaps wants the export method tidying up.
>
>> Trinabh also replied to you, pointing one of the previous
>> LKML discussions about the mis-use of pm_idle.
>
> And there are misuses of just about every kernel symbol - kmalloc for
> example causes some people a lot of trouble !
There are other problems too. This design of pm_idle has been copied
by numerous other architectures. arm/blackfin/cris/ia64/m32r/m68knomm
/microblaze/mn10300/sh/sparc all have pm_idle. This will keep spreading
in future I guess.
>
>> We'll create a new APM cpuidle driver in Linux (Trinabh prototyped one),
>> and at the same time, schedule it for removal in a year. Personally,
>> I think it is make-work, and in real-life it is more likely to do
>> more harm than removing apm_idle, but I don't want to stand in the
>> way of process.
>
> So you could just leave it alone - that's less work, less disruption and
> doesn't do any harm at all.
>
> As I read this the plan at the moment otherwise is
>
> - churn up all the code
> - remove PM idle hook
> - rewrite the APM code
> - replace the APM code
>
> whereas you could just leave the symbol exported or even just a hook to
> make people to do it right using:
>
> int register_pm_idle(function);
A patch was posted to do exactly this; see
https://lkml.org/lkml/2010/10/19/449 . The problem is that it
results in two places of registration: cpuidle subsystem and
this. It was pointed that 99.99% of people run cpuidle and
we should directly call cpuidle and use its registration mechanism
rather than duplicate code.
Thanks,
-Trinabh
On Sat, Apr 02, 2011 at 03:22:39PM -0400, Len Brown wrote:
> From: Len Brown <[email protected]>
>
> The workaround for AMD erratum 400 uses the term "c1e" falsely suggesting:
> 1. Intel C1E is somehow involved
> 2. All AMD processors with C1E are involved
>
> Use the string "amd_c1e" instead of simply "c1e" to clarify that
> this workaround is specific to AMD's version of C1E.
> Use the string "e400" to clarify that the workaround is specific
> to AMD processors with Erratum 400.
>
> This patch is text-substitution only, with no functional change.
>
> cc: [email protected]
> cc: Hans Rosenfeld <[email protected]>
> cc: Andreas Herrmann <[email protected]>
> Signed-off-by: Len Brown <[email protected]>
Looks good, thanks.
Acked-by: Borislav Petkov <[email protected]>
--
Regards/Gruss,
Boris.
Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
General Managers: Alberto Bozzo, Andrew Bowd
Registration: Dornach, Gemeinde Aschheim, Landkreis Muenchen
Registergericht Muenchen, HRB Nr. 43632
> There are other problems too. This design of pm_idle has been copied
> by numerous other architectures. arm/blackfin/cris/ia64/m32r/m68knomm
> /microblaze/mn10300/sh/sparc all have pm_idle. This will keep spreading
> in future I guess.
Presumably because they've decided it is a good model and works for them.
That's a matter for their arch maintainers surely.
> https://lkml.org/lkml/2010/10/19/449 . The problem is that it
> results in two places of registration: cpuidle subsystem and
> this. It was pointed that 99.99% of people run cpuidle and
> we should directly call cpuidle and use its registration mechanism
> rather than duplicate code.
That makes sense. However what Len is trying to do doesn't seem to.
The most likely case is nobody really needs APM idle now. In which case
Len's first patches (adding the warnings) make sense, but instead of
rushing headlong into everything else a simple years wait until the WARNs
have been in Fedora and co for a few months would avoid any further work
on it. In the mean time it produces a WARN, it can even be marked
__deprecated to ensure nobody else uses it.
The less likely case is that at some point within the year it turns out a
few people do need and care about it, so it needs shuffling into cpuidle
nicely.
In computing terms this seems to be a lazy evaluation problem - why do
all the extra work and risk bugs and problems trying to do things within
one release when you can just let it chill for a year and maybe not do
any work at all ?
Don't let me stop anyone actually doing the work but it seems to be
impatience before sanity ?
Alan
On Sat, Apr 02, 2011 at 02:22:51AM -0400, Len Brown wrote:
> From: Len Brown <[email protected]>
>
> When a Xen Dom0 kernel boots on a hypervisor, it gets access
> to the raw-hardware ACPI tables. While it parses the idle tables
> for the hypervisor's beneift, it uses HLT for its own idle.
>
> Rather than have xen scribble on pm_idle and access default_idle,
> have it simply disable_cpuidle() so acpi_idle will not load and
> architecture default HLT will be used.
Hey Len,
Looks good to me. I've also tested this on the affected Intel machine and
your patchset works fine.
>
> cc: [email protected]
> Signed-off-by: Len Brown <[email protected]>
> ---
> arch/x86/xen/setup.c | 3 ++-
> drivers/cpuidle/cpuidle.c | 4 ++++
> include/linux/cpuidle.h | 2 ++
> 3 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
> index a8a66a5..aa02cce 100644
> --- a/arch/x86/xen/setup.c
> +++ b/arch/x86/xen/setup.c
> @@ -9,6 +9,7 @@
> #include <linux/mm.h>
> #include <linux/pm.h>
> #include <linux/memblock.h>
> +#include <linux/cpuidle.h>
>
> #include <asm/elf.h>
> #include <asm/vdso.h>
> @@ -354,7 +355,7 @@ void __init xen_arch_setup(void)
> #ifdef CONFIG_X86_32
> boot_cpu_data.hlt_works_ok = 1;
> #endif
> - pm_idle = default_idle;
> + disable_cpuidle();
> boot_option_idle_override = IDLE_HALT;
>
> fiddle_vdso();
> diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
> index faae2c3..041df0b 100644
> --- a/drivers/cpuidle/cpuidle.c
> +++ b/drivers/cpuidle/cpuidle.c
> @@ -34,6 +34,10 @@ int cpuidle_disabled(void)
> {
> return off;
> }
> +void disable_cpuidle(void)
> +{
> + off = 1;
> +}
>
> #if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT)
> static void cpuidle_kick_cpus(void)
> diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
> index 36719ea..b89f67d 100644
> --- a/include/linux/cpuidle.h
> +++ b/include/linux/cpuidle.h
> @@ -122,6 +122,7 @@ struct cpuidle_driver {
> };
>
> #ifdef CONFIG_CPU_IDLE
> +extern void disable_cpuidle(void);
>
> extern int cpuidle_register_driver(struct cpuidle_driver *drv);
> struct cpuidle_driver *cpuidle_get_driver(void);
> @@ -135,6 +136,7 @@ extern int cpuidle_enable_device(struct cpuidle_device *dev);
> extern void cpuidle_disable_device(struct cpuidle_device *dev);
>
> #else
> +static inline void disable_cpuidle(void) { }
>
> static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
> {return -ENODEV; }
> --
> 1.7.5.rc0
>
>
> _______________________________________________
> Xen-devel mailing list
> [email protected]
> http://lists.xensource.com/xen-devel
On Sat 2011-04-02 14:28:31, Len Brown wrote:
> > Give it a year, it doesn't cause any complexities I can see.
>
> I'd rather not create a new an APM cpuilde driver,
> since there is nobody volunteering to test it.
> If you have the time and the hardware, please speak up.
I'm willing to test is, as is Jiri Kosina AFAICT.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
On 04/02/2011 11:52 AM, Len Brown wrote:
> From: Len Brown<[email protected]>
>
> pm_idle does not scale as an idle handler registration mechanism.
> Don't use it for cpuidle. Instead, call cpuidle directly, and
> allow architectures to use pm_idle as an arch-specific default
> if they need it. ie.
>
> cpu_idle()
> ...
> if(cpuidle_call_idle())
> pm_idle();
>
Hi Len,
This doesn't compile right now for ARM. The patch below
(on top of your series) is required to compile on arm, sh
Thanks,
-Trinabh
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d7ee0d4..1a347f4 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -197,7 +197,7 @@ void cpu_idle(void)
cpu_relax();
} else {
stop_critical_timings();
- if (cpuidle_call_idle())
+ if (cpuidle_idle_call())
pm_idle();
start_critical_timings();
/*
diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c
index 9c7099e..1db1968 100644
--- a/arch/sh/kernel/idle.c
+++ b/arch/sh/kernel/idle.c
@@ -101,7 +101,7 @@ void cpu_idle(void)
local_irq_disable();
/* Don't trace irqs off for idle */
stop_critical_timings();
- if (cpuidle_call_idle())
+ if (cpuidle_idle_call())
pm_idle();
/*
* Sanity check to ensure that pm_idle() returns