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

Commit 307e7181 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "sched: Consider PF_WAKE_UP_IDLE in select_best_cpu()"

parents 62f7f138 92ba1d55
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -819,9 +819,14 @@ in Sec 5.

This is a per-cpu parameter. If non-zero for a cpu which is part of a cluster
and cluster current frequency is less than this threshold, then scheduler will
poack all tasks on a single cpu in cluster. The cpu chosen is the first most
pack all tasks on a single cpu in cluster. The cpu chosen is the first most
power-efficient cpu found while scanning cluster's online cpus.

- PF_WAKE_UP_IDLE
	Any task that has this flag set in its 'task_struct.flags' field will be
always woken to idle cpu. Further any task woken by such tasks will be also
placed on idle cpu.

For some low band of frequency, spread of task on all available cpus can be
groslly power-inefficient. As an example, consider two tasks that each need
500MHz. Packing them on one cpu could lead to 1GHz. In spread case, we incur
+22 −1
Original line number Diff line number Diff line
@@ -1916,6 +1916,20 @@ static int select_packing_target(struct task_struct *p, int best_cpu)
	return target;
}

/*
 * Should task be woken to any available idle cpu?
 *
 * Waking tasks to idle cpu has mixed implications on both performance and
 * power. In many cases, scheduler can't estimate correctly impact of using idle
 * cpus on either performance or power. PF_WAKE_UP_IDLE allows external kernel
 * module to pass a strong hint to scheduler that the task in question should be
 * woken to idle cpu, generally to improve performance.
 */
static inline int wake_to_idle(struct task_struct *p)
{
	return (current->flags & PF_WAKE_UP_IDLE) ||
			 (p->flags & PF_WAKE_UP_IDLE);
}

/* return cheapest cpu that can fit this task */
static int select_best_cpu(struct task_struct *p, int target, int reason,
@@ -1931,6 +1945,13 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
	int cstate, min_cstate = INT_MAX;
	int prefer_idle = reason ? 1 : sysctl_sched_prefer_idle;
	int curr_cpu = smp_processor_id();
	int prefer_idle_override = 0;

	if (wake_to_idle(p)) {
		prefer_idle = 1;
		prefer_idle_override = 1;
		small_task = 0;
	}

	trace_sched_task_load(p, small_task, boost, reason, sync, prefer_idle);

@@ -2063,7 +2084,7 @@ done:
			best_cpu = fallback_idle_cpu;
	}

	if (cpu_rq(best_cpu)->mostly_idle_freq)
	if (cpu_rq(best_cpu)->mostly_idle_freq && !prefer_idle_override)
		best_cpu = select_packing_target(p, best_cpu);

	return best_cpu;