Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
2addac72
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看板
提交
2addac72
编写于
4月 28, 2017
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge schedutil governor updates for v4.12.
上级
2dee4b0e
1b72e7fd
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
76 addition
and
28 deletion
+76
-28
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/intel_pstate.c
+2
-0
include/linux/cpufreq.h
include/linux/cpufreq.h
+7
-0
include/linux/tick.h
include/linux/tick.h
+1
-0
kernel/sched/cpufreq_schedutil.c
kernel/sched/cpufreq_schedutil.c
+54
-28
kernel/time/tick-sched.c
kernel/time/tick-sched.c
+12
-0
未找到文件。
drivers/cpufreq/intel_pstate.c
浏览文件 @
2addac72
...
...
@@ -41,6 +41,7 @@
#define INTEL_PSTATE_HWP_SAMPLING_INTERVAL (50 * NSEC_PER_MSEC)
#define INTEL_CPUFREQ_TRANSITION_LATENCY 20000
#define INTEL_CPUFREQ_TRANSITION_DELAY 500
#ifdef CONFIG_ACPI
#include <acpi/processor.h>
...
...
@@ -2237,6 +2238,7 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
return
ret
;
policy
->
cpuinfo
.
transition_latency
=
INTEL_CPUFREQ_TRANSITION_LATENCY
;
policy
->
transition_delay_us
=
INTEL_CPUFREQ_TRANSITION_DELAY
;
/* This reflects the intel_pstate_get_cpu_pstates() setting. */
policy
->
cur
=
policy
->
cpuinfo
.
min_freq
;
...
...
include/linux/cpufreq.h
浏览文件 @
2addac72
...
...
@@ -120,6 +120,13 @@ struct cpufreq_policy {
bool
fast_switch_possible
;
bool
fast_switch_enabled
;
/*
* Preferred average time interval between consecutive invocations of
* the driver to set the frequency for this policy. To be set by the
* scaling driver (0, which is the default, means no preference).
*/
unsigned
int
transition_delay_us
;
/* Cached frequency lookup from cpufreq_driver_resolve_freq. */
unsigned
int
cached_target_freq
;
int
cached_resolved_idx
;
...
...
include/linux/tick.h
浏览文件 @
2addac72
...
...
@@ -117,6 +117,7 @@ extern void tick_nohz_idle_enter(void);
extern
void
tick_nohz_idle_exit
(
void
);
extern
void
tick_nohz_irq_exit
(
void
);
extern
ktime_t
tick_nohz_get_sleep_length
(
void
);
extern
unsigned
long
tick_nohz_get_idle_calls
(
void
);
extern
u64
get_cpu_idle_time_us
(
int
cpu
,
u64
*
last_update_time
);
extern
u64
get_cpu_iowait_time_us
(
int
cpu
,
u64
*
last_update_time
);
#else
/* !CONFIG_NO_HZ_COMMON */
...
...
kernel/sched/cpufreq_schedutil.c
浏览文件 @
2addac72
...
...
@@ -61,6 +61,11 @@ struct sugov_cpu {
unsigned
long
util
;
unsigned
long
max
;
unsigned
int
flags
;
/* The field below is for single-CPU policies only. */
#ifdef CONFIG_NO_HZ_COMMON
unsigned
long
saved_idle_calls
;
#endif
};
static
DEFINE_PER_CPU
(
struct
sugov_cpu
,
sugov_cpu
);
...
...
@@ -93,22 +98,23 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
{
struct
cpufreq_policy
*
policy
=
sg_policy
->
policy
;
if
(
sg_policy
->
next_freq
==
next_freq
)
return
;
if
(
sg_policy
->
next_freq
>
next_freq
)
next_freq
=
(
sg_policy
->
next_freq
+
next_freq
)
>>
1
;
sg_policy
->
next_freq
=
next_freq
;
sg_policy
->
last_freq_update_time
=
time
;
if
(
policy
->
fast_switch_enabled
)
{
if
(
sg_policy
->
next_freq
==
next_freq
)
{
trace_cpu_frequency
(
policy
->
cur
,
smp_processor_id
());
return
;
}
sg_policy
->
next_freq
=
next_freq
;
next_freq
=
cpufreq_driver_fast_switch
(
policy
,
next_freq
);
if
(
next_freq
==
CPUFREQ_ENTRY_INVALID
)
return
;
policy
->
cur
=
next_freq
;
trace_cpu_frequency
(
next_freq
,
smp_processor_id
());
}
else
if
(
sg_policy
->
next_freq
!=
next_freq
)
{
sg_policy
->
next_freq
=
next_freq
;
}
else
{
sg_policy
->
work_in_progress
=
true
;
irq_work_queue
(
&
sg_policy
->
irq_work
);
}
...
...
@@ -192,6 +198,19 @@ static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util,
sg_cpu
->
iowait_boost
>>=
1
;
}
#ifdef CONFIG_NO_HZ_COMMON
static
bool
sugov_cpu_is_busy
(
struct
sugov_cpu
*
sg_cpu
)
{
unsigned
long
idle_calls
=
tick_nohz_get_idle_calls
();
bool
ret
=
idle_calls
==
sg_cpu
->
saved_idle_calls
;
sg_cpu
->
saved_idle_calls
=
idle_calls
;
return
ret
;
}
#else
static
inline
bool
sugov_cpu_is_busy
(
struct
sugov_cpu
*
sg_cpu
)
{
return
false
;
}
#endif
/* CONFIG_NO_HZ_COMMON */
static
void
sugov_update_single
(
struct
update_util_data
*
hook
,
u64
time
,
unsigned
int
flags
)
{
...
...
@@ -200,6 +219,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
struct
cpufreq_policy
*
policy
=
sg_policy
->
policy
;
unsigned
long
util
,
max
;
unsigned
int
next_f
;
bool
busy
;
sugov_set_iowait_boost
(
sg_cpu
,
time
,
flags
);
sg_cpu
->
last_update
=
time
;
...
...
@@ -207,40 +227,37 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
if
(
!
sugov_should_update_freq
(
sg_policy
,
time
))
return
;
busy
=
sugov_cpu_is_busy
(
sg_cpu
);
if
(
flags
&
SCHED_CPUFREQ_RT_DL
)
{
next_f
=
policy
->
cpuinfo
.
max_freq
;
}
else
{
sugov_get_util
(
&
util
,
&
max
);
sugov_iowait_boost
(
sg_cpu
,
&
util
,
&
max
);
next_f
=
get_next_freq
(
sg_policy
,
util
,
max
);
/*
* Do not reduce the frequency if the CPU has not been idle
* recently, as the reduction is likely to be premature then.
*/
if
(
busy
&&
next_f
<
sg_policy
->
next_freq
)
next_f
=
sg_policy
->
next_freq
;
}
sugov_update_commit
(
sg_policy
,
time
,
next_f
);
}
static
unsigned
int
sugov_next_freq_shared
(
struct
sugov_cpu
*
sg_cpu
,
unsigned
long
util
,
unsigned
long
max
,
unsigned
int
flags
)
static
unsigned
int
sugov_next_freq_shared
(
struct
sugov_cpu
*
sg_cpu
)
{
struct
sugov_policy
*
sg_policy
=
sg_cpu
->
sg_policy
;
struct
cpufreq_policy
*
policy
=
sg_policy
->
policy
;
unsigned
int
max_f
=
policy
->
cpuinfo
.
max_freq
;
u64
last_freq_update_time
=
sg_policy
->
last_freq_update_time
;
unsigned
long
util
=
0
,
max
=
1
;
unsigned
int
j
;
if
(
flags
&
SCHED_CPUFREQ_RT_DL
)
return
max_f
;
sugov_iowait_boost
(
sg_cpu
,
&
util
,
&
max
);
for_each_cpu
(
j
,
policy
->
cpus
)
{
struct
sugov_cpu
*
j_sg_cpu
;
struct
sugov_cpu
*
j_sg_cpu
=
&
per_cpu
(
sugov_cpu
,
j
)
;
unsigned
long
j_util
,
j_max
;
s64
delta_ns
;
if
(
j
==
smp_processor_id
())
continue
;
j_sg_cpu
=
&
per_cpu
(
sugov_cpu
,
j
);
/*
* If the CPU utilization was last updated before the previous
* frequency update and the time elapsed between the last update
...
...
@@ -254,7 +271,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
continue
;
}
if
(
j_sg_cpu
->
flags
&
SCHED_CPUFREQ_RT_DL
)
return
max_f
;
return
policy
->
cpuinfo
.
max_freq
;
j_util
=
j_sg_cpu
->
util
;
j_max
=
j_sg_cpu
->
max
;
...
...
@@ -289,7 +306,11 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
sg_cpu
->
last_update
=
time
;
if
(
sugov_should_update_freq
(
sg_policy
,
time
))
{
next_f
=
sugov_next_freq_shared
(
sg_cpu
,
util
,
max
,
flags
);
if
(
flags
&
SCHED_CPUFREQ_RT_DL
)
next_f
=
sg_policy
->
policy
->
cpuinfo
.
max_freq
;
else
next_f
=
sugov_next_freq_shared
(
sg_cpu
);
sugov_update_commit
(
sg_policy
,
time
,
next_f
);
}
...
...
@@ -473,7 +494,6 @@ static int sugov_init(struct cpufreq_policy *policy)
{
struct
sugov_policy
*
sg_policy
;
struct
sugov_tunables
*
tunables
;
unsigned
int
lat
;
int
ret
=
0
;
/* State should be equivalent to EXIT */
...
...
@@ -512,10 +532,16 @@ static int sugov_init(struct cpufreq_policy *policy)
goto
stop_kthread
;
}
tunables
->
rate_limit_us
=
LATENCY_MULTIPLIER
;
lat
=
policy
->
cpuinfo
.
transition_latency
/
NSEC_PER_USEC
;
if
(
lat
)
tunables
->
rate_limit_us
*=
lat
;
if
(
policy
->
transition_delay_us
)
{
tunables
->
rate_limit_us
=
policy
->
transition_delay_us
;
}
else
{
unsigned
int
lat
;
tunables
->
rate_limit_us
=
LATENCY_MULTIPLIER
;
lat
=
policy
->
cpuinfo
.
transition_latency
/
NSEC_PER_USEC
;
if
(
lat
)
tunables
->
rate_limit_us
*=
lat
;
}
policy
->
governor_data
=
sg_policy
;
sg_policy
->
tunables
=
tunables
;
...
...
kernel/time/tick-sched.c
浏览文件 @
2addac72
...
...
@@ -993,6 +993,18 @@ ktime_t tick_nohz_get_sleep_length(void)
return
ts
->
sleep_length
;
}
/**
* tick_nohz_get_idle_calls - return the current idle calls counter value
*
* Called from the schedutil frequency scaling governor in scheduler context.
*/
unsigned
long
tick_nohz_get_idle_calls
(
void
)
{
struct
tick_sched
*
ts
=
this_cpu_ptr
(
&
tick_cpu_sched
);
return
ts
->
idle_calls
;
}
static
void
tick_nohz_account_idle_ticks
(
struct
tick_sched
*
ts
)
{
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录