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

Commit b1a04fef authored by Morten Rasmussen's avatar Morten Rasmussen Committed by Gerrit - the friendly Code Review server
Browse files

ANDROID: sched: Estimate energy impact of scheduling decisions



Adds a generic energy-aware helper function, energy_diff(), that
calculates energy impact of adding, removing, and migrating utilization
in the system.

cc: Ingo Molnar <mingo@redhat.com>
cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: default avatarMorten Rasmussen <morten.rasmussen@arm.com>
Change-Id: I05ce491e5e97c9f30183a4f8f3131c92aa68cecc
Signed-off-by: default avatarChris Redpath <chris.redpath@arm.com>
Git-commit: 19de2fa7
Git-repo: https://android.googlesource.com/kernel/common/


Signed-off-by: default avatarSatya Durga Srinivasu Prabhala <satyap@codeaurora.org>
parent 42633af7
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -5561,6 +5561,58 @@ static int sched_group_energy(struct energy_env *eenv)
	return 0;
}

static inline bool cpu_in_sg(struct sched_group *sg, int cpu)
{
	return cpu != -1 && cpumask_test_cpu(cpu, sched_group_span(sg));
}

/*
 * energy_diff(): Estimate the energy impact of changing the utilization
 * distribution. eenv specifies the change: utilisation amount, source, and
 * destination cpu. Source or destination cpu may be -1 in which case the
 * utilization is removed from or added to the system (e.g. task wake-up). If
 * both are specified, the utilization is migrated.
 */
static int energy_diff(struct energy_env *eenv)
{
	struct sched_domain *sd;
	struct sched_group *sg;
	int sd_cpu = -1, energy_before = 0, energy_after = 0;

	struct energy_env eenv_before = {
		.util_delta	= 0,
		.src_cpu	= eenv->src_cpu,
		.dst_cpu	= eenv->dst_cpu,
	};

	if (eenv->src_cpu == eenv->dst_cpu)
		return 0;

	sd_cpu = (eenv->src_cpu != -1) ? eenv->src_cpu : eenv->dst_cpu;
	sd = rcu_dereference(per_cpu(sd_ea, sd_cpu));

	if (!sd)
		return 0; /* Error */

	sg = sd->groups;

	do {
		if (cpu_in_sg(sg, eenv->src_cpu) || cpu_in_sg(sg, eenv->dst_cpu)) {
			eenv_before.sg_top = eenv->sg_top = sg;

			if (sched_group_energy(&eenv_before))
				return 0; /* Invalid result abort */
			energy_before += eenv_before.energy;

			if (sched_group_energy(eenv))
				return 0; /* Invalid result abort */
			energy_after += eenv->energy;
		}
	} while (sg = sg->next, sg != sd->groups);

	return energy_after-energy_before;
}

/*
 * Detect M:N waker/wakee relationships via a switching-frequency heuristic.
 *