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

Commit b20a943e authored by Pavankumar Kondeti's avatar Pavankumar Kondeti Committed by Syed Rameez Mustafa
Browse files

sched: qhmp: add a knob to restrict tasks spreading



There is an opportunity to save power by consolidating the load
to fewer CPUs on some targets. The results indicate that the
aggressive packing results in higher frequency residency, but
still help power as fewer CPUs are used. Provide a knob to
restrict the task spreading.

When sched_restrict_tasks_spread knob is enabled tasks spreading
is contained by applying the following two policies.

- The small tasks are packed up to spill thresholds which otherwise
are packed up to mostly_idle thresholds. This helps in consolidating
the load to fewer CPUs.

- The current CPU selection algorithm for RT tasks looks for the
least loaded CPU in the lower power cluster. Due to this, RT tasks
are getting placed on the idle CPU more often. This CPUs pulls the
tasks from other CPUs as part of the newly_idle load balance after
finishing the RT task execution. This results in more concurrent
CPU usage and hurting the power. Restrict the search to first
available lower power CPU to contain the load to fewer CPUs.
When sched_boost is ON, this restriction is not applied.

CRs-Fixed: 996652
Change-Id: If0d481cc74ff084fe72ff6cdc4d6aeba96171653
Signed-off-by: default avatarPavankumar Kondeti <pkondeti@codeaurora.org>
parent 6f11c7fa
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -1485,6 +1485,22 @@ overcommitted scenario. See notes on sched_spill_nr_run and sched_spill_load for
how overcommitment threshold is defined and also notes on
'sched_upmigrate_min_nice' tunable.

*** 7.26 sched_restrict_tasks_spread

Default value: 0

Appears at /proc/sys/kernel/sched_restrict_tasks_spread

When this knob is enabled tasks spreading is contained by applying the
following two policies.

- The small tasks are packed up to spill thresholds which otherwise are
packed up to mostly_idle thresholds.

- The current CPU selection algorithm for RT tasks looks for the least loaded
CPU in the lower power cluster. Restrict the search to first available lower
power CPU. When sched_boost is ON, this restriction is not applied.

=========================
8. HMP SCHEDULER TRACE POINTS
=========================
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ extern unsigned int sysctl_sched_prefer_sync_wakee_to_waker;
#ifdef CONFIG_SCHED_QHMP
extern unsigned int sysctl_sched_min_runtime;
extern unsigned int sysctl_sched_small_task_pct;
extern unsigned int sysctl_sched_restrict_tasks_spread;
#else
extern unsigned int sysctl_sched_select_prev_cpu_us;
extern unsigned int sysctl_sched_enable_colocation;
+46 −17
Original line number Diff line number Diff line
@@ -2559,6 +2559,15 @@ unsigned int up_down_migrate_scale_factor = 1024;
 */
unsigned int sysctl_sched_boost;

/*
 * When sched_restrict_tasks_spread is enabled, small tasks are packed
 * up to spill thresholds, which otherwise are packed up to mostly_idle
 * thresholds. The RT tasks are also placed on the fist available lowest
 * power CPU which otherwise placed on least loaded CPU including idle
 * CPUs.
 */
unsigned int __read_mostly sysctl_sched_restrict_tasks_spread;

static inline int available_cpu_capacity(int cpu)
{
	struct rq *rq = cpu_rq(cpu);
@@ -3085,13 +3094,30 @@ static int best_small_task_cpu(struct task_struct *p, int sync)
		}

		cpu_load = cpu_load_sync(i, sync);

		if (sysctl_sched_restrict_tasks_spread) {
			tload = scale_load_to_cpu(task_load(p), i);
			if (!spill_threshold_crossed(tload, cpu_load, rq)) {
				if (cpu_load < min_load) {
					min_load = cpu_load;
					best_busy_cpu = i;
				}
			}
			continue;
		}

		if (mostly_idle_cpu_sync(i, cpu_load, sync))
			return i;

	} while ((i = cpumask_first(&search_cpu)) < nr_cpu_ids);

	if (best_busy_cpu != -1)
		return best_busy_cpu;

	if (min_cstate_cpu != -1)
		return min_cstate_cpu;

	if (!sysctl_sched_restrict_tasks_spread) {
		cpumask_and(&search_cpu, tsk_cpus_allowed(p), cpu_online_mask);
		cpumask_andnot(&search_cpu, &search_cpu, &fb_search_cpu);
		for_each_cpu(i, &search_cpu) {
@@ -3105,7 +3131,8 @@ static int best_small_task_cpu(struct task_struct *p, int sync)
			cpu_load = cpu_load_sync(i, sync);
			if (!spill_threshold_crossed(tload, cpu_load, rq)) {
				if (cpu_load < min_load ||
			    (prev_cpu && cpu_load == min_load)) {
						(prev_cpu &&
						 cpu_load == min_load)) {
					min_load = cpu_load;
					best_busy_cpu = i;
				}
@@ -3115,6 +3142,8 @@ static int best_small_task_cpu(struct task_struct *p, int sync)
		if (best_busy_cpu != -1)
			return best_busy_cpu;

	}

	for_each_cpu(i, &fb_search_cpu) {
		rq = cpu_rq(i);
		prev_cpu = (i == task_cpu(p));
+14 −1
Original line number Diff line number Diff line
@@ -1642,6 +1642,8 @@ static int find_lowest_rq_hmp(struct task_struct *task)
	int best_cpu = -1;
	int prev_cpu = task_cpu(task);
	int i;
	int restrict_tasks_spread = sched_boost() ? 0 :
			sysctl_sched_restrict_tasks_spread;

	/* Make sure the mask is initialized first */
	if (unlikely(!lowest_mask))
@@ -1687,7 +1689,18 @@ static int find_lowest_rq_hmp(struct task_struct *task)
		if (sched_cpu_high_irqload(i))
			continue;

		if (cpu_load < min_load ||
		if (restrict_tasks_spread) {
			if (best_cpu == -1) {
				best_cpu = i;
				continue;

			}

			if (cpu_cost < min_cost) {
				min_cost = cpu_cost;
				best_cpu = i;
			}
		} else if (cpu_load < min_load ||
		    (cpu_load == min_load &&
		     (i == prev_cpu || (best_cpu != prev_cpu &&
					cpus_share_cache(prev_cpu, i))))) {
+2 −0
Original line number Diff line number Diff line
@@ -915,6 +915,8 @@ extern unsigned int sched_init_task_load_pelt;
extern unsigned int sched_init_task_load_windows;
extern unsigned int sched_heavy_task;
extern unsigned int up_down_migrate_scale_factor;
extern unsigned int sysctl_sched_restrict_tasks_spread;

extern void reset_cpu_hmp_stats(int cpu, int reset_cra);
extern void fixup_nr_big_small_task(int cpu, int reset_stats);
extern unsigned int max_task_load(void);
Loading