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

Commit 352e0961 authored by Valentin Schneider's avatar Valentin Schneider Committed by Andres Oportus
Browse files

ANDROID: sched/fair: discount task contribution to find CPU with lowest utilization



In some cases, the new_util of a task can be the same on several
CPUs. This causes an issue because the target_util is only updated
if the current new_util is strictly smaller than target_util.

To fix that, the cpu_util_wake() return value is used alongside the
new_util value. If two CPUs compute the same new_util value,
we'll now also look at their cpu_util_wake() return value. In this
case, the CPU that last ran the task will be chosen in priority.

Change-Id: Ia1ea2c4b3ec39621372c2f748862317d5b497723
Signed-off-by: default avatarValentin Schneider <valentin.schneider@arm.com>
Signed-off-by: default avatarQuentin Perret <quentin.perret@arm.com>
parent db00ec15
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -6560,7 +6560,8 @@ static inline int find_best_target(struct task_struct *p, bool boosted, bool pre
		int i;

		for_each_cpu_and(i, tsk_cpus_allowed(p), sched_group_cpus(sg)) {
			unsigned long cur_capacity, new_util;
			unsigned long cur_capacity, new_util, wake_util;
			unsigned long min_wake_util = ULONG_MAX;

			if (!cpu_online(i))
				continue;
@@ -6570,7 +6571,8 @@ static inline int find_best_target(struct task_struct *p, bool boosted, bool pre
			 * so prev_cpu will receive a negative bias due to the double
			 * accounting. However, the blocked utilization may be zero.
			 */
			new_util = cpu_util_wake(i, p) + task_util(p);
			wake_util = cpu_util_wake(i, p);
			new_util = wake_util + task_util(p);

			/*
			 * Ensure minimum capacity to grant the required boost.
@@ -6604,8 +6606,15 @@ static inline int find_best_target(struct task_struct *p, bool boosted, bool pre
					 * Find a target cpu with the lowest/highest
					 * utilization if prefer_idle/!prefer_idle.
					 */
					if ((prefer_idle && target_util > new_util) ||
					    (!prefer_idle && target_util < new_util)) {
					if (prefer_idle) {
						/* Favor the CPU that last ran the task */
						if (new_util > target_util ||
						    wake_util > min_wake_util)
							continue;
						min_wake_util = wake_util;
						target_util = new_util;
						target_cpu = i;
					} else if (target_util < new_util) {
						target_util = new_util;
						target_cpu = i;
					}