Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
2e7d0f60
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
2e7d0f60
编写于
2月 18, 2013
作者:
L
Len Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branches 'idle-remove-statedata', 'pm_idle' and 'idle-hsw-turbostat' into release
上级
57fa8273
558bd3e8
1ed51011
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
281 addition
and
252 deletion
+281
-252
arch/arm/kernel/process.c
arch/arm/kernel/process.c
+4
-9
arch/arm64/kernel/process.c
arch/arm64/kernel/process.c
+4
-9
arch/blackfin/kernel/process.c
arch/blackfin/kernel/process.c
+0
-7
arch/cris/kernel/process.c
arch/cris/kernel/process.c
+1
-10
arch/ia64/kernel/process.c
arch/ia64/kernel/process.c
+0
-3
arch/ia64/kernel/setup.c
arch/ia64/kernel/setup.c
+0
-1
arch/m32r/kernel/process.c
arch/m32r/kernel/process.c
+2
-49
arch/microblaze/kernel/process.c
arch/microblaze/kernel/process.c
+0
-3
arch/mn10300/kernel/process.c
arch/mn10300/kernel/process.c
+0
-7
arch/openrisc/kernel/idle.c
arch/openrisc/kernel/idle.c
+0
-5
arch/sh/kernel/idle.c
arch/sh/kernel/idle.c
+6
-6
arch/sparc/include/asm/processor_32.h
arch/sparc/include/asm/processor_32.h
+1
-0
arch/sparc/kernel/apc.c
arch/sparc/kernel/apc.c
+2
-1
arch/sparc/kernel/leon_pmc.c
arch/sparc/kernel/leon_pmc.c
+3
-2
arch/sparc/kernel/pmc.c
arch/sparc/kernel/pmc.c
+2
-1
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_32.c
+3
-4
arch/unicore32/kernel/process.c
arch/unicore32/kernel/process.c
+0
-5
arch/x86/Kconfig
arch/x86/Kconfig
+1
-0
arch/x86/include/asm/mwait.h
arch/x86/include/asm/mwait.h
+2
-1
arch/x86/include/uapi/asm/msr-index.h
arch/x86/include/uapi/asm/msr-index.h
+3
-0
arch/x86/kernel/apm_32.c
arch/x86/kernel/apm_32.c
+34
-23
arch/x86/kernel/process.c
arch/x86/kernel/process.c
+12
-19
drivers/idle/intel_idle.c
drivers/idle/intel_idle.c
+147
-56
include/linux/pm.h
include/linux/pm.h
+0
-1
tools/power/x86/turbostat/turbostat.8
tools/power/x86/turbostat/turbostat.8
+16
-20
tools/power/x86/turbostat/turbostat.c
tools/power/x86/turbostat/turbostat.c
+38
-10
未找到文件。
arch/arm/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -172,14 +172,9 @@ static void default_idle(void)
...
@@ -172,14 +172,9 @@ static void default_idle(void)
local_irq_enable
();
local_irq_enable
();
}
}
void
(
*
pm_idle
)(
void
)
=
default_idle
;
EXPORT_SYMBOL
(
pm_idle
);
/*
/*
* The idle thread, has rather strange semantics for calling pm_idle,
* The idle thread.
* but this is what x86 does and we need to do the same, so that
* We always respect 'hlt_counter' to prevent low power idle.
* things like cpuidle get called in the same way. The only difference
* is that we always respect 'hlt_counter' to prevent low power idle.
*/
*/
void
cpu_idle
(
void
)
void
cpu_idle
(
void
)
{
{
...
@@ -210,10 +205,10 @@ void cpu_idle(void)
...
@@ -210,10 +205,10 @@ void cpu_idle(void)
}
else
if
(
!
need_resched
())
{
}
else
if
(
!
need_resched
())
{
stop_critical_timings
();
stop_critical_timings
();
if
(
cpuidle_idle_call
())
if
(
cpuidle_idle_call
())
pm
_idle
();
default
_idle
();
start_critical_timings
();
start_critical_timings
();
/*
/*
*
pm
_idle functions must always
*
default
_idle functions must always
* return with IRQs enabled.
* return with IRQs enabled.
*/
*/
WARN_ON
(
irqs_disabled
());
WARN_ON
(
irqs_disabled
());
...
...
arch/arm64/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -97,14 +97,9 @@ static void default_idle(void)
...
@@ -97,14 +97,9 @@ static void default_idle(void)
local_irq_enable
();
local_irq_enable
();
}
}
void
(
*
pm_idle
)(
void
)
=
default_idle
;
EXPORT_SYMBOL_GPL
(
pm_idle
);
/*
/*
* The idle thread, has rather strange semantics for calling pm_idle,
* The idle thread.
* but this is what x86 does and we need to do the same, so that
* We always respect 'hlt_counter' to prevent low power idle.
* things like cpuidle get called in the same way. The only difference
* is that we always respect 'hlt_counter' to prevent low power idle.
*/
*/
void
cpu_idle
(
void
)
void
cpu_idle
(
void
)
{
{
...
@@ -122,10 +117,10 @@ void cpu_idle(void)
...
@@ -122,10 +117,10 @@ void cpu_idle(void)
local_irq_disable
();
local_irq_disable
();
if
(
!
need_resched
())
{
if
(
!
need_resched
())
{
stop_critical_timings
();
stop_critical_timings
();
pm
_idle
();
default
_idle
();
start_critical_timings
();
start_critical_timings
();
/*
/*
*
pm
_idle functions should always return
*
default
_idle functions should always return
* with IRQs enabled.
* with IRQs enabled.
*/
*/
WARN_ON
(
irqs_disabled
());
WARN_ON
(
irqs_disabled
());
...
...
arch/blackfin/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -39,12 +39,6 @@ int nr_l1stack_tasks;
...
@@ -39,12 +39,6 @@ int nr_l1stack_tasks;
void
*
l1_stack_base
;
void
*
l1_stack_base
;
unsigned
long
l1_stack_len
;
unsigned
long
l1_stack_len
;
/*
* Powermanagement idle function, if any..
*/
void
(
*
pm_idle
)(
void
)
=
NULL
;
EXPORT_SYMBOL
(
pm_idle
);
void
(
*
pm_power_off
)(
void
)
=
NULL
;
void
(
*
pm_power_off
)(
void
)
=
NULL
;
EXPORT_SYMBOL
(
pm_power_off
);
EXPORT_SYMBOL
(
pm_power_off
);
...
@@ -81,7 +75,6 @@ void cpu_idle(void)
...
@@ -81,7 +75,6 @@ void cpu_idle(void)
{
{
/* endless idle loop with no priority at all */
/* endless idle loop with no priority at all */
while
(
1
)
{
while
(
1
)
{
void
(
*
idle
)(
void
)
=
pm_idle
;
#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_HOTPLUG_CPU
if
(
cpu_is_offline
(
smp_processor_id
()))
if
(
cpu_is_offline
(
smp_processor_id
()))
...
...
arch/cris/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -54,11 +54,6 @@ void enable_hlt(void)
...
@@ -54,11 +54,6 @@ void enable_hlt(void)
EXPORT_SYMBOL
(
enable_hlt
);
EXPORT_SYMBOL
(
enable_hlt
);
/*
* The following aren't currently used.
*/
void
(
*
pm_idle
)(
void
);
extern
void
default_idle
(
void
);
extern
void
default_idle
(
void
);
void
(
*
pm_power_off
)(
void
);
void
(
*
pm_power_off
)(
void
);
...
@@ -77,16 +72,12 @@ void cpu_idle (void)
...
@@ -77,16 +72,12 @@ void cpu_idle (void)
while
(
1
)
{
while
(
1
)
{
rcu_idle_enter
();
rcu_idle_enter
();
while
(
!
need_resched
())
{
while
(
!
need_resched
())
{
void
(
*
idle
)(
void
);
/*
/*
* Mark this as an RCU critical section so that
* Mark this as an RCU critical section so that
* synchronize_kernel() in the unload path waits
* synchronize_kernel() in the unload path waits
* for our completion.
* for our completion.
*/
*/
idle
=
pm_idle
;
default_idle
();
if
(
!
idle
)
idle
=
default_idle
;
idle
();
}
}
rcu_idle_exit
();
rcu_idle_exit
();
schedule_preempt_disabled
();
schedule_preempt_disabled
();
...
...
arch/ia64/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -57,8 +57,6 @@ void (*ia64_mark_idle)(int);
...
@@ -57,8 +57,6 @@ void (*ia64_mark_idle)(int);
unsigned
long
boot_option_idle_override
=
IDLE_NO_OVERRIDE
;
unsigned
long
boot_option_idle_override
=
IDLE_NO_OVERRIDE
;
EXPORT_SYMBOL
(
boot_option_idle_override
);
EXPORT_SYMBOL
(
boot_option_idle_override
);
void
(
*
pm_idle
)
(
void
);
EXPORT_SYMBOL
(
pm_idle
);
void
(
*
pm_power_off
)
(
void
);
void
(
*
pm_power_off
)
(
void
);
EXPORT_SYMBOL
(
pm_power_off
);
EXPORT_SYMBOL
(
pm_power_off
);
...
@@ -301,7 +299,6 @@ cpu_idle (void)
...
@@ -301,7 +299,6 @@ cpu_idle (void)
if
(
mark_idle
)
if
(
mark_idle
)
(
*
mark_idle
)(
1
);
(
*
mark_idle
)(
1
);
idle
=
pm_idle
;
if
(
!
idle
)
if
(
!
idle
)
idle
=
default_idle
;
idle
=
default_idle
;
(
*
idle
)();
(
*
idle
)();
...
...
arch/ia64/kernel/setup.c
浏览文件 @
2e7d0f60
...
@@ -1051,7 +1051,6 @@ cpu_init (void)
...
@@ -1051,7 +1051,6 @@ cpu_init (void)
max_num_phys_stacked
=
num_phys_stacked
;
max_num_phys_stacked
=
num_phys_stacked
;
}
}
platform_cpu_init
();
platform_cpu_init
();
pm_idle
=
default_idle
;
}
}
void
__init
void
__init
...
...
arch/m32r/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -44,35 +44,9 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
...
@@ -44,35 +44,9 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
return
tsk
->
thread
.
lr
;
return
tsk
->
thread
.
lr
;
}
}
/*
* Powermanagement idle function, if any..
*/
static
void
(
*
pm_idle
)(
void
)
=
NULL
;
void
(
*
pm_power_off
)(
void
)
=
NULL
;
void
(
*
pm_power_off
)(
void
)
=
NULL
;
EXPORT_SYMBOL
(
pm_power_off
);
EXPORT_SYMBOL
(
pm_power_off
);
/*
* We use this is we don't have any better
* idle routine..
*/
static
void
default_idle
(
void
)
{
/* M32R_FIXME: Please use "cpu_sleep" mode. */
cpu_relax
();
}
/*
* On SMP it's slightly faster (but much more power-consuming!)
* to poll the ->work.need_resched flag instead of waiting for the
* cross-CPU IPI to arrive. Use this option with caution.
*/
static
void
poll_idle
(
void
)
{
/* M32R_FIXME */
cpu_relax
();
}
/*
/*
* The idle thread. There's no useful work to be
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* done, so just try to conserve power and have a
...
@@ -84,14 +58,8 @@ void cpu_idle (void)
...
@@ -84,14 +58,8 @@ void cpu_idle (void)
/* endless idle loop with no priority at all */
/* endless idle loop with no priority at all */
while
(
1
)
{
while
(
1
)
{
rcu_idle_enter
();
rcu_idle_enter
();
while
(
!
need_resched
())
{
while
(
!
need_resched
())
void
(
*
idle
)(
void
)
=
pm_idle
;
cpu_relax
();
if
(
!
idle
)
idle
=
default_idle
;
idle
();
}
rcu_idle_exit
();
rcu_idle_exit
();
schedule_preempt_disabled
();
schedule_preempt_disabled
();
}
}
...
@@ -120,21 +88,6 @@ void machine_power_off(void)
...
@@ -120,21 +88,6 @@ void machine_power_off(void)
/* M32R_FIXME */
/* M32R_FIXME */
}
}
static
int
__init
idle_setup
(
char
*
str
)
{
if
(
!
strncmp
(
str
,
"poll"
,
4
))
{
printk
(
"using poll in idle threads.
\n
"
);
pm_idle
=
poll_idle
;
}
else
if
(
!
strncmp
(
str
,
"sleep"
,
4
))
{
printk
(
"using sleep in idle threads.
\n
"
);
pm_idle
=
default_idle
;
}
return
1
;
}
__setup
(
"idle="
,
idle_setup
);
void
show_regs
(
struct
pt_regs
*
regs
)
void
show_regs
(
struct
pt_regs
*
regs
)
{
{
printk
(
"
\n
"
);
printk
(
"
\n
"
);
...
...
arch/microblaze/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -41,7 +41,6 @@ void show_regs(struct pt_regs *regs)
...
@@ -41,7 +41,6 @@ void show_regs(struct pt_regs *regs)
regs
->
msr
,
regs
->
ear
,
regs
->
esr
,
regs
->
fsr
);
regs
->
msr
,
regs
->
ear
,
regs
->
esr
,
regs
->
fsr
);
}
}
void
(
*
pm_idle
)(
void
);
void
(
*
pm_power_off
)(
void
)
=
NULL
;
void
(
*
pm_power_off
)(
void
)
=
NULL
;
EXPORT_SYMBOL
(
pm_power_off
);
EXPORT_SYMBOL
(
pm_power_off
);
...
@@ -98,8 +97,6 @@ void cpu_idle(void)
...
@@ -98,8 +97,6 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
/* endless idle loop with no priority at all */
while
(
1
)
{
while
(
1
)
{
void
(
*
idle
)(
void
)
=
pm_idle
;
if
(
!
idle
)
if
(
!
idle
)
idle
=
default_idle
;
idle
=
default_idle
;
...
...
arch/mn10300/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -36,12 +36,6 @@
...
@@ -36,12 +36,6 @@
#include <asm/gdb-stub.h>
#include <asm/gdb-stub.h>
#include "internal.h"
#include "internal.h"
/*
* power management idle function, if any..
*/
void
(
*
pm_idle
)(
void
);
EXPORT_SYMBOL
(
pm_idle
);
/*
/*
* return saved PC of a blocked thread.
* return saved PC of a blocked thread.
*/
*/
...
@@ -113,7 +107,6 @@ void cpu_idle(void)
...
@@ -113,7 +107,6 @@ void cpu_idle(void)
void
(
*
idle
)(
void
);
void
(
*
idle
)(
void
);
smp_rmb
();
smp_rmb
();
idle
=
pm_idle
;
if
(
!
idle
)
{
if
(
!
idle
)
{
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
idle
=
poll_idle
;
idle
=
poll_idle
;
...
...
arch/openrisc/kernel/idle.c
浏览文件 @
2e7d0f60
...
@@ -39,11 +39,6 @@
...
@@ -39,11 +39,6 @@
void
(
*
powersave
)
(
void
)
=
NULL
;
void
(
*
powersave
)
(
void
)
=
NULL
;
static
inline
void
pm_idle
(
void
)
{
barrier
();
}
void
cpu_idle
(
void
)
void
cpu_idle
(
void
)
{
{
set_thread_flag
(
TIF_POLLING_NRFLAG
);
set_thread_flag
(
TIF_POLLING_NRFLAG
);
...
...
arch/sh/kernel/idle.c
浏览文件 @
2e7d0f60
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
#include <asm/smp.h>
#include <asm/smp.h>
#include <asm/bl_bit.h>
#include <asm/bl_bit.h>
void
(
*
pm
_idle
)(
void
);
static
void
(
*
sh
_idle
)(
void
);
static
int
hlt_counter
;
static
int
hlt_counter
;
...
@@ -103,9 +103,9 @@ void cpu_idle(void)
...
@@ -103,9 +103,9 @@ void cpu_idle(void)
/* Don't trace irqs off for idle */
/* Don't trace irqs off for idle */
stop_critical_timings
();
stop_critical_timings
();
if
(
cpuidle_idle_call
())
if
(
cpuidle_idle_call
())
pm
_idle
();
sh
_idle
();
/*
/*
* Sanity check to ensure that
pm
_idle() returns
* Sanity check to ensure that
sh
_idle() returns
* with IRQs enabled
* with IRQs enabled
*/
*/
WARN_ON
(
irqs_disabled
());
WARN_ON
(
irqs_disabled
());
...
@@ -123,13 +123,13 @@ void __init select_idle_routine(void)
...
@@ -123,13 +123,13 @@ void __init select_idle_routine(void)
/*
/*
* If a platform has set its own idle routine, leave it alone.
* If a platform has set its own idle routine, leave it alone.
*/
*/
if
(
pm
_idle
)
if
(
sh
_idle
)
return
;
return
;
if
(
hlt_works
())
if
(
hlt_works
())
pm
_idle
=
default_idle
;
sh
_idle
=
default_idle
;
else
else
pm
_idle
=
poll_idle
;
sh
_idle
=
poll_idle
;
}
}
void
stop_this_cpu
(
void
*
unused
)
void
stop_this_cpu
(
void
*
unused
)
...
...
arch/sparc/include/asm/processor_32.h
浏览文件 @
2e7d0f60
...
@@ -118,6 +118,7 @@ extern unsigned long get_wchan(struct task_struct *);
...
@@ -118,6 +118,7 @@ extern unsigned long get_wchan(struct task_struct *);
extern
struct
task_struct
*
last_task_used_math
;
extern
struct
task_struct
*
last_task_used_math
;
#define cpu_relax() barrier()
#define cpu_relax() barrier()
extern
void
(
*
sparc_idle
)(
void
);
#endif
#endif
...
...
arch/sparc/kernel/apc.c
浏览文件 @
2e7d0f60
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/auxio.h>
#include <asm/auxio.h>
#include <asm/apc.h>
#include <asm/apc.h>
#include <asm/processor.h>
/* Debugging
/* Debugging
*
*
...
@@ -158,7 +159,7 @@ static int apc_probe(struct platform_device *op)
...
@@ -158,7 +159,7 @@ static int apc_probe(struct platform_device *op)
/* Assign power management IDLE handler */
/* Assign power management IDLE handler */
if
(
!
apc_no_idle
)
if
(
!
apc_no_idle
)
pm_idle
=
apc_swift_idle
;
sparc_idle
=
apc_swift_idle
;
printk
(
KERN_INFO
"%s: power management initialized%s
\n
"
,
printk
(
KERN_INFO
"%s: power management initialized%s
\n
"
,
APC_DEVNAME
,
apc_no_idle
?
" (CPU idle disabled)"
:
""
);
APC_DEVNAME
,
apc_no_idle
?
" (CPU idle disabled)"
:
""
);
...
...
arch/sparc/kernel/leon_pmc.c
浏览文件 @
2e7d0f60
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include <asm/leon_amba.h>
#include <asm/leon_amba.h>
#include <asm/cpu_type.h>
#include <asm/cpu_type.h>
#include <asm/leon.h>
#include <asm/leon.h>
#include <asm/processor.h>
/* List of Systems that need fixup instructions around power-down instruction */
/* List of Systems that need fixup instructions around power-down instruction */
unsigned
int
pmc_leon_fixup_ids
[]
=
{
unsigned
int
pmc_leon_fixup_ids
[]
=
{
...
@@ -69,9 +70,9 @@ static int __init leon_pmc_install(void)
...
@@ -69,9 +70,9 @@ static int __init leon_pmc_install(void)
if
(
sparc_cpu_model
==
sparc_leon
)
{
if
(
sparc_cpu_model
==
sparc_leon
)
{
/* Assign power management IDLE handler */
/* Assign power management IDLE handler */
if
(
pmc_leon_need_fixup
())
if
(
pmc_leon_need_fixup
())
pm
_idle
=
pmc_leon_idle_fixup
;
sparc
_idle
=
pmc_leon_idle_fixup
;
else
else
pm
_idle
=
pmc_leon_idle
;
sparc
_idle
=
pmc_leon_idle
;
printk
(
KERN_INFO
"leon: power management initialized
\n
"
);
printk
(
KERN_INFO
"leon: power management initialized
\n
"
);
}
}
...
...
arch/sparc/kernel/pmc.c
浏览文件 @
2e7d0f60
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include <asm/oplib.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/auxio.h>
#include <asm/auxio.h>
#include <asm/processor.h>
/* Debug
/* Debug
*
*
...
@@ -63,7 +64,7 @@ static int pmc_probe(struct platform_device *op)
...
@@ -63,7 +64,7 @@ static int pmc_probe(struct platform_device *op)
#ifndef PMC_NO_IDLE
#ifndef PMC_NO_IDLE
/* Assign power management IDLE handler */
/* Assign power management IDLE handler */
pm
_idle
=
pmc_swift_idle
;
sparc
_idle
=
pmc_swift_idle
;
#endif
#endif
printk
(
KERN_INFO
"%s: power management initialized
\n
"
,
PMC_DEVNAME
);
printk
(
KERN_INFO
"%s: power management initialized
\n
"
,
PMC_DEVNAME
);
...
...
arch/sparc/kernel/process_32.c
浏览文件 @
2e7d0f60
...
@@ -43,8 +43,7 @@
...
@@ -43,8 +43,7 @@
* Power management idle function
* Power management idle function
* Set in pm platform drivers (apc.c and pmc.c)
* Set in pm platform drivers (apc.c and pmc.c)
*/
*/
void
(
*
pm_idle
)(
void
);
void
(
*
sparc_idle
)(
void
);
EXPORT_SYMBOL
(
pm_idle
);
/*
/*
* Power-off handler instantiation for pm.h compliance
* Power-off handler instantiation for pm.h compliance
...
@@ -75,8 +74,8 @@ void cpu_idle(void)
...
@@ -75,8 +74,8 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
/* endless idle loop with no priority at all */
for
(;;)
{
for
(;;)
{
while
(
!
need_resched
())
{
while
(
!
need_resched
())
{
if
(
pm
_idle
)
if
(
sparc
_idle
)
(
*
pm
_idle
)();
(
*
sparc
_idle
)();
else
else
cpu_relax
();
cpu_relax
();
}
}
...
...
arch/unicore32/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -45,11 +45,6 @@ static const char * const processor_modes[] = {
...
@@ -45,11 +45,6 @@ static const char * const processor_modes[] = {
"UK18"
,
"UK19"
,
"UK1A"
,
"EXTN"
,
"UK1C"
,
"UK1D"
,
"UK1E"
,
"SUSR"
"UK18"
,
"UK19"
,
"UK1A"
,
"EXTN"
,
"UK1C"
,
"UK1D"
,
"UK1E"
,
"SUSR"
};
};
/*
* The idle thread, has rather strange semantics for calling pm_idle,
* but this is what x86 does and we need to do the same, so that
* things like cpuidle get called in the same way.
*/
void
cpu_idle
(
void
)
void
cpu_idle
(
void
)
{
{
/* endless idle loop with no priority at all */
/* endless idle loop with no priority at all */
...
...
arch/x86/Kconfig
浏览文件 @
2e7d0f60
...
@@ -1912,6 +1912,7 @@ config APM_DO_ENABLE
...
@@ -1912,6 +1912,7 @@ config APM_DO_ENABLE
this feature.
this feature.
config APM_CPU_IDLE
config APM_CPU_IDLE
depends on CPU_IDLE
bool "Make CPU Idle calls when idle"
bool "Make CPU Idle calls when idle"
---help---
---help---
Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
...
...
arch/x86/include/asm/mwait.h
浏览文件 @
2e7d0f60
...
@@ -4,7 +4,8 @@
...
@@ -4,7 +4,8 @@
#define MWAIT_SUBSTATE_MASK 0xf
#define MWAIT_SUBSTATE_MASK 0xf
#define MWAIT_CSTATE_MASK 0xf
#define MWAIT_CSTATE_MASK 0xf
#define MWAIT_SUBSTATE_SIZE 4
#define MWAIT_SUBSTATE_SIZE 4
#define MWAIT_MAX_NUM_CSTATES 8
#define MWAIT_HINT2CSTATE(hint) (((hint) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK)
#define MWAIT_HINT2SUBSTATE(hint) ((hint) & MWAIT_CSTATE_MASK)
#define CPUID_MWAIT_LEAF 5
#define CPUID_MWAIT_LEAF 5
#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
...
...
arch/x86/include/uapi/asm/msr-index.h
浏览文件 @
2e7d0f60
...
@@ -103,6 +103,8 @@
...
@@ -103,6 +103,8 @@
#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10)
#define DEBUGCTLMSR_BTS_OFF_USR (1UL << 10)
#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
#define DEBUGCTLMSR_FREEZE_LBRS_ON_PMI (1UL << 11)
#define MSR_IA32_POWER_CTL 0x000001fc
#define MSR_IA32_MC0_CTL 0x00000400
#define MSR_IA32_MC0_CTL 0x00000400
#define MSR_IA32_MC0_STATUS 0x00000401
#define MSR_IA32_MC0_STATUS 0x00000401
#define MSR_IA32_MC0_ADDR 0x00000402
#define MSR_IA32_MC0_ADDR 0x00000402
...
@@ -272,6 +274,7 @@
...
@@ -272,6 +274,7 @@
#define MSR_IA32_PLATFORM_ID 0x00000017
#define MSR_IA32_PLATFORM_ID 0x00000017
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
#define MSR_EBC_FREQUENCY_ID 0x0000002c
#define MSR_EBC_FREQUENCY_ID 0x0000002c
#define MSR_SMI_COUNT 0x00000034
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
#define MSR_IA32_TSC_ADJUST 0x0000003b
#define MSR_IA32_TSC_ADJUST 0x0000003b
...
...
arch/x86/kernel/apm_32.c
浏览文件 @
2e7d0f60
...
@@ -232,6 +232,7 @@
...
@@ -232,6 +232,7 @@
#include <linux/acpi.h>
#include <linux/acpi.h>
#include <linux/syscore_ops.h>
#include <linux/syscore_ops.h>
#include <linux/i8253.h>
#include <linux/i8253.h>
#include <linux/cpuidle.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <asm/desc.h>
#include <asm/desc.h>
...
@@ -360,13 +361,35 @@ struct apm_user {
...
@@ -360,13 +361,35 @@ struct apm_user {
* idle percentage above which bios idle calls are done
* idle percentage above which bios idle calls are done
*/
*/
#ifdef CONFIG_APM_CPU_IDLE
#ifdef CONFIG_APM_CPU_IDLE
#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012
#define DEFAULT_IDLE_THRESHOLD 95
#define DEFAULT_IDLE_THRESHOLD 95
#else
#else
#define DEFAULT_IDLE_THRESHOLD 100
#define DEFAULT_IDLE_THRESHOLD 100
#endif
#endif
#define DEFAULT_IDLE_PERIOD (100 / 3)
#define DEFAULT_IDLE_PERIOD (100 / 3)
static
int
apm_cpu_idle
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
int
index
);
static
struct
cpuidle_driver
apm_idle_driver
=
{
.
name
=
"apm_idle"
,
.
owner
=
THIS_MODULE
,
.
en_core_tk_irqen
=
1
,
.
states
=
{
{
/* entry 0 is for polling */
},
{
/* entry 1 is for APM idle */
.
name
=
"APM"
,
.
desc
=
"APM idle"
,
.
flags
=
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
250
,
/* WAG */
.
target_residency
=
500
,
/* WAG */
.
enter
=
&
apm_cpu_idle
},
},
.
state_count
=
2
,
};
static
struct
cpuidle_device
apm_cpuidle_device
;
/*
/*
* Local variables
* Local variables
*/
*/
...
@@ -377,7 +400,6 @@ static struct {
...
@@ -377,7 +400,6 @@ static struct {
static
int
clock_slowed
;
static
int
clock_slowed
;
static
int
idle_threshold
__read_mostly
=
DEFAULT_IDLE_THRESHOLD
;
static
int
idle_threshold
__read_mostly
=
DEFAULT_IDLE_THRESHOLD
;
static
int
idle_period
__read_mostly
=
DEFAULT_IDLE_PERIOD
;
static
int
idle_period
__read_mostly
=
DEFAULT_IDLE_PERIOD
;
static
int
set_pm_idle
;
static
int
suspends_pending
;
static
int
suspends_pending
;
static
int
standbys_pending
;
static
int
standbys_pending
;
static
int
ignore_sys_suspend
;
static
int
ignore_sys_suspend
;
...
@@ -884,8 +906,6 @@ static void apm_do_busy(void)
...
@@ -884,8 +906,6 @@ static void apm_do_busy(void)
#define IDLE_CALC_LIMIT (HZ * 100)
#define IDLE_CALC_LIMIT (HZ * 100)
#define IDLE_LEAKY_MAX 16
#define IDLE_LEAKY_MAX 16
static
void
(
*
original_pm_idle
)(
void
)
__read_mostly
;
/**
/**
* apm_cpu_idle - cpu idling for APM capable Linux
* apm_cpu_idle - cpu idling for APM capable Linux
*
*
...
@@ -894,7 +914,8 @@ static void (*original_pm_idle)(void) __read_mostly;
...
@@ -894,7 +914,8 @@ static void (*original_pm_idle)(void) __read_mostly;
* Furthermore it calls the system default idle routine.
* Furthermore it calls the system default idle routine.
*/
*/
static
void
apm_cpu_idle
(
void
)
static
int
apm_cpu_idle
(
struct
cpuidle_device
*
dev
,
struct
cpuidle_driver
*
drv
,
int
index
)
{
{
static
int
use_apm_idle
;
/* = 0 */
static
int
use_apm_idle
;
/* = 0 */
static
unsigned
int
last_jiffies
;
/* = 0 */
static
unsigned
int
last_jiffies
;
/* = 0 */
...
@@ -904,7 +925,6 @@ static void apm_cpu_idle(void)
...
@@ -904,7 +925,6 @@ static void apm_cpu_idle(void)
unsigned
int
jiffies_since_last_check
=
jiffies
-
last_jiffies
;
unsigned
int
jiffies_since_last_check
=
jiffies
-
last_jiffies
;
unsigned
int
bucket
;
unsigned
int
bucket
;
WARN_ONCE
(
1
,
"deprecated apm_cpu_idle will be deleted in 2012"
);
recalc:
recalc:
if
(
jiffies_since_last_check
>
IDLE_CALC_LIMIT
)
{
if
(
jiffies_since_last_check
>
IDLE_CALC_LIMIT
)
{
use_apm_idle
=
0
;
use_apm_idle
=
0
;
...
@@ -950,10 +970,7 @@ static void apm_cpu_idle(void)
...
@@ -950,10 +970,7 @@ static void apm_cpu_idle(void)
break
;
break
;
}
}
}
}
if
(
original_pm_idle
)
default_idle
();
original_pm_idle
();
else
default_idle
();
local_irq_disable
();
local_irq_disable
();
jiffies_since_last_check
=
jiffies
-
last_jiffies
;
jiffies_since_last_check
=
jiffies
-
last_jiffies
;
if
(
jiffies_since_last_check
>
idle_period
)
if
(
jiffies_since_last_check
>
idle_period
)
...
@@ -963,7 +980,7 @@ static void apm_cpu_idle(void)
...
@@ -963,7 +980,7 @@ static void apm_cpu_idle(void)
if
(
apm_idle_done
)
if
(
apm_idle_done
)
apm_do_busy
();
apm_do_busy
();
local_irq_enable
()
;
return
index
;
}
}
/**
/**
...
@@ -2381,9 +2398,9 @@ static int __init apm_init(void)
...
@@ -2381,9 +2398,9 @@ static int __init apm_init(void)
if
(
HZ
!=
100
)
if
(
HZ
!=
100
)
idle_period
=
(
idle_period
*
HZ
)
/
100
;
idle_period
=
(
idle_period
*
HZ
)
/
100
;
if
(
idle_threshold
<
100
)
{
if
(
idle_threshold
<
100
)
{
original_pm_idle
=
pm_idle
;
if
(
!
cpuidle_register_driver
(
&
apm_idle_driver
))
pm_idle
=
apm_cpu_idle
;
if
(
cpuidle_register_device
(
&
apm_cpuidle_device
))
set_pm_idle
=
1
;
cpuidle_unregister_driver
(
&
apm_idle_driver
)
;
}
}
return
0
;
return
0
;
...
@@ -2393,15 +2410,9 @@ static void __exit apm_exit(void)
...
@@ -2393,15 +2410,9 @@ static void __exit apm_exit(void)
{
{
int
error
;
int
error
;
if
(
set_pm_idle
)
{
cpuidle_unregister_device
(
&
apm_cpuidle_device
);
pm_idle
=
original_pm_idle
;
cpuidle_unregister_driver
(
&
apm_idle_driver
);
/*
* 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.
*/
kick_all_cpus_sync
();
}
if
(((
apm_info
.
bios
.
flags
&
APM_BIOS_DISENGAGED
)
==
0
)
if
(((
apm_info
.
bios
.
flags
&
APM_BIOS_DISENGAGED
)
==
0
)
&&
(
apm_info
.
connection_version
>
0x0100
))
{
&&
(
apm_info
.
connection_version
>
0x0100
))
{
error
=
apm_engage_power_management
(
APM_DEVICE_ALL
,
0
);
error
=
apm_engage_power_management
(
APM_DEVICE_ALL
,
0
);
...
...
arch/x86/kernel/process.c
浏览文件 @
2e7d0f60
...
@@ -268,13 +268,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
...
@@ -268,13 +268,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
unsigned
long
boot_option_idle_override
=
IDLE_NO_OVERRIDE
;
unsigned
long
boot_option_idle_override
=
IDLE_NO_OVERRIDE
;
EXPORT_SYMBOL
(
boot_option_idle_override
);
EXPORT_SYMBOL
(
boot_option_idle_override
);
/*
static
void
(
*
x86_idle
)(
void
);
* Powermanagement idle function, if any..
*/
void
(
*
pm_idle
)(
void
);
#ifdef CONFIG_APM_MODULE
EXPORT_SYMBOL
(
pm_idle
);
#endif
#ifndef CONFIG_SMP
#ifndef CONFIG_SMP
static
inline
void
play_dead
(
void
)
static
inline
void
play_dead
(
void
)
...
@@ -351,7 +345,7 @@ void cpu_idle(void)
...
@@ -351,7 +345,7 @@ void cpu_idle(void)
rcu_idle_enter
();
rcu_idle_enter
();
if
(
cpuidle_idle_call
())
if
(
cpuidle_idle_call
())
pm
_idle
();
x86
_idle
();
rcu_idle_exit
();
rcu_idle_exit
();
start_critical_timings
();
start_critical_timings
();
...
@@ -398,9 +392,9 @@ EXPORT_SYMBOL(default_idle);
...
@@ -398,9 +392,9 @@ EXPORT_SYMBOL(default_idle);
bool
set_pm_idle_to_default
(
void
)
bool
set_pm_idle_to_default
(
void
)
{
{
bool
ret
=
!!
pm
_idle
;
bool
ret
=
!!
x86
_idle
;
pm
_idle
=
default_idle
;
x86
_idle
=
default_idle
;
return
ret
;
return
ret
;
}
}
...
@@ -567,11 +561,10 @@ static void amd_e400_idle(void)
...
@@ -567,11 +561,10 @@ static void amd_e400_idle(void)
void
__cpuinit
select_idle_routine
(
const
struct
cpuinfo_x86
*
c
)
void
__cpuinit
select_idle_routine
(
const
struct
cpuinfo_x86
*
c
)
{
{
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
if
(
pm_idle
==
poll_idle
&&
smp_num_siblings
>
1
)
{
if
(
x86_idle
==
poll_idle
&&
smp_num_siblings
>
1
)
pr_warn_once
(
"WARNING: polling idle and HT enabled, performance may degrade
\n
"
);
pr_warn_once
(
"WARNING: polling idle and HT enabled, performance may degrade
\n
"
);
}
#endif
#endif
if
(
pm
_idle
)
if
(
x86
_idle
)
return
;
return
;
if
(
cpu_has
(
c
,
X86_FEATURE_MWAIT
)
&&
mwait_usable
(
c
))
{
if
(
cpu_has
(
c
,
X86_FEATURE_MWAIT
)
&&
mwait_usable
(
c
))
{
...
@@ -579,19 +572,19 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
...
@@ -579,19 +572,19 @@ void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
* One CPU supports mwait => All CPUs supports mwait
* One CPU supports mwait => All CPUs supports mwait
*/
*/
pr_info
(
"using mwait in idle threads
\n
"
);
pr_info
(
"using mwait in idle threads
\n
"
);
pm
_idle
=
mwait_idle
;
x86
_idle
=
mwait_idle
;
}
else
if
(
cpu_has_amd_erratum
(
amd_erratum_400
))
{
}
else
if
(
cpu_has_amd_erratum
(
amd_erratum_400
))
{
/* E400: APIC timer interrupt does not wake up CPU from C1e */
/* E400: APIC timer interrupt does not wake up CPU from C1e */
pr_info
(
"using AMD E400 aware idle routine
\n
"
);
pr_info
(
"using AMD E400 aware idle routine
\n
"
);
pm
_idle
=
amd_e400_idle
;
x86
_idle
=
amd_e400_idle
;
}
else
}
else
pm
_idle
=
default_idle
;
x86
_idle
=
default_idle
;
}
}
void
__init
init_amd_e400_c1e_mask
(
void
)
void
__init
init_amd_e400_c1e_mask
(
void
)
{
{
/* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */
/* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */
if
(
pm
_idle
==
amd_e400_idle
)
if
(
x86
_idle
==
amd_e400_idle
)
zalloc_cpumask_var
(
&
amd_e400_c1e_mask
,
GFP_KERNEL
);
zalloc_cpumask_var
(
&
amd_e400_c1e_mask
,
GFP_KERNEL
);
}
}
...
@@ -602,7 +595,7 @@ static int __init idle_setup(char *str)
...
@@ -602,7 +595,7 @@ static int __init idle_setup(char *str)
if
(
!
strcmp
(
str
,
"poll"
))
{
if
(
!
strcmp
(
str
,
"poll"
))
{
pr_info
(
"using polling idle threads
\n
"
);
pr_info
(
"using polling idle threads
\n
"
);
pm
_idle
=
poll_idle
;
x86
_idle
=
poll_idle
;
boot_option_idle_override
=
IDLE_POLL
;
boot_option_idle_override
=
IDLE_POLL
;
}
else
if
(
!
strcmp
(
str
,
"mwait"
))
{
}
else
if
(
!
strcmp
(
str
,
"mwait"
))
{
boot_option_idle_override
=
IDLE_FORCE_MWAIT
;
boot_option_idle_override
=
IDLE_FORCE_MWAIT
;
...
@@ -615,7 +608,7 @@ static int __init idle_setup(char *str)
...
@@ -615,7 +608,7 @@ static int __init idle_setup(char *str)
* To continue to load the CPU idle driver, don't touch
* To continue to load the CPU idle driver, don't touch
* the boot_option_idle_override.
* the boot_option_idle_override.
*/
*/
pm
_idle
=
default_idle
;
x86
_idle
=
default_idle
;
boot_option_idle_override
=
IDLE_HALT
;
boot_option_idle_override
=
IDLE_HALT
;
}
else
if
(
!
strcmp
(
str
,
"nomwait"
))
{
}
else
if
(
!
strcmp
(
str
,
"nomwait"
))
{
/*
/*
...
...
drivers/idle/intel_idle.c
浏览文件 @
2e7d0f60
...
@@ -74,7 +74,7 @@ static struct cpuidle_driver intel_idle_driver = {
...
@@ -74,7 +74,7 @@ static struct cpuidle_driver intel_idle_driver = {
.
en_core_tk_irqen
=
1
,
.
en_core_tk_irqen
=
1
,
};
};
/* intel_idle.max_cstate=0 disables driver */
/* intel_idle.max_cstate=0 disables driver */
static
int
max_cstate
=
MWAIT_MAX_NUM_CSTATES
-
1
;
static
int
max_cstate
=
CPUIDLE_STATE_MAX
-
1
;
static
unsigned
int
mwait_substates
;
static
unsigned
int
mwait_substates
;
...
@@ -90,6 +90,7 @@ struct idle_cpu {
...
@@ -90,6 +90,7 @@ struct idle_cpu {
* Indicate which enable bits to clear here.
* Indicate which enable bits to clear here.
*/
*/
unsigned
long
auto_demotion_disable_flags
;
unsigned
long
auto_demotion_disable_flags
;
bool
disable_promotion_to_c1e
;
};
};
static
const
struct
idle_cpu
*
icpu
;
static
const
struct
idle_cpu
*
icpu
;
...
@@ -123,127 +124,190 @@ static struct cpuidle_state *cpuidle_state_table;
...
@@ -123,127 +124,190 @@ static struct cpuidle_state *cpuidle_state_table;
* which is also the index into the MWAIT hint array.
* which is also the index into the MWAIT hint array.
* Thus C0 is a dummy.
* Thus C0 is a dummy.
*/
*/
static
struct
cpuidle_state
nehalem_cstates
[
MWAIT_MAX_NUM_CSTATES
]
=
{
static
struct
cpuidle_state
nehalem_cstates
[
CPUIDLE_STATE_MAX
]
=
{
{
/* MWAIT C0 */
},
{
{
/* MWAIT C1 */
.
name
=
"C1-NHM"
,
.
name
=
"C1-NHM"
,
.
desc
=
"MWAIT 0x00"
,
.
desc
=
"MWAIT 0x00"
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
3
,
.
exit_latency
=
3
,
.
target_residency
=
6
,
.
target_residency
=
6
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C2 */
{
.
name
=
"C1E-NHM"
,
.
desc
=
"MWAIT 0x01"
,
.
flags
=
MWAIT2flg
(
0x01
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
10
,
.
target_residency
=
20
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C3-NHM"
,
.
name
=
"C3-NHM"
,
.
desc
=
"MWAIT 0x10"
,
.
desc
=
"MWAIT 0x10"
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
20
,
.
exit_latency
=
20
,
.
target_residency
=
80
,
.
target_residency
=
80
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C3 */
{
.
name
=
"C6-NHM"
,
.
name
=
"C6-NHM"
,
.
desc
=
"MWAIT 0x20"
,
.
desc
=
"MWAIT 0x20"
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
200
,
.
exit_latency
=
200
,
.
target_residency
=
800
,
.
target_residency
=
800
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
.
enter
=
NULL
}
};
};
static
struct
cpuidle_state
snb_cstates
[
MWAIT_MAX_NUM_CSTATES
]
=
{
static
struct
cpuidle_state
snb_cstates
[
CPUIDLE_STATE_MAX
]
=
{
{
/* MWAIT C0 */
},
{
{
/* MWAIT C1 */
.
name
=
"C1-SNB"
,
.
name
=
"C1-SNB"
,
.
desc
=
"MWAIT 0x00"
,
.
desc
=
"MWAIT 0x00"
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
1
,
.
exit_latency
=
2
,
.
target_residency
=
1
,
.
target_residency
=
2
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C2 */
{
.
name
=
"C1E-SNB"
,
.
desc
=
"MWAIT 0x01"
,
.
flags
=
MWAIT2flg
(
0x01
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
10
,
.
target_residency
=
20
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C3-SNB"
,
.
name
=
"C3-SNB"
,
.
desc
=
"MWAIT 0x10"
,
.
desc
=
"MWAIT 0x10"
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
80
,
.
exit_latency
=
80
,
.
target_residency
=
211
,
.
target_residency
=
211
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C3 */
{
.
name
=
"C6-SNB"
,
.
name
=
"C6-SNB"
,
.
desc
=
"MWAIT 0x20"
,
.
desc
=
"MWAIT 0x20"
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
104
,
.
exit_latency
=
104
,
.
target_residency
=
345
,
.
target_residency
=
345
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C4 */
{
.
name
=
"C7-SNB"
,
.
name
=
"C7-SNB"
,
.
desc
=
"MWAIT 0x30"
,
.
desc
=
"MWAIT 0x30"
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
109
,
.
exit_latency
=
109
,
.
target_residency
=
345
,
.
target_residency
=
345
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
.
enter
=
NULL
}
};
};
static
struct
cpuidle_state
ivb_cstates
[
MWAIT_MAX_NUM_CSTATES
]
=
{
static
struct
cpuidle_state
ivb_cstates
[
CPUIDLE_STATE_MAX
]
=
{
{
/* MWAIT C0 */
},
{
{
/* MWAIT C1 */
.
name
=
"C1-IVB"
,
.
name
=
"C1-IVB"
,
.
desc
=
"MWAIT 0x00"
,
.
desc
=
"MWAIT 0x00"
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
1
,
.
exit_latency
=
1
,
.
target_residency
=
1
,
.
target_residency
=
1
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C2 */
{
.
name
=
"C1E-IVB"
,
.
desc
=
"MWAIT 0x01"
,
.
flags
=
MWAIT2flg
(
0x01
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
10
,
.
target_residency
=
20
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C3-IVB"
,
.
name
=
"C3-IVB"
,
.
desc
=
"MWAIT 0x10"
,
.
desc
=
"MWAIT 0x10"
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
59
,
.
exit_latency
=
59
,
.
target_residency
=
156
,
.
target_residency
=
156
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C3 */
{
.
name
=
"C6-IVB"
,
.
name
=
"C6-IVB"
,
.
desc
=
"MWAIT 0x20"
,
.
desc
=
"MWAIT 0x20"
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
80
,
.
exit_latency
=
80
,
.
target_residency
=
300
,
.
target_residency
=
300
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C4 */
{
.
name
=
"C7-IVB"
,
.
name
=
"C7-IVB"
,
.
desc
=
"MWAIT 0x30"
,
.
desc
=
"MWAIT 0x30"
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
87
,
.
exit_latency
=
87
,
.
target_residency
=
300
,
.
target_residency
=
300
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
.
enter
=
NULL
}
};
};
static
struct
cpuidle_state
atom_cstates
[
MWAIT_MAX_NUM_CSTATES
]
=
{
static
struct
cpuidle_state
hsw_cstates
[
CPUIDLE_STATE_MAX
]
=
{
{
/* MWAIT C0 */
},
{
{
/* MWAIT C1 */
.
name
=
"C1-HSW"
,
.
name
=
"C1-ATM"
,
.
desc
=
"MWAIT 0x00"
,
.
desc
=
"MWAIT 0x00"
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
1
,
.
exit_latency
=
2
,
.
target_residency
=
4
,
.
target_residency
=
2
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C2 */
{
.
name
=
"C1E-HSW"
,
.
desc
=
"MWAIT 0x01"
,
.
flags
=
MWAIT2flg
(
0x01
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
10
,
.
target_residency
=
20
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C3-HSW"
,
.
desc
=
"MWAIT 0x10"
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
33
,
.
target_residency
=
100
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C6-HSW"
,
.
desc
=
"MWAIT 0x20"
,
.
flags
=
MWAIT2flg
(
0x20
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
133
,
.
target_residency
=
400
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C7s-HSW"
,
.
desc
=
"MWAIT 0x32"
,
.
flags
=
MWAIT2flg
(
0x32
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
166
,
.
target_residency
=
500
,
.
enter
=
&
intel_idle
},
{
.
enter
=
NULL
}
};
static
struct
cpuidle_state
atom_cstates
[
CPUIDLE_STATE_MAX
]
=
{
{
.
name
=
"C1E-ATM"
,
.
desc
=
"MWAIT 0x00"
,
.
flags
=
MWAIT2flg
(
0x00
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
10
,
.
target_residency
=
20
,
.
enter
=
&
intel_idle
},
{
.
name
=
"C2-ATM"
,
.
name
=
"C2-ATM"
,
.
desc
=
"MWAIT 0x10"
,
.
desc
=
"MWAIT 0x10"
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
flags
=
MWAIT2flg
(
0x10
)
|
CPUIDLE_FLAG_TIME_VALID
,
.
exit_latency
=
20
,
.
exit_latency
=
20
,
.
target_residency
=
80
,
.
target_residency
=
80
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C3 */
},
{
{
/* MWAIT C4 */
.
name
=
"C4-ATM"
,
.
name
=
"C4-ATM"
,
.
desc
=
"MWAIT 0x30"
,
.
desc
=
"MWAIT 0x30"
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x30
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
100
,
.
exit_latency
=
100
,
.
target_residency
=
400
,
.
target_residency
=
400
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
/* MWAIT C5 */
},
{
{
/* MWAIT C6 */
.
name
=
"C6-ATM"
,
.
name
=
"C6-ATM"
,
.
desc
=
"MWAIT 0x52"
,
.
desc
=
"MWAIT 0x52"
,
.
flags
=
MWAIT2flg
(
0x52
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
flags
=
MWAIT2flg
(
0x52
)
|
CPUIDLE_FLAG_TIME_VALID
|
CPUIDLE_FLAG_TLB_FLUSHED
,
.
exit_latency
=
140
,
.
exit_latency
=
140
,
.
target_residency
=
560
,
.
target_residency
=
560
,
.
enter
=
&
intel_idle
},
.
enter
=
&
intel_idle
},
{
.
enter
=
NULL
}
};
};
/**
/**
...
@@ -342,10 +406,19 @@ static void auto_demotion_disable(void *dummy)
...
@@ -342,10 +406,19 @@ static void auto_demotion_disable(void *dummy)
msr_bits
&=
~
(
icpu
->
auto_demotion_disable_flags
);
msr_bits
&=
~
(
icpu
->
auto_demotion_disable_flags
);
wrmsrl
(
MSR_NHM_SNB_PKG_CST_CFG_CTL
,
msr_bits
);
wrmsrl
(
MSR_NHM_SNB_PKG_CST_CFG_CTL
,
msr_bits
);
}
}
static
void
c1e_promotion_disable
(
void
*
dummy
)
{
unsigned
long
long
msr_bits
;
rdmsrl
(
MSR_IA32_POWER_CTL
,
msr_bits
);
msr_bits
&=
~
0x2
;
wrmsrl
(
MSR_IA32_POWER_CTL
,
msr_bits
);
}
static
const
struct
idle_cpu
idle_cpu_nehalem
=
{
static
const
struct
idle_cpu
idle_cpu_nehalem
=
{
.
state_table
=
nehalem_cstates
,
.
state_table
=
nehalem_cstates
,
.
auto_demotion_disable_flags
=
NHM_C1_AUTO_DEMOTE
|
NHM_C3_AUTO_DEMOTE
,
.
auto_demotion_disable_flags
=
NHM_C1_AUTO_DEMOTE
|
NHM_C3_AUTO_DEMOTE
,
.
disable_promotion_to_c1e
=
true
,
};
};
static
const
struct
idle_cpu
idle_cpu_atom
=
{
static
const
struct
idle_cpu
idle_cpu_atom
=
{
...
@@ -359,10 +432,17 @@ static const struct idle_cpu idle_cpu_lincroft = {
...
@@ -359,10 +432,17 @@ static const struct idle_cpu idle_cpu_lincroft = {
static
const
struct
idle_cpu
idle_cpu_snb
=
{
static
const
struct
idle_cpu
idle_cpu_snb
=
{
.
state_table
=
snb_cstates
,
.
state_table
=
snb_cstates
,
.
disable_promotion_to_c1e
=
true
,
};
};
static
const
struct
idle_cpu
idle_cpu_ivb
=
{
static
const
struct
idle_cpu
idle_cpu_ivb
=
{
.
state_table
=
ivb_cstates
,
.
state_table
=
ivb_cstates
,
.
disable_promotion_to_c1e
=
true
,
};
static
const
struct
idle_cpu
idle_cpu_hsw
=
{
.
state_table
=
hsw_cstates
,
.
disable_promotion_to_c1e
=
true
,
};
};
#define ICPU(model, cpu) \
#define ICPU(model, cpu) \
...
@@ -382,6 +462,9 @@ static const struct x86_cpu_id intel_idle_ids[] = {
...
@@ -382,6 +462,9 @@ static const struct x86_cpu_id intel_idle_ids[] = {
ICPU
(
0x2d
,
idle_cpu_snb
),
ICPU
(
0x2d
,
idle_cpu_snb
),
ICPU
(
0x3a
,
idle_cpu_ivb
),
ICPU
(
0x3a
,
idle_cpu_ivb
),
ICPU
(
0x3e
,
idle_cpu_ivb
),
ICPU
(
0x3e
,
idle_cpu_ivb
),
ICPU
(
0x3c
,
idle_cpu_hsw
),
ICPU
(
0x3f
,
idle_cpu_hsw
),
ICPU
(
0x45
,
idle_cpu_hsw
),
{}
{}
};
};
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_idle_ids
);
MODULE_DEVICE_TABLE
(
x86cpu
,
intel_idle_ids
);
...
@@ -464,32 +547,31 @@ static int intel_idle_cpuidle_driver_init(void)
...
@@ -464,32 +547,31 @@ static int intel_idle_cpuidle_driver_init(void)
drv
->
state_count
=
1
;
drv
->
state_count
=
1
;
for
(
cstate
=
1
;
cstate
<
MWAIT_MAX_NUM_CSTATES
;
++
cstate
)
{
for
(
cstate
=
0
;
cstate
<
CPUIDLE_STATE_MAX
;
++
cstate
)
{
int
num_substates
;
int
num_substates
,
mwait_hint
,
mwait_cstate
,
mwait_substate
;
if
(
cstate
>
max_cstate
)
{
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
break
;
if
(
cstate
+
1
>
max_cstate
)
{
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
max_cstate
);
max_cstate
);
break
;
break
;
}
}
mwait_hint
=
flg2MWAIT
(
cpuidle_state_table
[
cstate
].
flags
);
mwait_cstate
=
MWAIT_HINT2CSTATE
(
mwait_hint
);
mwait_substate
=
MWAIT_HINT2SUBSTATE
(
mwait_hint
);
/* does the state exist in CPUID.MWAIT? */
/* does the state exist in CPUID.MWAIT? */
num_substates
=
(
mwait_substates
>>
((
cstate
)
*
4
))
num_substates
=
(
mwait_substates
>>
((
mwait_cstate
+
1
)
*
4
))
&
MWAIT_SUBSTATE_MASK
;
&
MWAIT_SUBSTATE_MASK
;
if
(
num_substates
==
0
)
continue
;
/* if sub-state in table is not enumerated by CPUID */
/* is the state not enabled? */
if
((
mwait_substate
+
1
)
>
num_substates
)
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
{
/* does the driver not know about the state? */
if
(
*
cpuidle_state_table
[
cstate
].
name
==
'\0'
)
pr_debug
(
PREFIX
"unaware of model 0x%x"
" MWAIT %d please"
" contact lenb@kernel.org
\n
"
,
boot_cpu_data
.
x86_model
,
cstate
);
continue
;
continue
;
}
if
((
cstate
>
2
)
&&
if
((
(
mwait_cstate
+
1
)
>
2
)
&&
!
boot_cpu_has
(
X86_FEATURE_NONSTOP_TSC
))
!
boot_cpu_has
(
X86_FEATURE_NONSTOP_TSC
))
mark_tsc_unstable
(
"TSC halts in idle"
mark_tsc_unstable
(
"TSC halts in idle"
" states deeper than C2"
);
" states deeper than C2"
);
...
@@ -503,6 +585,9 @@ static int intel_idle_cpuidle_driver_init(void)
...
@@ -503,6 +585,9 @@ static int intel_idle_cpuidle_driver_init(void)
if
(
icpu
->
auto_demotion_disable_flags
)
if
(
icpu
->
auto_demotion_disable_flags
)
on_each_cpu
(
auto_demotion_disable
,
NULL
,
1
);
on_each_cpu
(
auto_demotion_disable
,
NULL
,
1
);
if
(
icpu
->
disable_promotion_to_c1e
)
/* each-cpu is redundant */
on_each_cpu
(
c1e_promotion_disable
,
NULL
,
1
);
return
0
;
return
0
;
}
}
...
@@ -521,21 +606,27 @@ static int intel_idle_cpu_init(int cpu)
...
@@ -521,21 +606,27 @@ static int intel_idle_cpu_init(int cpu)
dev
->
state_count
=
1
;
dev
->
state_count
=
1
;
for
(
cstate
=
1
;
cstate
<
MWAIT_MAX_NUM_CSTATES
;
++
cstate
)
{
for
(
cstate
=
0
;
cstate
<
CPUIDLE_STATE_MAX
;
++
cstate
)
{
int
num_substates
;
int
num_substates
,
mwait_hint
,
mwait_cstate
,
mwait_substate
;
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
continue
;
if
(
cstate
>
max_cstate
)
{
if
(
cstate
+
1
>
max_cstate
)
{
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
max_cstate
);
printk
(
PREFIX
"max_cstate %d reached
\n
"
,
max_cstate
);
break
;
break
;
}
}
mwait_hint
=
flg2MWAIT
(
cpuidle_state_table
[
cstate
].
flags
);
mwait_cstate
=
MWAIT_HINT2CSTATE
(
mwait_hint
);
mwait_substate
=
MWAIT_HINT2SUBSTATE
(
mwait_hint
);
/* does the state exist in CPUID.MWAIT? */
/* does the state exist in CPUID.MWAIT? */
num_substates
=
(
mwait_substates
>>
((
cstate
)
*
4
))
num_substates
=
(
mwait_substates
>>
((
mwait_cstate
+
1
)
*
4
))
&
MWAIT_SUBSTATE_MASK
;
&
MWAIT_SUBSTATE_MASK
;
if
(
num_substates
==
0
)
continue
;
/* if sub-state in table is not enumerated by CPUID */
/* is the state not enabled? */
if
((
mwait_substate
+
1
)
>
num_substates
)
if
(
cpuidle_state_table
[
cstate
].
enter
==
NULL
)
continue
;
continue
;
dev
->
state_count
+=
1
;
dev
->
state_count
+=
1
;
...
...
include/linux/pm.h
浏览文件 @
2e7d0f60
...
@@ -31,7 +31,6 @@
...
@@ -31,7 +31,6 @@
/*
/*
* Callbacks for platform drivers to implement.
* Callbacks for platform drivers to implement.
*/
*/
extern
void
(
*
pm_idle
)(
void
);
extern
void
(
*
pm_power_off
)(
void
);
extern
void
(
*
pm_power_off
)(
void
);
extern
void
(
*
pm_power_off_prepare
)(
void
);
extern
void
(
*
pm_power_off_prepare
)(
void
);
...
...
tools/power/x86/turbostat/turbostat.8
浏览文件 @
2e7d0f60
...
@@ -31,8 +31,6 @@ The \fB-S\fP option limits output to a 1-line System Summary for each interval.
...
@@ -31,8 +31,6 @@ The \fB-S\fP option limits output to a 1-line System Summary for each interval.
.PP
.PP
The \fB-v\fP option increases verbosity.
The \fB-v\fP option increases verbosity.
.PP
.PP
The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
.PP
The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
.PP
.PP
The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
...
@@ -186,26 +184,24 @@ This is a weighted average, where the weight is %c0. ie. it is the total number
...
@@ -186,26 +184,24 @@ This is a weighted average, where the weight is %c0. ie. it is the total number
un-halted cycles elapsed per time divided by the number of CPUs.
un-halted cycles elapsed per time divided by the number of CPUs.
.SH SMI COUNTING EXAMPLE
.SH SMI COUNTING EXAMPLE
On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
Using the -m option, you can display how many SMIs have fired since reset, or if there
This counter is shown by default under the "SMI" column.
are SMIs during the measurement interval, you can display the delta using the -d option.
.nf
.nf
[root@x980 ~]# turbostat
-m 0x34
[root@x980 ~]# turbostat
cor CPU %c0 GHz TSC
MSR 0x034 %c1 %c3 %c6
%pc3 %pc6
cor CPU %c0 GHz TSC
SMI %c1 %c3 %c6 CTMP
%pc3 %pc6
1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55
0.11 1.91 3.38 0 1.84 0.26 97.79 29 0.82 83.87
0 0
3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55
0 0
0.40 1.63 3.38 0 10.27 0.12 89.20 20 0.82 83.88
0 6 0.
14 1.63 3.38 0x00000056 5.30
0 6 0.
06 1.63 3.38 0 10.61
1 2
2.51 1.80 3.38 0x00000056 15.65 29.33 52.5
2
1 2
0.37 2.63 3.38 0 0.02 0.10 99.51 2
2
1 8 0.
10 1.65 3.38 0x00000056 18.05
1 8 0.
01 1.62 3.38 0 0.39
2 4
1.16 1.68 3.38 0x00000056 5.87 24.47 68.50
2 4
0.07 1.62 3.38 0 0.04 0.07 99.82 23
2 10 0.
10 1.63 3.38 0x00000056 6.93
2 10 0.
02 1.62 3.38 0 0.09
8 1
3.84 1.91 3.38 0x00000056 1.36 50.65 44.16
8 1
0.23 1.64 3.38 0 0.10 1.07 98.60 24
8 7 0.0
8 1.64 3.38 0x00000056 5.12
8 7 0.0
2 1.64 3.38 0 0.31
9 3
1.82 1.73 3.38 0x00000056 7.59 24.21 66.38
9 3
0.03 1.62 3.38 0 0.03 0.05 99.89 29
9 9 0.0
9 1.68 3.38 0x00000056 9.32
9 9 0.0
2 1.62 3.38 0 0.05
10 5
1.66 1.65 3.38 0x00000056 15.10 50.00 33.23
10 5
0.07 1.62 3.38 0 0.08 0.12 99.73 27
10 11
1.72 1.65 3.38 0x00000056 15.05
10 11
0.03 1.62 3.38 0 0.13
^C
^C
[root@x980 ~]#
.fi
.fi
.SH NOTES
.SH NOTES
...
...
tools/power/x86/turbostat/turbostat.c
浏览文件 @
2e7d0f60
...
@@ -58,6 +58,7 @@ unsigned int extra_msr_offset32;
...
@@ -58,6 +58,7 @@ unsigned int extra_msr_offset32;
unsigned
int
extra_msr_offset64
;
unsigned
int
extra_msr_offset64
;
unsigned
int
extra_delta_offset32
;
unsigned
int
extra_delta_offset32
;
unsigned
int
extra_delta_offset64
;
unsigned
int
extra_delta_offset64
;
int
do_smi
;
double
bclk
;
double
bclk
;
unsigned
int
show_pkg
;
unsigned
int
show_pkg
;
unsigned
int
show_core
;
unsigned
int
show_core
;
...
@@ -99,6 +100,7 @@ struct thread_data {
...
@@ -99,6 +100,7 @@ struct thread_data {
unsigned
long
long
extra_delta64
;
unsigned
long
long
extra_delta64
;
unsigned
long
long
extra_msr32
;
unsigned
long
long
extra_msr32
;
unsigned
long
long
extra_delta32
;
unsigned
long
long
extra_delta32
;
unsigned
int
smi_count
;
unsigned
int
cpu_id
;
unsigned
int
cpu_id
;
unsigned
int
flags
;
unsigned
int
flags
;
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2
...
@@ -248,6 +250,8 @@ void print_header(void)
...
@@ -248,6 +250,8 @@ void print_header(void)
if
(
has_aperf
)
if
(
has_aperf
)
outp
+=
sprintf
(
outp
,
" GHz"
);
outp
+=
sprintf
(
outp
,
" GHz"
);
outp
+=
sprintf
(
outp
,
" TSC"
);
outp
+=
sprintf
(
outp
,
" TSC"
);
if
(
do_smi
)
outp
+=
sprintf
(
outp
,
" SMI"
);
if
(
extra_delta_offset32
)
if
(
extra_delta_offset32
)
outp
+=
sprintf
(
outp
,
" count 0x%03X"
,
extra_delta_offset32
);
outp
+=
sprintf
(
outp
,
" count 0x%03X"
,
extra_delta_offset32
);
if
(
extra_delta_offset64
)
if
(
extra_delta_offset64
)
...
@@ -314,6 +318,8 @@ int dump_counters(struct thread_data *t, struct core_data *c,
...
@@ -314,6 +318,8 @@ int dump_counters(struct thread_data *t, struct core_data *c,
extra_msr_offset32
,
t
->
extra_msr32
);
extra_msr_offset32
,
t
->
extra_msr32
);
fprintf
(
stderr
,
"msr0x%x: %016llX
\n
"
,
fprintf
(
stderr
,
"msr0x%x: %016llX
\n
"
,
extra_msr_offset64
,
t
->
extra_msr64
);
extra_msr_offset64
,
t
->
extra_msr64
);
if
(
do_smi
)
fprintf
(
stderr
,
"SMI: %08X
\n
"
,
t
->
smi_count
);
}
}
if
(
c
)
{
if
(
c
)
{
...
@@ -352,6 +358,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
...
@@ -352,6 +358,7 @@ int dump_counters(struct thread_data *t, struct core_data *c,
* RAM_W: %5.2
* RAM_W: %5.2
* GHz: "GHz" 3 columns %3.2
* GHz: "GHz" 3 columns %3.2
* TSC: "TSC" 3 columns %3.2
* TSC: "TSC" 3 columns %3.2
* SMI: "SMI" 4 columns %4d
* percentage " %pc3" %6.2
* percentage " %pc3" %6.2
* Perf Status percentage: %5.2
* Perf Status percentage: %5.2
* "CTMP" 4 columns %4d
* "CTMP" 4 columns %4d
...
@@ -431,6 +438,10 @@ int format_counters(struct thread_data *t, struct core_data *c,
...
@@ -431,6 +438,10 @@ int format_counters(struct thread_data *t, struct core_data *c,
/* TSC */
/* TSC */
outp
+=
sprintf
(
outp
,
"%5.2f"
,
1
.
0
*
t
->
tsc
/
units
/
interval_float
);
outp
+=
sprintf
(
outp
,
"%5.2f"
,
1
.
0
*
t
->
tsc
/
units
/
interval_float
);
/* SMI */
if
(
do_smi
)
outp
+=
sprintf
(
outp
,
"%4d"
,
t
->
smi_count
);
/* delta */
/* delta */
if
(
extra_delta_offset32
)
if
(
extra_delta_offset32
)
outp
+=
sprintf
(
outp
,
" %11llu"
,
t
->
extra_delta32
);
outp
+=
sprintf
(
outp
,
" %11llu"
,
t
->
extra_delta32
);
...
@@ -645,6 +656,9 @@ delta_thread(struct thread_data *new, struct thread_data *old,
...
@@ -645,6 +656,9 @@ delta_thread(struct thread_data *new, struct thread_data *old,
*/
*/
old
->
extra_msr32
=
new
->
extra_msr32
;
old
->
extra_msr32
=
new
->
extra_msr32
;
old
->
extra_msr64
=
new
->
extra_msr64
;
old
->
extra_msr64
=
new
->
extra_msr64
;
if
(
do_smi
)
old
->
smi_count
=
new
->
smi_count
-
old
->
smi_count
;
}
}
int
delta_cpu
(
struct
thread_data
*
t
,
struct
core_data
*
c
,
int
delta_cpu
(
struct
thread_data
*
t
,
struct
core_data
*
c
,
...
@@ -672,6 +686,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
...
@@ -672,6 +686,7 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
t
->
mperf
=
0
;
t
->
mperf
=
0
;
t
->
c1
=
0
;
t
->
c1
=
0
;
t
->
smi_count
=
0
;
t
->
extra_delta32
=
0
;
t
->
extra_delta32
=
0
;
t
->
extra_delta64
=
0
;
t
->
extra_delta64
=
0
;
...
@@ -802,6 +817,11 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
...
@@ -802,6 +817,11 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return
-
4
;
return
-
4
;
}
}
if
(
do_smi
)
{
if
(
get_msr
(
cpu
,
MSR_SMI_COUNT
,
&
msr
))
return
-
5
;
t
->
smi_count
=
msr
&
0xFFFFFFFF
;
}
if
(
extra_delta_offset32
)
{
if
(
extra_delta_offset32
)
{
if
(
get_msr
(
cpu
,
extra_delta_offset32
,
&
msr
))
if
(
get_msr
(
cpu
,
extra_delta_offset32
,
&
msr
))
return
-
5
;
return
-
5
;
...
@@ -908,8 +928,7 @@ void print_verbose_header(void)
...
@@ -908,8 +928,7 @@ void print_verbose_header(void)
get_msr
(
0
,
MSR_NHM_PLATFORM_INFO
,
&
msr
);
get_msr
(
0
,
MSR_NHM_PLATFORM_INFO
,
&
msr
);
if
(
verbose
)
fprintf
(
stderr
,
"cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx
\n
"
,
msr
);
fprintf
(
stderr
,
"cpu0: MSR_NHM_PLATFORM_INFO: 0x%08llx
\n
"
,
msr
);
ratio
=
(
msr
>>
40
)
&
0xFF
;
ratio
=
(
msr
>>
40
)
&
0xFF
;
fprintf
(
stderr
,
"%d * %.0f = %.0f MHz max efficiency
\n
"
,
fprintf
(
stderr
,
"%d * %.0f = %.0f MHz max efficiency
\n
"
,
...
@@ -919,13 +938,16 @@ void print_verbose_header(void)
...
@@ -919,13 +938,16 @@ void print_verbose_header(void)
fprintf
(
stderr
,
"%d * %.0f = %.0f MHz TSC frequency
\n
"
,
fprintf
(
stderr
,
"%d * %.0f = %.0f MHz TSC frequency
\n
"
,
ratio
,
bclk
,
ratio
*
bclk
);
ratio
,
bclk
,
ratio
*
bclk
);
get_msr
(
0
,
MSR_IA32_POWER_CTL
,
&
msr
);
fprintf
(
stderr
,
"cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E: %sabled)
\n
"
,
msr
,
msr
&
0x2
?
"EN"
:
"DIS"
);
if
(
!
do_ivt_turbo_ratio_limit
)
if
(
!
do_ivt_turbo_ratio_limit
)
goto
print_nhm_turbo_ratio_limits
;
goto
print_nhm_turbo_ratio_limits
;
get_msr
(
0
,
MSR_IVT_TURBO_RATIO_LIMIT
,
&
msr
);
get_msr
(
0
,
MSR_IVT_TURBO_RATIO_LIMIT
,
&
msr
);
if
(
verbose
)
fprintf
(
stderr
,
"cpu0: MSR_IVT_TURBO_RATIO_LIMIT: 0x%08llx
\n
"
,
msr
);
fprintf
(
stderr
,
"cpu0: MSR_IVT_TURBO_RATIO_LIMIT: 0x%08llx
\n
"
,
msr
);
ratio
=
(
msr
>>
56
)
&
0xFF
;
ratio
=
(
msr
>>
56
)
&
0xFF
;
if
(
ratio
)
if
(
ratio
)
...
@@ -1016,8 +1038,7 @@ void print_verbose_header(void)
...
@@ -1016,8 +1038,7 @@ void print_verbose_header(void)
get_msr
(
0
,
MSR_NHM_TURBO_RATIO_LIMIT
,
&
msr
);
get_msr
(
0
,
MSR_NHM_TURBO_RATIO_LIMIT
,
&
msr
);
if
(
verbose
)
fprintf
(
stderr
,
"cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx
\n
"
,
msr
);
fprintf
(
stderr
,
"cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x%08llx
\n
"
,
msr
);
ratio
=
(
msr
>>
56
)
&
0xFF
;
ratio
=
(
msr
>>
56
)
&
0xFF
;
if
(
ratio
)
if
(
ratio
)
...
@@ -1397,6 +1418,9 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
...
@@ -1397,6 +1418,9 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
case
0x2D
:
/* SNB Xeon */
case
0x2D
:
/* SNB Xeon */
case
0x3A
:
/* IVB */
case
0x3A
:
/* IVB */
case
0x3E
:
/* IVB Xeon */
case
0x3E
:
/* IVB Xeon */
case
0x3C
:
/* HSW */
case
0x3F
:
/* HSW */
case
0x45
:
/* HSW */
return
1
;
return
1
;
case
0x2E
:
/* Nehalem-EX Xeon - Beckton */
case
0x2E
:
/* Nehalem-EX Xeon - Beckton */
case
0x2F
:
/* Westmere-EX Xeon - Eagleton */
case
0x2F
:
/* Westmere-EX Xeon - Eagleton */
...
@@ -1488,6 +1512,9 @@ void rapl_probe(unsigned int family, unsigned int model)
...
@@ -1488,6 +1512,9 @@ void rapl_probe(unsigned int family, unsigned int model)
switch
(
model
)
{
switch
(
model
)
{
case
0x2A
:
case
0x2A
:
case
0x3A
:
case
0x3A
:
case
0x3C
:
/* HSW */
case
0x3F
:
/* HSW */
case
0x45
:
/* HSW */
do_rapl
=
RAPL_PKG
|
RAPL_CORES
|
RAPL_GFX
;
do_rapl
=
RAPL_PKG
|
RAPL_CORES
|
RAPL_GFX
;
break
;
break
;
case
0x2D
:
case
0x2D
:
...
@@ -1724,6 +1751,9 @@ int is_snb(unsigned int family, unsigned int model)
...
@@ -1724,6 +1751,9 @@ int is_snb(unsigned int family, unsigned int model)
case
0x2D
:
case
0x2D
:
case
0x3A
:
/* IVB */
case
0x3A
:
/* IVB */
case
0x3E
:
/* IVB Xeon */
case
0x3E
:
/* IVB Xeon */
case
0x3C
:
/* HSW */
case
0x3F
:
/* HSW */
case
0x45
:
/* HSW */
return
1
;
return
1
;
}
}
return
0
;
return
0
;
...
@@ -1883,6 +1913,7 @@ void check_cpuid()
...
@@ -1883,6 +1913,7 @@ void check_cpuid()
do_nehalem_platform_info
=
genuine_intel
&&
has_invariant_tsc
;
do_nehalem_platform_info
=
genuine_intel
&&
has_invariant_tsc
;
do_nhm_cstates
=
genuine_intel
;
/* all Intel w/ non-stop TSC have NHM counters */
do_nhm_cstates
=
genuine_intel
;
/* all Intel w/ non-stop TSC have NHM counters */
do_smi
=
do_nhm_cstates
;
do_snb_cstates
=
is_snb
(
family
,
model
);
do_snb_cstates
=
is_snb
(
family
,
model
);
bclk
=
discover_bclk
(
family
,
model
);
bclk
=
discover_bclk
(
family
,
model
);
...
@@ -2219,9 +2250,6 @@ void cmdline(int argc, char **argv)
...
@@ -2219,9 +2250,6 @@ void cmdline(int argc, char **argv)
case
'c'
:
case
'c'
:
sscanf
(
optarg
,
"%x"
,
&
extra_delta_offset32
);
sscanf
(
optarg
,
"%x"
,
&
extra_delta_offset32
);
break
;
break
;
case
's'
:
extra_delta_offset32
=
0x34
;
/* SMI counter */
break
;
case
'C'
:
case
'C'
:
sscanf
(
optarg
,
"%x"
,
&
extra_delta_offset64
);
sscanf
(
optarg
,
"%x"
,
&
extra_delta_offset64
);
break
;
break
;
...
@@ -2248,7 +2276,7 @@ int main(int argc, char **argv)
...
@@ -2248,7 +2276,7 @@ int main(int argc, char **argv)
cmdline
(
argc
,
argv
);
cmdline
(
argc
,
argv
);
if
(
verbose
)
if
(
verbose
)
fprintf
(
stderr
,
"turbostat v3.
0 November 23, 2012
"
fprintf
(
stderr
,
"turbostat v3.
2 February 11, 2013
"
" - Len Brown <lenb@kernel.org>
\n
"
);
" - Len Brown <lenb@kernel.org>
\n
"
);
turbostat_init
();
turbostat_init
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录