Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
b6e25117
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b6e25117
编写于
10月 02, 2016
作者:
R
Rafael J. Wysocki
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pm-cpufreq-sched' into pm-cpufreq
上级
9ad0a1b6
3ba7bcaa
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
178 addition
and
119 deletion
+178
-119
arch/arm/configs/exynos_defconfig
arch/arm/configs/exynos_defconfig
+1
-1
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/multi_v7_defconfig
+1
-1
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig
+1
-4
drivers/cpufreq/cpufreq_governor.c
drivers/cpufreq/cpufreq_governor.c
+1
-1
drivers/cpufreq/intel_pstate.c
drivers/cpufreq/intel_pstate.c
+34
-29
include/linux/sched.h
include/linux/sched.h
+9
-4
include/trace/events/power.h
include/trace/events/power.h
+9
-4
kernel/sched/cpufreq.c
kernel/sched/cpufreq.c
+1
-1
kernel/sched/cpufreq_schedutil.c
kernel/sched/cpufreq_schedutil.c
+88
-34
kernel/sched/deadline.c
kernel/sched/deadline.c
+2
-3
kernel/sched/fair.c
kernel/sched/fair.c
+11
-12
kernel/sched/rt.c
kernel/sched/rt.c
+2
-3
kernel/sched/sched.h
kernel/sched/sched.h
+18
-22
未找到文件。
arch/arm/configs/exynos_defconfig
浏览文件 @
b6e25117
...
...
@@ -28,7 +28,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=
m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=
y
CONFIG_CPUFREQ_DT=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_EXYNOS_CPUIDLE=y
...
...
arch/arm/configs/multi_v7_defconfig
浏览文件 @
b6e25117
...
...
@@ -135,7 +135,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=
m
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=
y
CONFIG_QORIQ_CPUFREQ=y
CONFIG_CPU_IDLE=y
CONFIG_ARM_CPUIDLE=y
...
...
drivers/cpufreq/Kconfig
浏览文件 @
b6e25117
...
...
@@ -194,7 +194,7 @@ config CPU_FREQ_GOV_CONSERVATIVE
If in doubt, say N.
config CPU_FREQ_GOV_SCHEDUTIL
tristate
"'schedutil' cpufreq policy governor"
bool
"'schedutil' cpufreq policy governor"
depends on CPU_FREQ && SMP
select CPU_FREQ_GOV_ATTR_SET
select IRQ_WORK
...
...
@@ -208,9 +208,6 @@ config CPU_FREQ_GOV_SCHEDUTIL
frequency tipping point is at utilization/capacity equal to 80% in
both cases.
To compile this driver as a module, choose M here: the module will
be called cpufreq_schedutil.
If in doubt, say N.
comment "CPU frequency scaling drivers"
...
...
drivers/cpufreq/cpufreq_governor.c
浏览文件 @
b6e25117
...
...
@@ -260,7 +260,7 @@ static void dbs_irq_work(struct irq_work *irq_work)
}
static
void
dbs_update_util_handler
(
struct
update_util_data
*
data
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
unsigned
int
flags
)
{
struct
cpu_dbs_info
*
cdbs
=
container_of
(
data
,
struct
cpu_dbs_info
,
update_util
);
struct
policy_dbs_info
*
policy_dbs
=
cdbs
->
policy_dbs
;
...
...
drivers/cpufreq/intel_pstate.c
浏览文件 @
b6e25117
...
...
@@ -181,6 +181,8 @@ struct _pid {
* @cpu: CPU number for this instance data
* @update_util: CPUFreq utility callback information
* @update_util_set: CPUFreq utility callback is set
* @iowait_boost: iowait-related boost fraction
* @last_update: Time of the last update.
* @pstate: Stores P state limits for this CPU
* @vid: Stores VID limits for this CPU
* @pid: Stores PID parameters for this CPU
...
...
@@ -206,6 +208,7 @@ struct cpudata {
struct
vid_data
vid
;
struct
_pid
pid
;
u64
last_update
;
u64
last_sample_time
;
u64
prev_aperf
;
u64
prev_mperf
;
...
...
@@ -216,6 +219,7 @@ struct cpudata {
struct
acpi_processor_performance
acpi_perf_data
;
bool
valid_pss_table
;
#endif
unsigned
int
iowait_boost
;
};
static
struct
cpudata
**
all_cpu_data
;
...
...
@@ -229,6 +233,7 @@ static struct cpudata **all_cpu_data;
* @p_gain_pct: PID proportional gain
* @i_gain_pct: PID integral gain
* @d_gain_pct: PID derivative gain
* @boost_iowait: Whether or not to use iowait boosting.
*
* Stores per CPU model static PID configuration data.
*/
...
...
@@ -240,6 +245,7 @@ struct pstate_adjust_policy {
int
p_gain_pct
;
int
d_gain_pct
;
int
i_gain_pct
;
bool
boost_iowait
;
};
/**
...
...
@@ -1037,6 +1043,7 @@ static const struct cpu_defaults silvermont_params = {
.
p_gain_pct
=
14
,
.
d_gain_pct
=
0
,
.
i_gain_pct
=
4
,
.
boost_iowait
=
true
,
},
.
funcs
=
{
.
get_max
=
atom_get_max_pstate
,
...
...
@@ -1058,6 +1065,7 @@ static const struct cpu_defaults airmont_params = {
.
p_gain_pct
=
14
,
.
d_gain_pct
=
0
,
.
i_gain_pct
=
4
,
.
boost_iowait
=
true
,
},
.
funcs
=
{
.
get_max
=
atom_get_max_pstate
,
...
...
@@ -1099,6 +1107,7 @@ static const struct cpu_defaults bxt_params = {
.
p_gain_pct
=
14
,
.
d_gain_pct
=
0
,
.
i_gain_pct
=
4
,
.
boost_iowait
=
true
,
},
.
funcs
=
{
.
get_max
=
core_get_max_pstate
,
...
...
@@ -1222,36 +1231,18 @@ static inline int32_t get_avg_pstate(struct cpudata *cpu)
static
inline
int32_t
get_target_pstate_use_cpu_load
(
struct
cpudata
*
cpu
)
{
struct
sample
*
sample
=
&
cpu
->
sample
;
u64
cummulative_iowait
,
delta_iowait_us
;
u64
delta_iowait_mperf
;
u64
mperf
,
now
;
int32_t
cpu_load
;
int32_t
busy_frac
,
boost
;
cummulative_iowait
=
get_cpu_iowait_time_us
(
cpu
->
cpu
,
&
now
);
busy_frac
=
div_fp
(
sample
->
mperf
,
sample
->
tsc
);
/*
* Convert iowait time into number of IO cycles spent at max_freq.
* IO is considered as busy only for the cpu_load algorithm. For
* performance this is not needed since we always try to reach the
* maximum P-State, so we are already boosting the IOs.
*/
delta_iowait_us
=
cummulative_iowait
-
cpu
->
prev_cummulative_iowait
;
delta_iowait_mperf
=
div64_u64
(
delta_iowait_us
*
cpu
->
pstate
.
scaling
*
cpu
->
pstate
.
max_pstate
,
MSEC_PER_SEC
);
boost
=
cpu
->
iowait_boost
;
cpu
->
iowait_boost
>>=
1
;
mperf
=
cpu
->
sample
.
mperf
+
delta_iowait_mperf
;
cpu
->
prev_cummulative_iowait
=
cummulative_iowai
t
;
if
(
busy_frac
<
boost
)
busy_frac
=
boos
t
;
/*
* The load can be estimated as the ratio of the mperf counter
* running at a constant frequency during active periods
* (C0) and the time stamp counter running at the same frequency
* also during C-states.
*/
cpu_load
=
div64_u64
(
int_tofp
(
100
)
*
mperf
,
sample
->
tsc
);
cpu
->
sample
.
busy_scaled
=
cpu_load
;
return
get_avg_pstate
(
cpu
)
-
pid_calc
(
&
cpu
->
pid
,
cpu_load
);
sample
->
busy_scaled
=
busy_frac
*
100
;
return
get_avg_pstate
(
cpu
)
-
pid_calc
(
&
cpu
->
pid
,
sample
->
busy_scaled
);
}
static
inline
int32_t
get_target_pstate_use_performance
(
struct
cpudata
*
cpu
)
...
...
@@ -1325,15 +1316,29 @@ static inline void intel_pstate_adjust_busy_pstate(struct cpudata *cpu)
sample
->
mperf
,
sample
->
aperf
,
sample
->
tsc
,
get_avg_frequency
(
cpu
));
get_avg_frequency
(
cpu
),
fp_toint
(
cpu
->
iowait_boost
*
100
));
}
static
void
intel_pstate_update_util
(
struct
update_util_data
*
data
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
unsigned
int
flags
)
{
struct
cpudata
*
cpu
=
container_of
(
data
,
struct
cpudata
,
update_util
);
u64
delta_ns
=
time
-
cpu
->
sample
.
time
;
u64
delta_ns
;
if
(
pid_params
.
boost_iowait
)
{
if
(
flags
&
SCHED_CPUFREQ_IOWAIT
)
{
cpu
->
iowait_boost
=
int_tofp
(
1
);
}
else
if
(
cpu
->
iowait_boost
)
{
/* Clear iowait_boost if the CPU may have been idle. */
delta_ns
=
time
-
cpu
->
last_update
;
if
(
delta_ns
>
TICK_NSEC
)
cpu
->
iowait_boost
=
0
;
}
cpu
->
last_update
=
time
;
}
delta_ns
=
time
-
cpu
->
sample
.
time
;
if
((
s64
)
delta_ns
>=
pid_params
.
sample_rate_ns
)
{
bool
sample_taken
=
intel_pstate_sample
(
cpu
,
time
);
...
...
include/linux/sched.h
浏览文件 @
b6e25117
...
...
@@ -3469,15 +3469,20 @@ static inline unsigned long rlimit_max(unsigned int limit)
return
task_rlimit_max
(
current
,
limit
);
}
#define SCHED_CPUFREQ_RT (1U << 0)
#define SCHED_CPUFREQ_DL (1U << 1)
#define SCHED_CPUFREQ_IOWAIT (1U << 2)
#define SCHED_CPUFREQ_RT_DL (SCHED_CPUFREQ_RT | SCHED_CPUFREQ_DL)
#ifdef CONFIG_CPU_FREQ
struct
update_util_data
{
void
(
*
func
)(
struct
update_util_data
*
data
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
);
void
(
*
func
)(
struct
update_util_data
*
data
,
u64
time
,
unsigned
int
flags
);
};
void
cpufreq_add_update_util_hook
(
int
cpu
,
struct
update_util_data
*
data
,
void
(
*
func
)(
struct
update_util_data
*
data
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
));
void
(
*
func
)(
struct
update_util_data
*
data
,
u64
time
,
unsigned
int
flags
));
void
cpufreq_remove_update_util_hook
(
int
cpu
);
#endif
/* CONFIG_CPU_FREQ */
...
...
include/trace/events/power.h
浏览文件 @
b6e25117
...
...
@@ -69,7 +69,8 @@ TRACE_EVENT(pstate_sample,
u64
mperf
,
u64
aperf
,
u64
tsc
,
u32
freq
u32
freq
,
u32
io_boost
),
TP_ARGS
(
core_busy
,
...
...
@@ -79,7 +80,8 @@ TRACE_EVENT(pstate_sample,
mperf
,
aperf
,
tsc
,
freq
freq
,
io_boost
),
TP_STRUCT__entry
(
...
...
@@ -91,6 +93,7 @@ TRACE_EVENT(pstate_sample,
__field
(
u64
,
aperf
)
__field
(
u64
,
tsc
)
__field
(
u32
,
freq
)
__field
(
u32
,
io_boost
)
),
TP_fast_assign
(
...
...
@@ -102,9 +105,10 @@ TRACE_EVENT(pstate_sample,
__entry
->
aperf
=
aperf
;
__entry
->
tsc
=
tsc
;
__entry
->
freq
=
freq
;
__entry
->
io_boost
=
io_boost
;
),
TP_printk
(
"core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu "
,
TP_printk
(
"core_busy=%lu scaled=%lu from=%lu to=%lu mperf=%llu aperf=%llu tsc=%llu freq=%lu
io_boost=%lu
"
,
(
unsigned
long
)
__entry
->
core_busy
,
(
unsigned
long
)
__entry
->
scaled_busy
,
(
unsigned
long
)
__entry
->
from
,
...
...
@@ -112,7 +116,8 @@ TRACE_EVENT(pstate_sample,
(
unsigned
long
long
)
__entry
->
mperf
,
(
unsigned
long
long
)
__entry
->
aperf
,
(
unsigned
long
long
)
__entry
->
tsc
,
(
unsigned
long
)
__entry
->
freq
(
unsigned
long
)
__entry
->
freq
,
(
unsigned
long
)
__entry
->
io_boost
)
);
...
...
kernel/sched/cpufreq.c
浏览文件 @
b6e25117
...
...
@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
*/
void
cpufreq_add_update_util_hook
(
int
cpu
,
struct
update_util_data
*
data
,
void
(
*
func
)(
struct
update_util_data
*
data
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
))
unsigned
int
flags
))
{
if
(
WARN_ON
(
!
data
||
!
func
))
return
;
...
...
kernel/sched/cpufreq_schedutil.c
浏览文件 @
b6e25117
...
...
@@ -12,7 +12,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/cpufreq.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <trace/events/power.h>
...
...
@@ -48,11 +47,14 @@ struct sugov_cpu {
struct
sugov_policy
*
sg_policy
;
unsigned
int
cached_raw_freq
;
unsigned
long
iowait_boost
;
unsigned
long
iowait_boost_max
;
u64
last_update
;
/* The fields below are only needed when sharing a policy. */
unsigned
long
util
;
unsigned
long
max
;
u
64
last_update
;
u
nsigned
int
flags
;
};
static
DEFINE_PER_CPU
(
struct
sugov_cpu
,
sugov_cpu
);
...
...
@@ -144,24 +146,75 @@ static unsigned int get_next_freq(struct sugov_cpu *sg_cpu, unsigned long util,
return
cpufreq_driver_resolve_freq
(
policy
,
freq
);
}
static
void
sugov_get_util
(
unsigned
long
*
util
,
unsigned
long
*
max
)
{
struct
rq
*
rq
=
this_rq
();
unsigned
long
cfs_max
;
cfs_max
=
arch_scale_cpu_capacity
(
NULL
,
smp_processor_id
());
*
util
=
min
(
rq
->
cfs
.
avg
.
util_avg
,
cfs_max
);
*
max
=
cfs_max
;
}
static
void
sugov_set_iowait_boost
(
struct
sugov_cpu
*
sg_cpu
,
u64
time
,
unsigned
int
flags
)
{
if
(
flags
&
SCHED_CPUFREQ_IOWAIT
)
{
sg_cpu
->
iowait_boost
=
sg_cpu
->
iowait_boost_max
;
}
else
if
(
sg_cpu
->
iowait_boost
)
{
s64
delta_ns
=
time
-
sg_cpu
->
last_update
;
/* Clear iowait_boost if the CPU apprears to have been idle. */
if
(
delta_ns
>
TICK_NSEC
)
sg_cpu
->
iowait_boost
=
0
;
}
}
static
void
sugov_iowait_boost
(
struct
sugov_cpu
*
sg_cpu
,
unsigned
long
*
util
,
unsigned
long
*
max
)
{
unsigned
long
boost_util
=
sg_cpu
->
iowait_boost
;
unsigned
long
boost_max
=
sg_cpu
->
iowait_boost_max
;
if
(
!
boost_util
)
return
;
if
(
*
util
*
boost_max
<
*
max
*
boost_util
)
{
*
util
=
boost_util
;
*
max
=
boost_max
;
}
sg_cpu
->
iowait_boost
>>=
1
;
}
static
void
sugov_update_single
(
struct
update_util_data
*
hook
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
unsigned
int
flags
)
{
struct
sugov_cpu
*
sg_cpu
=
container_of
(
hook
,
struct
sugov_cpu
,
update_util
);
struct
sugov_policy
*
sg_policy
=
sg_cpu
->
sg_policy
;
struct
cpufreq_policy
*
policy
=
sg_policy
->
policy
;
unsigned
long
util
,
max
;
unsigned
int
next_f
;
sugov_set_iowait_boost
(
sg_cpu
,
time
,
flags
);
sg_cpu
->
last_update
=
time
;
if
(
!
sugov_should_update_freq
(
sg_policy
,
time
))
return
;
next_f
=
util
==
ULONG_MAX
?
policy
->
cpuinfo
.
max_freq
:
get_next_freq
(
sg_cpu
,
util
,
max
);
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_cpu
,
util
,
max
);
}
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
long
util
,
unsigned
long
max
,
unsigned
int
flags
)
{
struct
sugov_policy
*
sg_policy
=
sg_cpu
->
sg_policy
;
struct
cpufreq_policy
*
policy
=
sg_policy
->
policy
;
...
...
@@ -169,9 +222,11 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
u64
last_freq_update_time
=
sg_policy
->
last_freq_update_time
;
unsigned
int
j
;
if
(
util
==
ULONG_MAX
)
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
;
unsigned
long
j_util
,
j_max
;
...
...
@@ -186,41 +241,50 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
* frequency update and the time elapsed between the last update
* of the CPU utilization and the last frequency update is long
* enough, don't take the CPU into account as it probably is
* idle now.
* idle now
(and clear iowait_boost for it)
.
*/
delta_ns
=
last_freq_update_time
-
j_sg_cpu
->
last_update
;
if
(
delta_ns
>
TICK_NSEC
)
if
(
delta_ns
>
TICK_NSEC
)
{
j_sg_cpu
->
iowait_boost
=
0
;
continue
;
j_util
=
j_sg_cpu
->
util
;
if
(
j_util
==
ULONG_MAX
)
}
if
(
j_sg_cpu
->
flags
&
SCHED_CPUFREQ_RT_DL
)
return
max_f
;
j_util
=
j_sg_cpu
->
util
;
j_max
=
j_sg_cpu
->
max
;
if
(
j_util
*
max
>
j_max
*
util
)
{
util
=
j_util
;
max
=
j_max
;
}
sugov_iowait_boost
(
j_sg_cpu
,
&
util
,
&
max
);
}
return
get_next_freq
(
sg_cpu
,
util
,
max
);
}
static
void
sugov_update_shared
(
struct
update_util_data
*
hook
,
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
unsigned
int
flags
)
{
struct
sugov_cpu
*
sg_cpu
=
container_of
(
hook
,
struct
sugov_cpu
,
update_util
);
struct
sugov_policy
*
sg_policy
=
sg_cpu
->
sg_policy
;
unsigned
long
util
,
max
;
unsigned
int
next_f
;
sugov_get_util
(
&
util
,
&
max
);
raw_spin_lock
(
&
sg_policy
->
update_lock
);
sg_cpu
->
util
=
util
;
sg_cpu
->
max
=
max
;
sg_cpu
->
flags
=
flags
;
sugov_set_iowait_boost
(
sg_cpu
,
time
,
flags
);
sg_cpu
->
last_update
=
time
;
if
(
sugov_should_update_freq
(
sg_policy
,
time
))
{
next_f
=
sugov_next_freq_shared
(
sg_cpu
,
util
,
max
);
next_f
=
sugov_next_freq_shared
(
sg_cpu
,
util
,
max
,
flags
);
sugov_update_commit
(
sg_policy
,
time
,
next_f
);
}
...
...
@@ -444,10 +508,13 @@ static int sugov_start(struct cpufreq_policy *policy)
sg_cpu
->
sg_policy
=
sg_policy
;
if
(
policy_is_shared
(
policy
))
{
sg_cpu
->
util
=
ULONG_MAX
;
sg_cpu
->
util
=
0
;
sg_cpu
->
max
=
0
;
sg_cpu
->
flags
=
SCHED_CPUFREQ_RT
;
sg_cpu
->
last_update
=
0
;
sg_cpu
->
cached_raw_freq
=
0
;
sg_cpu
->
iowait_boost
=
0
;
sg_cpu
->
iowait_boost_max
=
policy
->
cpuinfo
.
max_freq
;
cpufreq_add_update_util_hook
(
cpu
,
&
sg_cpu
->
update_util
,
sugov_update_shared
);
}
else
{
...
...
@@ -495,28 +562,15 @@ static struct cpufreq_governor schedutil_gov = {
.
limits
=
sugov_limits
,
};
static
int
__init
sugov_module_init
(
void
)
{
return
cpufreq_register_governor
(
&
schedutil_gov
);
}
static
void
__exit
sugov_module_exit
(
void
)
{
cpufreq_unregister_governor
(
&
schedutil_gov
);
}
MODULE_AUTHOR
(
"Rafael J. Wysocki <rafael.j.wysocki@intel.com>"
);
MODULE_DESCRIPTION
(
"Utilization-based CPU frequency selection"
);
MODULE_LICENSE
(
"GPL"
);
#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL
struct
cpufreq_governor
*
cpufreq_default_governor
(
void
)
{
return
&
schedutil_gov
;
}
fs_initcall
(
sugov_module_init
);
#else
module_init
(
sugov_module_init
);
#endif
module_exit
(
sugov_module_exit
);
static
int
__init
sugov_register
(
void
)
{
return
cpufreq_register_governor
(
&
schedutil_gov
);
}
fs_initcall
(
sugov_register
);
kernel/sched/deadline.c
浏览文件 @
b6e25117
...
...
@@ -735,9 +735,8 @@ static void update_curr_dl(struct rq *rq)
return
;
}
/* kick cpufreq (see the comment in linux/cpufreq.h). */
if
(
cpu_of
(
rq
)
==
smp_processor_id
())
cpufreq_trigger_update
(
rq_clock
(
rq
));
/* kick cpufreq (see the comment in kernel/sched/sched.h). */
cpufreq_update_this_cpu
(
rq
,
SCHED_CPUFREQ_DL
);
schedstat_set
(
curr
->
se
.
statistics
.
exec_max
,
max
(
curr
->
se
.
statistics
.
exec_max
,
delta_exec
));
...
...
kernel/sched/fair.c
浏览文件 @
b6e25117
...
...
@@ -2875,12 +2875,7 @@ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force) {}
static
inline
void
cfs_rq_util_change
(
struct
cfs_rq
*
cfs_rq
)
{
struct
rq
*
rq
=
rq_of
(
cfs_rq
);
int
cpu
=
cpu_of
(
rq
);
if
(
cpu
==
smp_processor_id
()
&&
&
rq
->
cfs
==
cfs_rq
)
{
unsigned
long
max
=
rq
->
cpu_capacity_orig
;
if
(
&
this_rq
()
->
cfs
==
cfs_rq
)
{
/*
* There are a few boundary cases this might miss but it should
* get called often enough that that should (hopefully) not be
...
...
@@ -2897,8 +2892,7 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq)
*
* See cpu_util().
*/
cpufreq_update_util
(
rq_clock
(
rq
),
min
(
cfs_rq
->
avg
.
util_avg
,
max
),
max
);
cpufreq_update_util
(
rq_of
(
cfs_rq
),
0
);
}
}
...
...
@@ -3159,10 +3153,7 @@ update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq, bool update_freq)
static
inline
void
update_load_avg
(
struct
sched_entity
*
se
,
int
not_used
)
{
struct
cfs_rq
*
cfs_rq
=
cfs_rq_of
(
se
);
struct
rq
*
rq
=
rq_of
(
cfs_rq
);
cpufreq_trigger_update
(
rq_clock
(
rq
));
cpufreq_update_util
(
rq_of
(
cfs_rq_of
(
se
)),
0
);
}
static
inline
void
...
...
@@ -4509,6 +4500,14 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
struct
cfs_rq
*
cfs_rq
;
struct
sched_entity
*
se
=
&
p
->
se
;
/*
* If in_iowait is set, the code below may not trigger any cpufreq
* utilization updates, so do it here explicitly with the IOWAIT flag
* passed.
*/
if
(
p
->
in_iowait
)
cpufreq_update_this_cpu
(
rq
,
SCHED_CPUFREQ_IOWAIT
);
for_each_sched_entity
(
se
)
{
if
(
se
->
on_rq
)
break
;
...
...
kernel/sched/rt.c
浏览文件 @
b6e25117
...
...
@@ -957,9 +957,8 @@ static void update_curr_rt(struct rq *rq)
if
(
unlikely
((
s64
)
delta_exec
<=
0
))
return
;
/* Kick cpufreq (see the comment in linux/cpufreq.h). */
if
(
cpu_of
(
rq
)
==
smp_processor_id
())
cpufreq_trigger_update
(
rq_clock
(
rq
));
/* Kick cpufreq (see the comment in kernel/sched/sched.h). */
cpufreq_update_this_cpu
(
rq
,
SCHED_CPUFREQ_RT
);
schedstat_set
(
curr
->
se
.
statistics
.
exec_max
,
max
(
curr
->
se
.
statistics
.
exec_max
,
delta_exec
));
...
...
kernel/sched/sched.h
浏览文件 @
b6e25117
...
...
@@ -1763,27 +1763,13 @@ DECLARE_PER_CPU(struct update_util_data *, cpufreq_update_util_data);
/**
* cpufreq_update_util - Take a note about CPU utilization changes.
* @time: Current time.
* @util: Current utilization.
* @max: Utilization ceiling.
* @rq: Runqueue to carry out the update for.
* @flags: Update reason flags.
*
* This function is called by the scheduler on
every invocation of
*
update_load_avg() on the CPU whose utilization is
being updated.
* This function is called by the scheduler on
the CPU whose utilization is
* being updated.
*
* It can only be called from RCU-sched read-side critical sections.
*/
static
inline
void
cpufreq_update_util
(
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
{
struct
update_util_data
*
data
;
data
=
rcu_dereference_sched
(
*
this_cpu_ptr
(
&
cpufreq_update_util_data
));
if
(
data
)
data
->
func
(
data
,
time
,
util
,
max
);
}
/**
* cpufreq_trigger_update - Trigger CPU performance state evaluation if needed.
* @time: Current time.
*
* The way cpufreq is currently arranged requires it to evaluate the CPU
* performance state (frequency/voltage) on a regular basis to prevent it from
...
...
@@ -1797,13 +1783,23 @@ static inline void cpufreq_update_util(u64 time, unsigned long util, unsigned lo
* but that really is a band-aid. Going forward it should be replaced with
* solutions targeted more specifically at RT and DL tasks.
*/
static
inline
void
cpufreq_trigger_update
(
u64
time
)
static
inline
void
cpufreq_update_util
(
struct
rq
*
rq
,
unsigned
int
flags
)
{
struct
update_util_data
*
data
;
data
=
rcu_dereference_sched
(
*
this_cpu_ptr
(
&
cpufreq_update_util_data
));
if
(
data
)
data
->
func
(
data
,
rq_clock
(
rq
),
flags
);
}
static
inline
void
cpufreq_update_this_cpu
(
struct
rq
*
rq
,
unsigned
int
flags
)
{
cpufreq_update_util
(
time
,
ULONG_MAX
,
0
);
if
(
cpu_of
(
rq
)
==
smp_processor_id
())
cpufreq_update_util
(
rq
,
flags
);
}
#else
static
inline
void
cpufreq_update_util
(
u64
time
,
unsigned
long
util
,
unsigned
long
max
)
{}
static
inline
void
cpufreq_
trigger_update
(
u64
time
)
{}
static
inline
void
cpufreq_update_util
(
struct
rq
*
rq
,
unsigned
int
flags
)
{}
static
inline
void
cpufreq_
update_this_cpu
(
struct
rq
*
rq
,
unsigned
int
flags
)
{}
#endif
/* CONFIG_CPU_FREQ */
#ifdef arch_scale_freq_capacity
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录