Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc2c8370 authored by Chris Redpath's avatar Chris Redpath Committed by Quentin Perret
Browse files

ANDROID: sched/rt: Add schedtune accounting to rt task enqueue/dequeue



rt tasks are currently not eligible for schedtune boosting. Make it so
by adding enqueue/dequeue hooks.

For rt tasks, schedtune only acts as a frequency boosting framework, it
has no impact on placement decisions and the prefer_idle attribute is
not used.

Also prepare schedutil use of boosted util for rt task boosting

With this change, schedtune accounting will include rt class tasks,
however boosting currently only applies to the utilization provided by
fair class tasks. Sum up the tracked CPU utilization applying boost to
the aggregate util instead - this includes RT task util in the boosting
if any tasks are runnable.

Scenario 1, considering one CPU:
1x rt task running, util 250, boost 0
1x cfs task runnable, util 250, boost 50
 previous util=250+(50pct_boosted_250) = 887
 new      util=50_pct_boosted_500      = 762

Scenario 2, considering one CPU:
1x rt task running, util 250, boost 50
1x cfs task runnable, util 250, boost 0
 previous util=250+250                 = 500
 new      util=50_pct_boosted_500      = 762

Scenario 3, considering one CPU:
1x rt task running, util 250, boost 50
1x cfs task runnable, util 250, boost 50
 previous util=250+(50pct_boosted_250) = 887
 new      util=50_pct_boosted_500      = 762

Scenario 4:
1x rt task running, util 250, boost 50
 previous util=250                 = 250
 new      util=50_pct_boosted_250  = 637

Change-Id: Ie287cbd0692468525095b5024db9faac8b2f4878
Signed-off-by: default avatarChris Redpath <chris.redpath@arm.com>
(cherry picked from commit 8e266aebf737262aeca9662254a3e61ccc7f8dec)
[ - Fixed conflicts in sugov related to PELT signals of all classes
  - Fixed conflicts related to boosted_cpu_util being in a different
    location
  - Moved the CFS/RT util aggregation out of schedutil_freq_util to
    ease the integration with SchedTune ]
Signed-off-by: default avatarQuentin Perret <quentin.perret@arm.com>
parent 55679f64
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -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;
+3 −4
Original line number Diff line number Diff line
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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);

+5 −5
Original line number Diff line number Diff line
@@ -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

+2 −2
Original line number Diff line number Diff line
@@ -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 */