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

Commit 3e7ec426 authored by Pavankumar Kondeti's avatar Pavankumar Kondeti
Browse files

sched: add a knob to prefer the waker CPU to an idle CPU in waker cluster



The current policy has a preference to select an idle CPU in the waker
cluster compared to the waker CPU running only 1 task. By selecting
an idle CPU, it eliminates the chance of waker migrating to a
different CPU after the wakee preempts it. This policy is also not
susceptible to the incorrect "sync" usage i.e the waker does not goto
sleep after waking up the wakee.

However LPM exit latency associated with an idle CPU outweigh the
above benefits on some targets. So add a knob to prefer the waker
CPU having only 1 runnable task over idle CPUs in the waker cluster.

Change-Id: Id974748c07625c1b19112235f426a5d204dfdb33
Signed-off-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
parent e14d325a
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -1293,7 +1293,7 @@ categorized as small wakee tasks. Scheduler places small wakee tasks on the
waker's cluster.


*** 7.26 sched_big_waker_task_load
*** 7.27 sched_big_waker_task_load

Appears at: /proc/sys/kernel/sched_big_waker_task_load

@@ -1303,6 +1303,23 @@ This tunable is a percentage. Configure the minimum demand of big sync waker
task.  Scheduler places small wakee tasks woken up by big sync waker on the
waker's cluster.

*** 7.28 sched_prefer_sync_wakee_to_waker

Appears at: /proc/sys/kernel/sched_prefer_sync_wakee_to_waker

Default value: 0

The default sync wakee policy has a preference to select an idle CPU in the
waker cluster compared to the waker CPU running only 1 task. By selecting
an idle CPU, it eliminates the chance of waker migrating to a different CPU
after the wakee preempts it. This policy is also not susceptible to the
incorrect "sync" usage i.e the waker does not goto sleep after waking up
the wakee.

However LPM exit latency associated with an idle CPU outweigh the above
benefits on some targets. When this knob is turned on, the waker CPU is
selected if it has only 1 runnable task.

=========================
8. HMP SCHEDULER TRACE POINTS
=========================
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ extern unsigned int sysctl_sched_boost;
extern unsigned int sysctl_early_detection_duration;
extern unsigned int sysctl_sched_small_wakee_task_load_pct;
extern unsigned int sysctl_sched_big_waker_task_load_pct;
extern unsigned int sysctl_sched_prefer_sync_wakee_to_waker;

#ifdef CONFIG_SCHED_QHMP
extern unsigned int sysctl_sched_min_runtime;
+22 −6
Original line number Diff line number Diff line
@@ -2479,6 +2479,13 @@ unsigned int __read_mostly sysctl_sched_small_wakee_task_load_pct = 10;
unsigned int __read_mostly sched_big_waker_task_load;
unsigned int __read_mostly sysctl_sched_big_waker_task_load_pct = 25;

/*
 * Prefer the waker CPU for sync wakee task, if the CPU has only 1 runnable
 * task. This eliminates the LPM exit latency associated with the idle
 * CPUs in the waker cluster.
 */
unsigned int __read_mostly sysctl_sched_prefer_sync_wakee_to_waker;

/*
 * CPUs with load greater than the sched_spill_load_threshold are not
 * eligible for task placement. When all CPUs in a cluster achieve a
@@ -3315,6 +3322,7 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
	struct cluster_cpu_stats stats;
	bool fast_path = false;
	struct related_thread_group *grp;
	int cpu = raw_smp_processor_id();

	struct cpu_select_env env = {
		.p			= p,
@@ -3344,12 +3352,20 @@ static int select_best_cpu(struct task_struct *p, int target, int reason,
		else
			env.rtg = grp;
	} else {
		cluster = cpu_rq(smp_processor_id())->cluster;
		if (wake_to_waker_cluster(&env) &&
		    cluster_allowed(p, cluster)) {
		cluster = cpu_rq(cpu)->cluster;
		if (wake_to_waker_cluster(&env)) {
			if (sysctl_sched_prefer_sync_wakee_to_waker &&
				cpu_rq(cpu)->nr_running == 1 &&
				cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
				cpu_active(cpu)) {
				fast_path = true;
				target = cpu;
				goto out;
			} else if (cluster_allowed(p, cluster)) {
				env.need_waker_cluster = 1;
				bitmap_zero(env.candidate_list, NR_CPUS);
				__set_bit(cluster->id, env.candidate_list);
			}
		} else if (bias_to_prev_cpu(&env, &stats)) {
			fast_path = true;
			goto out;
+9 −0
Original line number Diff line number Diff line
@@ -481,6 +481,15 @@ static struct ctl_table kern_table[] = {
		.mode           = 0644,
		.proc_handler   = proc_dointvec,
	},
	{
		.procname	= "sched_prefer_sync_wakee_to_waker",
		.data		= &sysctl_sched_prefer_sync_wakee_to_waker,
		.maxlen		= sizeof(unsigned int),
		.mode		= 0644,
		.proc_handler	= proc_dointvec_minmax,
		.extra1		= &zero,
		.extra2		= &one,
	},
#ifdef CONFIG_SCHED_FREQ_INPUT
	{
		.procname       = "sched_new_task_windows",