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

Commit d7a6b8be authored by Joonwoo Park's avatar Joonwoo Park Committed by Todd Kjos
Browse files

sched: EAS: fix incorrect energy delta calculation due to rounding error



In order to calculate energy difference we currently iterates CPUs under
the same sched doamin to accumulate total energy cost and compare before
and after :

  for_each_domain(cpu)
          total_energy_before += (cpu_util * power) >> SCHED_CAPACITY_SHIFT;

  for_each_domain(cpu)
          total_energy_after += (cpu_util * power) >> SCHED_CAPACITY_SHIFT;

Doing such can incorrectly calculate and report abs(delta) > 0 when
there is actually no energy delta between before and after because the
same total accumulated cpu_util of all the CPUs can be distributed
differently before and after and it causes different amount of rounding
error.

Fix such incorrectness by shifting just once with accumulated
total_energy.

Change-Id: I82f1e2e358367058960938b4ef81714f57e921cf
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
(moved part to another commit)
Signed-off-by: default avatarChris Redpath <chris.redpath@arm.com>
(cherry picked from commit 11b618a0b2fc8598474a518add7037d4005d83e8)
[trivial cherry-pick issues]
Signed-off-by: default avatarQuentin Perret <quentin.perret@arm.com>
parent 8b34bba6
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -5630,10 +5630,8 @@ static int group_idle_state(struct energy_env *eenv, struct sched_group *sg)
 */
static int sched_group_energy(struct energy_env *eenv)
{
	struct sched_domain *sd;
	int cpu, total_energy = 0;
	struct cpumask visit_cpus;
	struct sched_group *sg;
	u64 total_energy = 0;

	WARN_ON(!eenv->sg_top->sge);

@@ -5641,8 +5639,8 @@ static int sched_group_energy(struct energy_env *eenv)

	while (!cpumask_empty(&visit_cpus)) {
		struct sched_group *sg_shared_cap = NULL;

		cpu = cpumask_first(&visit_cpus);
		int cpu = cpumask_first(&visit_cpus);
		struct sched_domain *sd;

		/*
		 * Is the group utilization affected by cpus outside this
@@ -5654,7 +5652,7 @@ static int sched_group_energy(struct energy_env *eenv)
			sg_shared_cap = sd->parent->groups;

		for_each_domain(cpu, sd) {
			sg = sd->groups;
			struct sched_group *sg = sd->groups;

			/* Has this sched_domain already been visited? */
			if (sd->child && group_first_cpu(sg) != cpu)
@@ -5690,11 +5688,9 @@ static int sched_group_energy(struct energy_env *eenv)
				idle_idx = group_idle_state(eenv, sg);
				group_util = group_norm_util(eenv, sg);

				sg_busy_energy = (group_util * sg->sge->cap_states[cap_idx].power)
								>> SCHED_CAPACITY_SHIFT;
				sg_busy_energy = (group_util * sg->sge->cap_states[cap_idx].power);
				sg_idle_energy = ((SCHED_CAPACITY_SCALE-group_util)
								* sg->sge->idle_states[idle_idx].power)
								>> SCHED_CAPACITY_SHIFT;
								* sg->sge->idle_states[idle_idx].power);

				total_energy += sg_busy_energy + sg_idle_energy;

@@ -5719,7 +5715,7 @@ static int sched_group_energy(struct energy_env *eenv)
		continue;
	}

	eenv->energy = total_energy;
	eenv->energy = total_energy >> SCHED_CAPACITY_SHIFT;
	return 0;
}