diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index b01cd99ffbd0..f1841ce4555f 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -219,6 +219,9 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, * Where the cfs,rt and dl util numbers are tracked with the same metric and * synchronized windows and are thus directly comparable. * + * The @util parameter passed to this function is assumed to be the aggregation + * of RT and CFS util numbers. The cases of DL and IRQ are managed here. + * * The cfs,rt,dl utilization are the running times measured with rq->clock_task * which excludes things like IRQ and steal-time. These latter are then accrued * in the irq utilization. @@ -227,11 +230,11 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, * based on the task model parameters and gives the minimal utilization * required to meet deadlines. */ -unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, +unsigned long schedutil_freq_util(int cpu, unsigned long util, unsigned long max, enum schedutil_type type) { struct rq *rq = cpu_rq(cpu); - unsigned long util, irq; + unsigned long irq; if (sched_feat(SUGOV_RT_MAX_FREQ) && type == FREQUENCY_UTIL && rt_rq_is_runnable(&rq->rt)) @@ -247,14 +250,11 @@ unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, return max; /* - * Because the time spend on RT/DL tasks is visible as 'lost' time to - * CFS tasks and we use the same metric to track the effective - * utilization (PELT windows are synchronized) we can directly add them - * to obtain the CPU's actual utilization. + * The function is called with @util defined as the aggregation (the + * sum) of RT and CFS signals, hence leaving the special case of DL + * to be delt with. The exact way of doing things depend on the calling + * context. */ - util = util_cfs; - util += cpu_util_rt(rq); - if (type == FREQUENCY_UTIL) { /* * For frequency selection we do not make cpu_util_dl() a @@ -267,7 +267,6 @@ unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, * to not quite hit saturation when we should -- * something for later. */ - if ((util + cpu_util_dl(rq)) >= max) return max; } else { @@ -314,7 +313,7 @@ unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, static unsigned long sugov_get_util(struct sugov_cpu *sg_cpu) { struct rq *rq = cpu_rq(sg_cpu->cpu); - unsigned long util = boosted_cpu_util(sg_cpu->cpu); + unsigned long util = boosted_cpu_util(sg_cpu->cpu, cpu_util_rt(rq)); unsigned long max = arch_scale_cpu_capacity(NULL, sg_cpu->cpu); sg_cpu->max = max; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 36d2f3bde904..8f3573d7165d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5849,9 +5849,9 @@ schedtune_task_margin(struct task_struct *task) } unsigned long -boosted_cpu_util(int cpu) +boosted_cpu_util(int cpu, unsigned long other_util) { - unsigned long util = cpu_util_cfs(cpu_rq(cpu)); + unsigned long util = cpu_util_cfs(cpu_rq(cpu)) + other_util; long margin = schedtune_cpu_margin(util, cpu); trace_sched_boost_cpu(cpu, util, margin); @@ -5875,8 +5875,6 @@ schedtune_task_margin(struct task_struct *task) #endif /* CONFIG_SCHED_TUNE */ - - static inline unsigned long boosted_task_util(struct task_struct *task) { @@ -6892,6 +6890,7 @@ compute_energy(struct task_struct *p, int dst_cpu, struct perf_domain *pd) */ for_each_cpu_and(cpu, perf_domain_span(pd), cpu_online_mask) { util = cpu_util_next(cpu, p, dst_cpu); + util += cpu_util_rt(cpu_rq(cpu)); util = schedutil_energy_util(cpu, util); max_util = max(util, max_util); sum_util += util; diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 0be707d9c2db..3eed85fc86db 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1329,6 +1329,8 @@ enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags) { struct sched_rt_entity *rt_se = &p->rt; + schedtune_enqueue_task(p, cpu_of(rq)); + if (flags & ENQUEUE_WAKEUP) rt_se->timeout = 0; @@ -1342,6 +1344,8 @@ static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int flags) { struct sched_rt_entity *rt_se = &p->rt; + schedtune_dequeue_task(p, cpu_of(rq)); + update_curr_rt(rq); dequeue_rt_entity(rt_se, flags); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 3997a6908afd..33911f3f74ac 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2253,19 +2253,19 @@ enum schedutil_type { ENERGY_UTIL, }; -unsigned long schedutil_freq_util(int cpu, unsigned long util_cfs, +unsigned long schedutil_freq_util(int cpu, unsigned long util, unsigned long max, enum schedutil_type type); -static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs) +static inline unsigned long schedutil_energy_util(int cpu, unsigned long util) { unsigned long max = arch_scale_cpu_capacity(NULL, cpu); - return schedutil_freq_util(cpu, cfs, max, ENERGY_UTIL); + return schedutil_freq_util(cpu, util, max, ENERGY_UTIL); } #else /* CONFIG_CPU_FREQ_GOV_SCHEDUTIL */ -static inline unsigned long schedutil_energy_util(int cpu, unsigned long cfs) +static inline unsigned long schedutil_energy_util(int cpu, unsigned long util) { - return cfs; + return util; } #endif diff --git a/kernel/sched/tune.h b/kernel/sched/tune.h index bb187c6112a7..821f026b510f 100644 --- a/kernel/sched/tune.h +++ b/kernel/sched/tune.h @@ -20,7 +20,7 @@ int schedtune_prefer_idle(struct task_struct *tsk); void schedtune_enqueue_task(struct task_struct *p, int cpu); void schedtune_dequeue_task(struct task_struct *p, int cpu); -unsigned long boosted_cpu_util(int cpu); +unsigned long boosted_cpu_util(int cpu, unsigned long other_util); #else /* CONFIG_SCHED_TUNE */ @@ -32,6 +32,6 @@ unsigned long boosted_cpu_util(int cpu); #define schedtune_enqueue_task(task, cpu) do { } while (0) #define schedtune_dequeue_task(task, cpu) do { } while (0) -#define boosted_cpu_util(cpu) cpu_util_cfs(cpu_rq(cpu)) +#define boosted_cpu_util(cpu, other_util) cpu_util_cfs(cpu_rq(cpu)) #endif /* CONFIG_SCHED_TUNE */