aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/cpufreq_schedutil.c9
-rw-r--r--kernel/sched/fair.c40
-rw-r--r--kernel/sched/sched.h21
3 files changed, 48 insertions, 22 deletions
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index d84e036a7536..636ca6f88c8e 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -196,8 +196,9 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
196 * based on the task model parameters and gives the minimal utilization 196 * based on the task model parameters and gives the minimal utilization
197 * required to meet deadlines. 197 * required to meet deadlines.
198 */ 198 */
199unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, 199unsigned long schedutil_cpu_util(int cpu, unsigned long util_cfs,
200 unsigned long max, enum schedutil_type type) 200 unsigned long max, enum schedutil_type type,
201 struct task_struct *p)
201{ 202{
202 unsigned long dl_util, util, irq; 203 unsigned long dl_util, util, irq;
203 struct rq *rq = cpu_rq(cpu); 204 struct rq *rq = cpu_rq(cpu);
@@ -230,7 +231,7 @@ unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs,
230 */ 231 */
231 util = util_cfs + cpu_util_rt(rq); 232 util = util_cfs + cpu_util_rt(rq);
232 if (type == FREQUENCY_UTIL) 233 if (type == FREQUENCY_UTIL)
233 util = uclamp_util(rq, util); 234 util = uclamp_util_with(rq, util, p);
234 235
235 dl_util = cpu_util_dl(rq); 236 dl_util = cpu_util_dl(rq);
236 237
@@ -290,7 +291,7 @@ static unsigned long sugov_get_util(struct sugov_cpu *sg_cpu)
290 sg_cpu->max = max; 291 sg_cpu->max = max;
291 sg_cpu->bw_dl = cpu_bw_dl(rq); 292 sg_cpu->bw_dl = cpu_bw_dl(rq);
292 293
293 return schedutil_freq_util(sg_cpu->cpu, util, max, FREQUENCY_UTIL); 294 return schedutil_cpu_util(sg_cpu->cpu, util, max, FREQUENCY_UTIL, NULL);
294} 295}
295 296
296/** 297/**
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 28db7ce5c3a6..b798fe7ff7cd 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6231,11 +6231,21 @@ static unsigned long cpu_util_next(int cpu, struct task_struct *p, int dst_cpu)
6231static long 6231static long
6232compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) 6232compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
6233{ 6233{
6234 long util, max_util, sum_util, energy = 0; 6234 unsigned int max_util, util_cfs, cpu_util, cpu_cap;
6235 unsigned long sum_util, energy = 0;
6236 struct task_struct *tsk;
6235 int cpu; 6237 int cpu;
6236 6238
6237 for (; pd; pd = pd->next) { 6239 for (; pd; pd = pd->next) {
6240 struct cpumask *pd_mask = perf_domain_span(pd);
6241
6242 /*
6243 * The energy model mandates all the CPUs of a performance
6244 * domain have the same capacity.
6245 */
6246 cpu_cap = arch_scale_cpu_capacity(cpumask_first(pd_mask));
6238 max_util = sum_util = 0; 6247 max_util = sum_util = 0;
6248
6239 /* 6249 /*
6240 * The capacity state of CPUs of the current rd can be driven by 6250 * The capacity state of CPUs of the current rd can be driven by
6241 * CPUs of another rd if they belong to the same performance 6251 * CPUs of another rd if they belong to the same performance
@@ -6246,11 +6256,29 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd)
6246 * it will not appear in its pd list and will not be accounted 6256 * it will not appear in its pd list and will not be accounted
6247 * by compute_energy(). 6257 * by compute_energy().
6248 */ 6258 */
6249 for_each_cpu_and(cpu, perf_domain_span(pd), cpu_online_mask) { 6259 for_each_cpu_and(cpu, pd_mask, cpu_online_mask) {
6250 util = cpu_util_next(cpu, p, dst_cpu); 6260 util_cfs = cpu_util_next(cpu, p, dst_cpu);
6251 util = schedutil_energy_util(cpu, util); 6261
6252 max_util = max(util, max_util); 6262 /*
6253 sum_util += util; 6263 * Busy time computation: utilization clamping is not
6264 * required since the ratio (sum_util / cpu_capacity)
6265 * is already enough to scale the EM reported power
6266 * consumption at the (eventually clamped) cpu_capacity.
6267 */
6268 sum_util += schedutil_cpu_util(cpu, util_cfs, cpu_cap,
6269 ENERGY_UTIL, NULL);
6270
6271 /*
6272 * Performance domain frequency: utilization clamping
6273 * must be considered since it affects the selection
6274 * of the performance domain frequency.
6275 * NOTE: in case RT tasks are running, by default the
6276 * FREQUENCY_UTIL's utilization can be max OPP.
6277 */
6278 tsk = cpu == dst_cpu ? p : NULL;
6279 cpu_util = schedutil_cpu_util(cpu, util_cfs, cpu_cap,
6280 FREQUENCY_UTIL, tsk);
6281 max_util = max(max_util, cpu_util);
6254 } 6282 }
6255 6283
6256 energy += em_pd_energy(pd->em_pd, max_util, sum_util); 6284 energy += em_pd_energy(pd->em_pd, max_util, sum_util);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 1783f6b4c2e0..802b1f3405f2 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -2322,7 +2322,6 @@ static inline unsigned long capacity_orig_of(int cpu)
2322} 2322}
2323#endif 2323#endif
2324 2324
2325#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL
2326/** 2325/**
2327 * enum schedutil_type - CPU utilization type 2326 * enum schedutil_type - CPU utilization type
2328 * @FREQUENCY_UTIL: Utilization used to select frequency 2327 * @FREQUENCY_UTIL: Utilization used to select frequency
@@ -2338,15 +2337,11 @@ enum schedutil_type {
2338 ENERGY_UTIL, 2337 ENERGY_UTIL,
2339}; 2338};
2340 2339
2341unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, 2340#ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL
2342 unsigned long max, enum schedutil_type type);
2343 2341
2344static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs) 2342unsigned long schedutil_cpu_util(int cpu, unsigned long util_cfs,
2345{ 2343 unsigned long max, enum schedutil_type type,
2346 unsigned long max = arch_scale_cpu_capacity(cpu); 2344 struct task_struct *p);
2347
2348 return schedutil_freq_util(cpu, cfs, max, ENERGY_UTIL);
2349}
2350 2345
2351static inline unsigned long cpu_bw_dl(struct rq *rq) 2346static inline unsigned long cpu_bw_dl(struct rq *rq)
2352{ 2347{
@@ -2375,11 +2370,13 @@ static inline unsigned long cpu_util_rt(struct rq *rq)
2375 return READ_ONCE(rq->avg_rt.util_avg); 2370 return READ_ONCE(rq->avg_rt.util_avg);
2376} 2371}
2377#else /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */ 2372#else /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */
2378static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs) 2373static inline unsigned long schedutil_cpu_util(int cpu, unsigned long util_cfs,
2374 unsigned long max, enum schedutil_type type,
2375 struct task_struct *p)
2379{ 2376{
2380 return cfs; 2377 return 0;
2381} 2378}
2382#endif 2379#endif /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */
2383 2380
2384#ifdef CONFIG_HAVE_SCHED_AVG_IRQ 2381#ifdef CONFIG_HAVE_SCHED_AVG_IRQ
2385static inline unsigned long cpu_util_irq(struct rq *rq) 2382static inline unsigned long cpu_util_irq(struct rq *rq)