Skip to content

Commit e60b56e

Browse files
vingu-linaroPeter Zijlstra
authored andcommitted
sched/fair: Wait before decaying max_newidle_lb_cost
Decay max_newidle_lb_cost only when it has not been updated for a while and ensure to not decay a recently changed value. Signed-off-by: Vincent Guittot <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Dietmar Eggemann <[email protected]> Acked-by: Mel Gorman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9d783c8 commit e60b56e

File tree

3 files changed

+29
-11
lines changed

3 files changed

+29
-11
lines changed

include/linux/sched/topology.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct sched_domain {
105105

106106
/* idle_balance() stats */
107107
u64 max_newidle_lb_cost;
108-
unsigned long next_decay_max_lb_cost;
108+
unsigned long last_decay_max_lb_cost;
109109

110110
u64 avg_scan_cost; /* select_idle_sibling */
111111

kernel/sched/fair.c

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10239,6 +10239,30 @@ void update_max_interval(void)
1023910239
max_load_balance_interval = HZ*num_online_cpus()/10;
1024010240
}
1024110241

10242+
static inline bool update_newidle_cost(struct sched_domain *sd, u64 cost)
10243+
{
10244+
if (cost > sd->max_newidle_lb_cost) {
10245+
/*
10246+
* Track max cost of a domain to make sure to not delay the
10247+
* next wakeup on the CPU.
10248+
*/
10249+
sd->max_newidle_lb_cost = cost;
10250+
sd->last_decay_max_lb_cost = jiffies;
10251+
} else if (time_after(jiffies, sd->last_decay_max_lb_cost + HZ)) {
10252+
/*
10253+
* Decay the newidle max times by ~1% per second to ensure that
10254+
* it is not outdated and the current max cost is actually
10255+
* shorter.
10256+
*/
10257+
sd->max_newidle_lb_cost = (sd->max_newidle_lb_cost * 253) / 256;
10258+
sd->last_decay_max_lb_cost = jiffies;
10259+
10260+
return true;
10261+
}
10262+
10263+
return false;
10264+
}
10265+
1024210266
/*
1024310267
* It checks each scheduling domain to see if it is due to be balanced,
1024410268
* and initiates a balancing operation if so.
@@ -10262,14 +10286,9 @@ static void rebalance_domains(struct rq *rq, enum cpu_idle_type idle)
1026210286
for_each_domain(cpu, sd) {
1026310287
/*
1026410288
* Decay the newidle max times here because this is a regular
10265-
* visit to all the domains. Decay ~1% per second.
10289+
* visit to all the domains.
1026610290
*/
10267-
if (time_after(jiffies, sd->next_decay_max_lb_cost)) {
10268-
sd->max_newidle_lb_cost =
10269-
(sd->max_newidle_lb_cost * 253) / 256;
10270-
sd->next_decay_max_lb_cost = jiffies + HZ;
10271-
need_decay = 1;
10272-
}
10291+
need_decay = update_newidle_cost(sd, 0);
1027310292
max_cost += sd->max_newidle_lb_cost;
1027410293

1027510294
/*
@@ -10911,8 +10930,7 @@ static int newidle_balance(struct rq *this_rq, struct rq_flags *rf)
1091110930

1091210931
t1 = sched_clock_cpu(this_cpu);
1091310932
domain_cost = t1 - t0;
10914-
if (domain_cost > sd->max_newidle_lb_cost)
10915-
sd->max_newidle_lb_cost = domain_cost;
10933+
update_newidle_cost(sd, domain_cost);
1091610934

1091710935
curr_cost += domain_cost;
1091810936
t0 = t1;

kernel/sched/topology.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ sd_init(struct sched_domain_topology_level *tl,
15681568
.last_balance = jiffies,
15691569
.balance_interval = sd_weight,
15701570
.max_newidle_lb_cost = 0,
1571-
.next_decay_max_lb_cost = jiffies,
1571+
.last_decay_max_lb_cost = jiffies,
15721572
.child = child,
15731573
#ifdef CONFIG_SCHED_DEBUG
15741574
.name = tl->name,

0 commit comments

Comments
 (0)