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

Commit 44c971bb authored by Joonwoo Park's avatar Joonwoo Park
Browse files

sched: introduce small wakee task on waker



Introduce small wakee task placmenet on waker CPU or cluster so
when the waker's demand is high enough wakee task also can take
advantage of high CPU frequency voted by the waker.

This feature is turned off by default with macro
SCHED_ENABLE_WAKER_WAKEE.

Change-Id: I384a2898a9f8468b4ecd704b184e291816578d58
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent f2bf4b01
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -869,6 +869,11 @@ DECLARE_EVENT_CLASS(sched_task_util,
		__entry->comm, __entry->pid, __entry->task_cpu, __entry->task_util, __entry->nominated_cpu, __entry->target_cpu, __entry->ediff, __entry->need_idle, __entry->latency)
);

DEFINE_EVENT(sched_task_util, sched_task_util_bias_to_waker,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
);

DEFINE_EVENT(sched_task_util, sched_task_util_colocated,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff, bool need_idle),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle)
+55 −4
Original line number Diff line number Diff line
@@ -5399,6 +5399,30 @@ static inline int task_util(struct task_struct *p)
	return p->se.avg.util_avg;
}

#define SCHED_ENABLE_WAKER_WAKEE	0

static unsigned int sched_small_wakee_task_util = 102; /* ~10% of max cap */
static unsigned int sched_big_waker_task_util = 256;  /* 25% of max cap */

static inline bool
wake_on_waker_sibling(struct task_struct *p)
{
	return SCHED_ENABLE_WAKER_WAKEE &&
	       task_util(current) > sched_big_waker_task_util &&
	       task_util(p) < sched_small_wakee_task_util;
}

#define sysctl_sched_prefer_sync_wakee_to_waker 0

static inline bool
bias_to_waker_cpu(struct task_struct *p, int cpu)
{
	return sysctl_sched_prefer_sync_wakee_to_waker &&
	       cpu_rq(cpu)->nr_running == 1 &&
	       cpumask_test_cpu(cpu, tsk_cpus_allowed(p)) &&
	       cpu_active(cpu) && !cpu_isolated(cpu);
}

static int calc_util_delta(struct energy_env *eenv, int cpu)
{
#ifdef CONFIG_SCHED_WALT
@@ -6682,6 +6706,7 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
	unsigned int target_cpu_util = UINT_MAX;
	long target_cpu_new_util_cum = LONG_MAX;
	struct cpumask *rtg_target = NULL;
	bool wake_on_sibling = false;
	bool need_idle;
	bool skip_ediff = false;

@@ -6705,8 +6730,17 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
		grp = task_related_thread_group(p);
		rcu_read_unlock();

		if (grp && grp->preferred_cluster)
		if (grp && grp->preferred_cluster) {
			rtg_target = &grp->preferred_cluster->cpus;
		} else if (sync && wake_on_waker_sibling(p)) {
			if (bias_to_waker_cpu(p, cpu)) {
				trace_sched_task_util_bias_to_waker(p,
						task_cpu(p), task_util(p), cpu,
						cpu, 0, need_idle);
				return cpu;
			}
			wake_on_sibling = true;
		}

		task_util_boosted = boosted_task_util(p);

@@ -6742,6 +6776,11 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
							     rtg_target))
						break;
					continue;
				} else if (wake_on_sibling) {
					/* Skip non-sibling CPUs */
					if (!cpumask_test_cpu(cpu,
							sched_group_cpus(sg)))
						continue;
				} else if (sync && curr_util >=
						   task_util_boosted) {
					if (cpumask_test_cpu(cpu,
@@ -6799,7 +6838,10 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
			cpu_idle_idx = cpu_rq(i)->nr_running ? -1 :
				       idle_get_state_idx(cpu_rq(i));

			if (!need_idle && add_capacity_margin(new_util_cum) <
			if (!need_idle &&
			    (!wake_on_sibling ||
			     (wake_on_sibling && i != cpu)) &&
			    add_capacity_margin(new_util_cum) <
			    capacity_curr_of(i)) {
				if (sysctl_sched_cstate_aware) {
					if (cpu_idle_idx < min_idle_idx) {
@@ -6832,7 +6874,9 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
					target_cpu = i;
					break;
				}
			} else if (!need_idle) {
			} else if (!need_idle &&
				   (!wake_on_sibling ||
				    (wake_on_sibling && i != cpu))) {
				/*
				 * At least one CPU other than target_cpu is
				 * going to raise CPU's OPP higher than current
@@ -6900,6 +6944,13 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
		}
	}

	if (wake_on_sibling && target_cpu != -1) {
		trace_sched_task_util_bias_to_waker(p, task_cpu(p),
						task_util(p), target_cpu,
						target_cpu, 0, need_idle);
		return target_cpu;
	}

	if (target_cpu != task_cpu(p)) {
		struct energy_env eenv = {
			.util_delta	= task_util(p),