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

Commit 4fdf00d2 authored by Joonwoo Park's avatar Joonwoo Park
Browse files

sched: EAS: take into account of PF_WAKE_UP_IDLE



Place on an idle CPU when it's possible and requested.

Change-Id: Iab363d249136786c1bc6787de00f445889dbc99e
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent 43003157
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -747,9 +747,9 @@ TRACE_EVENT(sched_cpu_util,

DECLARE_EVENT_CLASS(sched_task_util,

	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff),
	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),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff, need_idle),

	TP_STRUCT__entry(
		__array(char, comm, TASK_COMM_LEN	)
@@ -760,6 +760,7 @@ DECLARE_EVENT_CLASS(sched_task_util,
		__field(int, nominated_cpu		)
		__field(int, target_cpu			)
		__field(int, ediff			)
		__field(bool, need_idle			)
	),

	TP_fast_assign(
@@ -771,30 +772,31 @@ DECLARE_EVENT_CLASS(sched_task_util,
		__entry->nominated_cpu		= nominated_cpu;
		__entry->target_cpu		= target_cpu;
		__entry->ediff			= ediff;
		__entry->need_idle		= need_idle;
	),

	TP_printk("comm=%s pid=%d task_cpu=%d task_util=%lu nominated_cpu=%d target_cpu=%d energy_diff=%d",
		__entry->comm, __entry->pid, __entry->task_cpu, __entry->task_util, __entry->nominated_cpu, __entry->target_cpu, __entry->ediff)
	TP_printk("comm=%s pid=%d task_cpu=%d task_util=%lu nominated_cpu=%d target_cpu=%d energy_diff=%d need_idle=%d",
		__entry->comm, __entry->pid, __entry->task_cpu, __entry->task_util, __entry->nominated_cpu, __entry->target_cpu, __entry->ediff, __entry->need_idle)
);

DEFINE_EVENT(sched_task_util, sched_task_util_overutilzed,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff)
	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_energy_diff,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff)
	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_energy_aware,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff)
	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_imbalance,
	TP_PROTO(struct task_struct *p, int task_cpu, unsigned long task_util, int nominated_cpu, int target_cpu, int ediff),
	TP_ARGS(p, task_cpu, task_util, nominated_cpu, target_cpu, ediff)
	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)
);
#endif

+29 −25
Original line number Diff line number Diff line
@@ -6587,6 +6587,21 @@ static inline int find_best_target(struct task_struct *p, bool boosted, bool pre
	return target_cpu;
}

/*
 * 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);
}

static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
{
	struct sched_domain *sd;
@@ -6606,6 +6621,7 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
	int min_idle_idx_cpu;
	int min_idle_idx = INT_MAX;
	unsigned int target_cpu_util = UINT_MAX;
	bool need_idle;

	sd = rcu_dereference(per_cpu(sd_ea, task_cpu(p)));

@@ -6618,6 +6634,8 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
	sync = sync && sysctl_sched_sync_hint_enable;
	curr_util = boosted_task_util(cpu_rq(cpu)->curr);

	need_idle = wake_to_idle(p);

	if (sysctl_sched_is_big_little) {
		/*
		 * Find group with sufficient capacity. We only get here if no cpu is
@@ -6684,7 +6702,8 @@ 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 (add_capacity_margin(new_util_cum) <
			if (!need_idle &&
			    add_capacity_margin(new_util_cum) <
						capacity_curr_of(i)) {
				if (sysctl_sched_cstate_aware) {
					if (cpu_idle_idx < min_idle_idx ||
@@ -6774,7 +6793,7 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
		if (__cpu_overutilized(task_cpu(p), task_util_boosted)) {
			trace_sched_task_util_overutilzed(p, task_cpu(p),
						task_util(p), target_cpu,
						target_cpu, 0);
						target_cpu, 0, need_idle);
			return target_cpu;
		}

@@ -6783,24 +6802,24 @@ static int energy_aware_wake_cpu(struct task_struct *p, int target, int sync)
			if (ediff >= 0) {
				trace_sched_task_util_energy_diff(p,
						task_cpu(p), task_util(p),
						target_cpu, task_cpu(p),
						ediff);
						target_cpu, task_cpu(p), ediff,
						need_idle);
				return task_cpu(p);
			}
		} else {
			if (ediff > 0) {
				trace_sched_task_util_energy_diff(p,
							task_cpu(p),
							task_util(p),
							target_cpu,
							task_cpu(p), ediff);
						task_cpu(p), task_util(p),
						target_cpu, task_cpu(p), ediff,
						need_idle);
				return task_cpu(p);
			}
		}
	}

	trace_sched_task_util_energy_aware(p, task_cpu(p), task_util(p),
					   target_cpu, target_cpu, ediff);
					   target_cpu, target_cpu, ediff,
					   need_idle);
	return target_cpu;
}

@@ -11015,21 +11034,6 @@ struct cluster_cpu_stats {
	s64 highest_spare_capacity;
};

/*
 * 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);
}

static int spill_threshold_crossed(struct cpu_select_env *env, struct rq *rq)
{
	u64 total_load;