Skip to content

Commit 7bc2638

Browse files
vingu-linaroIngo Molnar
authored andcommitted
sched/topology: Consolidate and clean up access to a CPU's max compute capacity
Remove the rq::cpu_capacity_orig field and use arch_scale_cpu_capacity() instead. The scheduler uses 3 methods to get access to a CPU's max compute capacity: - arch_scale_cpu_capacity(cpu) which is the default way to get a CPU's capacity. - cpu_capacity_orig field which is periodically updated with arch_scale_cpu_capacity(). - capacity_orig_of(cpu) which encapsulates rq->cpu_capacity_orig. There is no real need to save the value returned by arch_scale_cpu_capacity() in struct rq. arch_scale_cpu_capacity() returns: - either a per_cpu variable. - or a const value for systems which have only one capacity. Remove rq::cpu_capacity_orig and use arch_scale_cpu_capacity() everywhere. No functional changes. Some performance tests on Arm64: - small SMP device (hikey): no noticeable changes - HMP device (RB5): hackbench shows minor improvement (1-2%) - large smp (thx2): hackbench and tbench shows minor improvement (1%) Signed-off-by: Vincent Guittot <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Reviewed-by: Dietmar Eggemann <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 089768d commit 7bc2638

File tree

8 files changed

+25
-29
lines changed

8 files changed

+25
-29
lines changed

Documentation/scheduler/sched-capacity.rst

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ per Hz, leading to::
3939
-------------------
4040

4141
Two different capacity values are used within the scheduler. A CPU's
42-
``capacity_orig`` is its maximum attainable capacity, i.e. its maximum
43-
attainable performance level. A CPU's ``capacity`` is its ``capacity_orig`` to
44-
which some loss of available performance (e.g. time spent handling IRQs) is
45-
subtracted.
42+
``original capacity`` is its maximum attainable capacity, i.e. its maximum
43+
attainable performance level. This original capacity is returned by
44+
the function arch_scale_cpu_capacity(). A CPU's ``capacity`` is its ``original
45+
capacity`` to which some loss of available performance (e.g. time spent
46+
handling IRQs) is subtracted.
4647

4748
Note that a CPU's ``capacity`` is solely intended to be used by the CFS class,
48-
while ``capacity_orig`` is class-agnostic. The rest of this document will use
49-
the term ``capacity`` interchangeably with ``capacity_orig`` for the sake of
49+
while ``original capacity`` is class-agnostic. The rest of this document will use
50+
the term ``capacity`` interchangeably with ``original capacity`` for the sake of
5051
brevity.
5152

5253
1.3 Platform examples

kernel/sched/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9929,7 +9929,7 @@ void __init sched_init(void)
99299929
#ifdef CONFIG_SMP
99309930
rq->sd = NULL;
99319931
rq->rd = NULL;
9932-
rq->cpu_capacity = rq->cpu_capacity_orig = SCHED_CAPACITY_SCALE;
9932+
rq->cpu_capacity = SCHED_CAPACITY_SCALE;
99339933
rq->balance_callback = &balance_push_callback;
99349934
rq->active_balance = 0;
99359935
rq->next_balance = jiffies;

kernel/sched/cpudeadline.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ int cpudl_find(struct cpudl *cp, struct task_struct *p,
131131
if (!dl_task_fits_capacity(p, cpu)) {
132132
cpumask_clear_cpu(cpu, later_mask);
133133

134-
cap = capacity_orig_of(cpu);
134+
cap = arch_scale_cpu_capacity(cpu);
135135

136136
if (cap > max_cap ||
137137
(cpu == task_cpu(p) && cap == max_cap)) {

kernel/sched/deadline.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ static inline unsigned long __dl_bw_capacity(const struct cpumask *mask)
132132
int i;
133133

134134
for_each_cpu_and(i, mask, cpu_active_mask)
135-
cap += capacity_orig_of(i);
135+
cap += arch_scale_cpu_capacity(i);
136136

137137
return cap;
138138
}
@@ -144,7 +144,7 @@ static inline unsigned long __dl_bw_capacity(const struct cpumask *mask)
144144
static inline unsigned long dl_bw_capacity(int i)
145145
{
146146
if (!sched_asym_cpucap_active() &&
147-
capacity_orig_of(i) == SCHED_CAPACITY_SCALE) {
147+
arch_scale_cpu_capacity(i) == SCHED_CAPACITY_SCALE) {
148148
return dl_bw_cpus(i) << SCHED_CAPACITY_SHIFT;
149149
} else {
150150
RCU_LOCKDEP_WARN(!rcu_read_lock_sched_held(),

kernel/sched/fair.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4669,7 +4669,7 @@ static inline void util_est_update(struct cfs_rq *cfs_rq,
46694669
* To avoid overestimation of actual task utilization, skip updates if
46704670
* we cannot grant there is idle time in this CPU.
46714671
*/
4672-
if (task_util(p) > capacity_orig_of(cpu_of(rq_of(cfs_rq))))
4672+
if (task_util(p) > arch_scale_cpu_capacity(cpu_of(rq_of(cfs_rq))))
46734673
return;
46744674

46754675
/*
@@ -4717,14 +4717,14 @@ static inline int util_fits_cpu(unsigned long util,
47174717
return fits;
47184718

47194719
/*
4720-
* We must use capacity_orig_of() for comparing against uclamp_min and
4720+
* We must use arch_scale_cpu_capacity() for comparing against uclamp_min and
47214721
* uclamp_max. We only care about capacity pressure (by using
47224722
* capacity_of()) for comparing against the real util.
47234723
*
47244724
* If a task is boosted to 1024 for example, we don't want a tiny
47254725
* pressure to skew the check whether it fits a CPU or not.
47264726
*
4727-
* Similarly if a task is capped to capacity_orig_of(little_cpu), it
4727+
* Similarly if a task is capped to arch_scale_cpu_capacity(little_cpu), it
47284728
* should fit a little cpu even if there's some pressure.
47294729
*
47304730
* Only exception is for thermal pressure since it has a direct impact
@@ -4736,7 +4736,7 @@ static inline int util_fits_cpu(unsigned long util,
47364736
* For uclamp_max, we can tolerate a drop in performance level as the
47374737
* goal is to cap the task. So it's okay if it's getting less.
47384738
*/
4739-
capacity_orig = capacity_orig_of(cpu);
4739+
capacity_orig = arch_scale_cpu_capacity(cpu);
47404740
capacity_orig_thermal = capacity_orig - arch_scale_thermal_pressure(cpu);
47414741

47424742
/*
@@ -7217,7 +7217,7 @@ select_idle_capacity(struct task_struct *p, struct sched_domain *sd, int target)
72177217
* Look for the CPU with best capacity.
72187218
*/
72197219
else if (fits < 0)
7220-
cpu_cap = capacity_orig_of(cpu) - thermal_load_avg(cpu_rq(cpu));
7220+
cpu_cap = arch_scale_cpu_capacity(cpu) - thermal_load_avg(cpu_rq(cpu));
72217221

72227222
/*
72237223
* First, select CPU which fits better (-1 being better than 0).
@@ -7459,7 +7459,7 @@ cpu_util(int cpu, struct task_struct *p, int dst_cpu, int boost)
74597459
util = max(util, util_est);
74607460
}
74617461

7462-
return min(util, capacity_orig_of(cpu));
7462+
return min(util, arch_scale_cpu_capacity(cpu));
74637463
}
74647464

74657465
unsigned long cpu_util_cfs(int cpu)
@@ -9250,8 +9250,6 @@ static void update_cpu_capacity(struct sched_domain *sd, int cpu)
92509250
unsigned long capacity = scale_rt_capacity(cpu);
92519251
struct sched_group *sdg = sd->groups;
92529252

9253-
cpu_rq(cpu)->cpu_capacity_orig = arch_scale_cpu_capacity(cpu);
9254-
92559253
if (!capacity)
92569254
capacity = 1;
92579255

@@ -9327,7 +9325,7 @@ static inline int
93279325
check_cpu_capacity(struct rq *rq, struct sched_domain *sd)
93289326
{
93299327
return ((rq->cpu_capacity * sd->imbalance_pct) <
9330-
(rq->cpu_capacity_orig * 100));
9328+
(arch_scale_cpu_capacity(cpu_of(rq)) * 100));
93319329
}
93329330

93339331
/*
@@ -9338,7 +9336,7 @@ check_cpu_capacity(struct rq *rq, struct sched_domain *sd)
93389336
static inline int check_misfit_status(struct rq *rq, struct sched_domain *sd)
93399337
{
93409338
return rq->misfit_task_load &&
9341-
(rq->cpu_capacity_orig < rq->rd->max_cpu_capacity ||
9339+
(arch_scale_cpu_capacity(rq->cpu) < rq->rd->max_cpu_capacity ||
93429340
check_cpu_capacity(rq, sd));
93439341
}
93449342

kernel/sched/rt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ static inline bool rt_task_fits_capacity(struct task_struct *p, int cpu)
471471
min_cap = uclamp_eff_value(p, UCLAMP_MIN);
472472
max_cap = uclamp_eff_value(p, UCLAMP_MAX);
473473

474-
cpu_cap = capacity_orig_of(cpu);
474+
cpu_cap = arch_scale_cpu_capacity(cpu);
475475

476476
return cpu_cap >= min(min_cap, max_cap);
477477
}

kernel/sched/sched.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,6 @@ struct rq {
10331033
struct sched_domain __rcu *sd;
10341034

10351035
unsigned long cpu_capacity;
1036-
unsigned long cpu_capacity_orig;
10371036

10381037
struct balance_callback *balance_callback;
10391038

@@ -2967,11 +2966,6 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {}
29672966
#endif
29682967

29692968
#ifdef CONFIG_SMP
2970-
static inline unsigned long capacity_orig_of(int cpu)
2971-
{
2972-
return cpu_rq(cpu)->cpu_capacity_orig;
2973-
}
2974-
29752969
/**
29762970
* enum cpu_util_type - CPU utilization type
29772971
* @FREQUENCY_UTIL: Utilization used to select frequency

kernel/sched/topology.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2488,12 +2488,15 @@ build_sched_domains(const struct cpumask *cpu_map, struct sched_domain_attr *att
24882488
/* Attach the domains */
24892489
rcu_read_lock();
24902490
for_each_cpu(i, cpu_map) {
2491+
unsigned long capacity;
2492+
24912493
rq = cpu_rq(i);
24922494
sd = *per_cpu_ptr(d.sd, i);
24932495

2496+
capacity = arch_scale_cpu_capacity(i);
24942497
/* Use READ_ONCE()/WRITE_ONCE() to avoid load/store tearing: */
2495-
if (rq->cpu_capacity_orig > READ_ONCE(d.rd->max_cpu_capacity))
2496-
WRITE_ONCE(d.rd->max_cpu_capacity, rq->cpu_capacity_orig);
2498+
if (capacity > READ_ONCE(d.rd->max_cpu_capacity))
2499+
WRITE_ONCE(d.rd->max_cpu_capacity, capacity);
24972500

24982501
cpu_attach_domain(sd, d.rd, i);
24992502
}

0 commit comments

Comments
 (0)