Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
aa9abe2c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
aa9abe2c
编写于
5月 07, 2014
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pm-cpuidle' into pm-sleep
上级
2c730785
a6220fc1
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
62 addition
and
39 deletion
+62
-39
drivers/cpuidle/cpuidle.c
drivers/cpuidle/cpuidle.c
+42
-13
drivers/cpuidle/governors/menu.c
drivers/cpuidle/governors/menu.c
+9
-8
include/linux/cpuidle.h
include/linux/cpuidle.h
+2
-5
kernel/power/suspend.c
kernel/power/suspend.c
+2
-0
kernel/sched/idle.c
kernel/sched/idle.c
+7
-13
未找到文件。
drivers/cpuidle/cpuidle.c
浏览文件 @
aa9abe2c
...
...
@@ -32,6 +32,7 @@ LIST_HEAD(cpuidle_detected_devices);
static
int
enabled_devices
;
static
int
off
__read_mostly
;
static
int
initialized
__read_mostly
;
static
bool
use_deepest_state
__read_mostly
;
int
cpuidle_disabled
(
void
)
{
...
...
@@ -65,23 +66,42 @@ int cpuidle_play_dead(void)
}
/**
* cpuidle_enabled - check if the cpuidle framework is ready
* @dev: cpuidle device for this cpu
* @drv: cpuidle driver for this cpu
* cpuidle_use_deepest_state - Enable/disable the "deepest idle" mode.
* @enable: Whether enable or disable the feature.
*
* If the "deepest idle" mode is enabled, cpuidle will ignore the governor and
* always use the state with the greatest exit latency (out of the states that
* are not disabled).
*
* Return 0 on success, otherwise:
* -NODEV : the cpuidle framework is not available
* -EBUSY : the cpuidle framework is not initialized
* This function can only be called after cpuidle_pause() to avoid races.
*/
int
cpuidle_enabled
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
)
void
cpuidle_use_deepest_state
(
bool
enable
)
{
if
(
off
||
!
initialized
)
return
-
ENODEV
;
use_deepest_state
=
enable
;
}
if
(
!
drv
||
!
dev
||
!
dev
->
enabled
)
return
-
EBUSY
;
/**
* cpuidle_find_deepest_state - Find the state of the greatest exit latency.
* @drv: cpuidle driver for a given CPU.
* @dev: cpuidle device for a given CPU.
*/
static
int
cpuidle_find_deepest_state
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
)
{
unsigned
int
latency_req
=
0
;
int
i
,
ret
=
CPUIDLE_DRIVER_STATE_START
-
1
;
return
0
;
for
(
i
=
CPUIDLE_DRIVER_STATE_START
;
i
<
drv
->
state_count
;
i
++
)
{
struct
cpuidle_state
*
s
=
&
drv
->
states
[
i
];
struct
cpuidle_state_usage
*
su
=
&
dev
->
states_usage
[
i
];
if
(
s
->
disabled
||
su
->
disable
||
s
->
exit_latency
<=
latency_req
)
continue
;
latency_req
=
s
->
exit_latency
;
ret
=
i
;
}
return
ret
;
}
/**
...
...
@@ -138,6 +158,15 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
*/
int
cpuidle_select
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
)
{
if
(
off
||
!
initialized
)
return
-
ENODEV
;
if
(
!
drv
||
!
dev
||
!
dev
->
enabled
)
return
-
EBUSY
;
if
(
unlikely
(
use_deepest_state
))
return
cpuidle_find_deepest_state
(
drv
,
dev
);
return
cpuidle_curr_governor
->
select
(
drv
,
dev
);
}
...
...
@@ -169,7 +198,7 @@ int cpuidle_enter(struct cpuidle_driver *drv, struct cpuidle_device *dev,
*/
void
cpuidle_reflect
(
struct
cpuidle_device
*
dev
,
int
index
)
{
if
(
cpuidle_curr_governor
->
reflect
)
if
(
cpuidle_curr_governor
->
reflect
&&
!
unlikely
(
use_deepest_state
)
)
cpuidle_curr_governor
->
reflect
(
dev
,
index
);
}
...
...
drivers/cpuidle/governors/menu.c
浏览文件 @
aa9abe2c
...
...
@@ -296,7 +296,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
data
->
needs_update
=
0
;
}
data
->
last_state_idx
=
0
;
data
->
last_state_idx
=
CPUIDLE_DRIVER_STATE_START
-
1
;
/* Special case when user has set very strict latency requirement */
if
(
unlikely
(
latency_req
==
0
))
...
...
@@ -310,13 +310,6 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
data
->
bucket
=
which_bucket
(
data
->
next_timer_us
);
/*
* if the correction factor is 0 (eg first time init or cpu hotplug
* etc), we actually want to start out with a unity factor.
*/
if
(
data
->
correction_factor
[
data
->
bucket
]
==
0
)
data
->
correction_factor
[
data
->
bucket
]
=
RESOLUTION
*
DECAY
;
/*
* Force the result of multiplication to be 64 bits even if both
* operands are 32 bits.
...
...
@@ -466,9 +459,17 @@ static int menu_enable_device(struct cpuidle_driver *drv,
struct
cpuidle_device
*
dev
)
{
struct
menu_device
*
data
=
&
per_cpu
(
menu_devices
,
dev
->
cpu
);
int
i
;
memset
(
data
,
0
,
sizeof
(
struct
menu_device
));
/*
* if the correction factor is 0 (eg first time init or cpu hotplug
* etc), we actually want to start out with a unity factor.
*/
for
(
i
=
0
;
i
<
BUCKETS
;
i
++
)
data
->
correction_factor
[
i
]
=
RESOLUTION
*
DECAY
;
return
0
;
}
...
...
include/linux/cpuidle.h
浏览文件 @
aa9abe2c
...
...
@@ -120,8 +120,6 @@ struct cpuidle_driver {
#ifdef CONFIG_CPU_IDLE
extern
void
disable_cpuidle
(
void
);
extern
int
cpuidle_enabled
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
);
extern
int
cpuidle_select
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
);
extern
int
cpuidle_enter
(
struct
cpuidle_driver
*
drv
,
...
...
@@ -145,13 +143,11 @@ extern void cpuidle_resume(void);
extern
int
cpuidle_enable_device
(
struct
cpuidle_device
*
dev
);
extern
void
cpuidle_disable_device
(
struct
cpuidle_device
*
dev
);
extern
int
cpuidle_play_dead
(
void
);
extern
void
cpuidle_use_deepest_state
(
bool
enable
);
extern
struct
cpuidle_driver
*
cpuidle_get_cpu_driver
(
struct
cpuidle_device
*
dev
);
#else
static
inline
void
disable_cpuidle
(
void
)
{
}
static
inline
int
cpuidle_enabled
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
)
{
return
-
ENODEV
;
}
static
inline
int
cpuidle_select
(
struct
cpuidle_driver
*
drv
,
struct
cpuidle_device
*
dev
)
{
return
-
ENODEV
;
}
...
...
@@ -180,6 +176,7 @@ static inline int cpuidle_enable_device(struct cpuidle_device *dev)
{
return
-
ENODEV
;
}
static
inline
void
cpuidle_disable_device
(
struct
cpuidle_device
*
dev
)
{
}
static
inline
int
cpuidle_play_dead
(
void
)
{
return
-
ENODEV
;
}
static
inline
void
cpuidle_use_deepest_state
(
bool
enable
)
{}
static
inline
struct
cpuidle_driver
*
cpuidle_get_cpu_driver
(
struct
cpuidle_device
*
dev
)
{
return
NULL
;
}
#endif
...
...
kernel/power/suspend.c
浏览文件 @
aa9abe2c
...
...
@@ -54,9 +54,11 @@ static void freeze_begin(void)
static
void
freeze_enter
(
void
)
{
cpuidle_use_deepest_state
(
true
);
cpuidle_resume
();
wait_event
(
suspend_freeze_wait_head
,
suspend_freeze_wake
);
cpuidle_pause
();
cpuidle_use_deepest_state
(
false
);
}
void
freeze_wake
(
void
)
...
...
kernel/sched/idle.c
浏览文件 @
aa9abe2c
...
...
@@ -101,19 +101,13 @@ static int cpuidle_idle_call(void)
rcu_idle_enter
();
/*
*
Check if the cpuidle framework is ready, otherwise fallback
*
to the default arch specific idle method
*
Ask the cpuidle framework to choose a convenient idle state.
*
Fall back to the default arch specific idle method on errors.
*/
ret
=
cpuidle_enabled
(
drv
,
dev
);
if
(
!
ret
)
{
/*
* Ask the governor to choose an idle state it thinks
* it is convenient to go to. There is *always* a
* convenient idle state
*/
next_state
=
cpuidle_select
(
drv
,
dev
);
next_state
=
cpuidle_select
(
drv
,
dev
);
ret
=
next_state
;
if
(
ret
>=
0
)
{
/*
* The idle task must be scheduled, it is pointless to
* go to idle, just update no idle residency and get
...
...
@@ -140,7 +134,7 @@ static int cpuidle_idle_call(void)
CLOCK_EVT_NOTIFY_BROADCAST_ENTER
,
&
dev
->
cpu
);
if
(
!
ret
)
{
if
(
ret
>=
0
)
{
trace_cpu_idle_rcuidle
(
next_state
,
dev
->
cpu
);
/*
...
...
@@ -175,7 +169,7 @@ static int cpuidle_idle_call(void)
* We can't use the cpuidle framework, let's use the default
* idle routine
*/
if
(
ret
)
if
(
ret
<
0
)
arch_cpu_idle
();
__current_set_polling
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录