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
2c2a83d3
Commit
2c2a83d3
authored
Oct 24, 2019
by
Rafael J. Wysocki
Browse files
Options
Browse Files
Download
Plain Diff
Merge back earlier cpuidle material for v5.5.
parents
31d85140
159e4856
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
59 additions
and
19 deletions
+59
-19
drivers/cpuidle/governors/teo.c
drivers/cpuidle/governors/teo.c
+59
-19
No files found.
drivers/cpuidle/governors/teo.c
View file @
2c2a83d3
...
@@ -233,7 +233,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -233,7 +233,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
{
{
struct
teo_cpu
*
cpu_data
=
per_cpu_ptr
(
&
teo_cpus
,
dev
->
cpu
);
struct
teo_cpu
*
cpu_data
=
per_cpu_ptr
(
&
teo_cpus
,
dev
->
cpu
);
int
latency_req
=
cpuidle_governor_latency_req
(
dev
->
cpu
);
int
latency_req
=
cpuidle_governor_latency_req
(
dev
->
cpu
);
unsigned
int
duration_us
,
count
;
unsigned
int
duration_us
,
hits
,
misses
,
early_hits
;
int
max_early_idx
,
constraint_idx
,
idx
,
i
;
int
max_early_idx
,
constraint_idx
,
idx
,
i
;
ktime_t
delta_tick
;
ktime_t
delta_tick
;
...
@@ -247,7 +247,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -247,7 +247,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
cpu_data
->
sleep_length_ns
=
tick_nohz_get_sleep_length
(
&
delta_tick
);
cpu_data
->
sleep_length_ns
=
tick_nohz_get_sleep_length
(
&
delta_tick
);
duration_us
=
ktime_to_us
(
cpu_data
->
sleep_length_ns
);
duration_us
=
ktime_to_us
(
cpu_data
->
sleep_length_ns
);
count
=
0
;
hits
=
0
;
misses
=
0
;
early_hits
=
0
;
max_early_idx
=
-
1
;
max_early_idx
=
-
1
;
constraint_idx
=
drv
->
state_count
;
constraint_idx
=
drv
->
state_count
;
idx
=
-
1
;
idx
=
-
1
;
...
@@ -258,23 +260,61 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -258,23 +260,61 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
if
(
s
->
disabled
||
su
->
disable
)
{
if
(
s
->
disabled
||
su
->
disable
)
{
/*
/*
* If the "early hits" metric of a disabled state is
* Ignore disabled states with target residencies beyond
* greater than the current maximum, it should be taken
* the anticipated idle duration.
* into account, because it would be a mistake to select
* a deeper state with lower "early hits" metric. The
* index cannot be changed to point to it, however, so
* just increase the max count alone and let the index
* still point to a shallower idle state.
*/
*/
if
(
max_early_idx
>=
0
&&
if
(
s
->
target_residency
>
duration_us
)
count
<
cpu_data
->
states
[
i
].
early_hits
)
continue
;
count
=
cpu_data
->
states
[
i
].
early_hits
;
/*
* This state is disabled, so the range of idle duration
* values corresponding to it is covered by the current
* candidate state, but still the "hits" and "misses"
* metrics of the disabled state need to be used to
* decide whether or not the state covering the range in
* question is good enough.
*/
hits
=
cpu_data
->
states
[
i
].
hits
;
misses
=
cpu_data
->
states
[
i
].
misses
;
if
(
early_hits
>=
cpu_data
->
states
[
i
].
early_hits
||
idx
<
0
)
continue
;
/*
* If the current candidate state has been the one with
* the maximum "early hits" metric so far, the "early
* hits" metric of the disabled state replaces the
* current "early hits" count to avoid selecting a
* deeper state with lower "early hits" metric.
*/
if
(
max_early_idx
==
idx
)
{
early_hits
=
cpu_data
->
states
[
i
].
early_hits
;
continue
;
}
/*
* The current candidate state is closer to the disabled
* one than the current maximum "early hits" state, so
* replace the latter with it, but in case the maximum
* "early hits" state index has not been set so far,
* check if the current candidate state is not too
* shallow for that role.
*/
if
(
!
(
tick_nohz_tick_stopped
()
&&
drv
->
states
[
idx
].
target_residency
<
TICK_USEC
))
{
early_hits
=
cpu_data
->
states
[
i
].
early_hits
;
max_early_idx
=
idx
;
}
continue
;
continue
;
}
}
if
(
idx
<
0
)
if
(
idx
<
0
)
{
idx
=
i
;
/* first enabled state */
idx
=
i
;
/* first enabled state */
hits
=
cpu_data
->
states
[
i
].
hits
;
misses
=
cpu_data
->
states
[
i
].
misses
;
}
if
(
s
->
target_residency
>
duration_us
)
if
(
s
->
target_residency
>
duration_us
)
break
;
break
;
...
@@ -283,11 +323,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -283,11 +323,13 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
constraint_idx
=
i
;
constraint_idx
=
i
;
idx
=
i
;
idx
=
i
;
hits
=
cpu_data
->
states
[
i
].
hits
;
misses
=
cpu_data
->
states
[
i
].
misses
;
if
(
count
<
cpu_data
->
states
[
i
].
early_hits
&&
if
(
early_hits
<
cpu_data
->
states
[
i
].
early_hits
&&
!
(
tick_nohz_tick_stopped
()
&&
!
(
tick_nohz_tick_stopped
()
&&
drv
->
states
[
i
].
target_residency
<
TICK_USEC
))
{
drv
->
states
[
i
].
target_residency
<
TICK_USEC
))
{
count
=
cpu_data
->
states
[
i
].
early_hits
;
early_hits
=
cpu_data
->
states
[
i
].
early_hits
;
max_early_idx
=
i
;
max_early_idx
=
i
;
}
}
}
}
...
@@ -300,8 +342,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -300,8 +342,7 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
* "early hits" metric, but if that cannot be determined, just use the
* "early hits" metric, but if that cannot be determined, just use the
* state selected so far.
* state selected so far.
*/
*/
if
(
cpu_data
->
states
[
idx
].
hits
<=
cpu_data
->
states
[
idx
].
misses
&&
if
(
hits
<=
misses
&&
max_early_idx
>=
0
)
{
max_early_idx
>=
0
)
{
idx
=
max_early_idx
;
idx
=
max_early_idx
;
duration_us
=
drv
->
states
[
idx
].
target_residency
;
duration_us
=
drv
->
states
[
idx
].
target_residency
;
}
}
...
@@ -316,10 +357,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
...
@@ -316,10 +357,9 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
if
(
idx
<
0
)
{
if
(
idx
<
0
)
{
idx
=
0
;
/* No states enabled. Must use 0. */
idx
=
0
;
/* No states enabled. Must use 0. */
}
else
if
(
idx
>
0
)
{
}
else
if
(
idx
>
0
)
{
unsigned
int
count
=
0
;
u64
sum
=
0
;
u64
sum
=
0
;
count
=
0
;
/*
/*
* Count and sum the most recent idle duration values less than
* Count and sum the most recent idle duration values less than
* the current expected idle duration value.
* the current expected idle duration value.
...
...
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