Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
70e493f3
Commit
70e493f3
authored
Mar 25, 2017
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back schedutil governor updates for 4.12.
parents
4296f23e
38d4ea22
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
54 additions
and
23 deletions
+54
-23
include/linux/tick.h
include/linux/tick.h
+1
-0
kernel/sched/cpufreq_schedutil.c
kernel/sched/cpufreq_schedutil.c
+41
-23
kernel/time/tick-sched.c
kernel/time/tick-sched.c
+12
-0
No files found.
include/linux/tick.h
View file @
70e493f3
...
...
@@ -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
View file @
70e493f3
...
...
@@ -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,20 @@ 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
;
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 +195,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 +216,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 +224,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 +268,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 +303,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
);
}
...
...
kernel/time/tick-sched.c
View file @
70e493f3
...
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment