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

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

Merge "sched: Avoid needless migration"

parents 9f25a3ef 232b0fe6
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3765,6 +3765,7 @@ void scheduler_tick(void)
	trigger_load_balance(rq, cpu);
#endif
	rq_last_tick_reset(rq);
	if (curr->sched_class == &fair_sched_class)
		check_for_migration(rq, curr);
}

+53 −14
Original line number Diff line number Diff line
@@ -1712,8 +1712,38 @@ static int best_small_task_cpu(struct task_struct *p)
	return best_fallback_cpu;
}

#define MOVE_TO_BIG_CPU			1
#define MOVE_TO_LITTLE_CPU		2
#define MOVE_TO_POWER_EFFICIENT_CPU	3

static int skip_cpu(struct task_struct *p, int cpu, int reason)
{
	struct rq *rq = cpu_rq(cpu);
	struct rq *task_rq = task_rq(p);
	int skip = 0;

	if (!reason)
		return 0;

	switch (reason) {
	case MOVE_TO_BIG_CPU:
		skip = (rq->capacity <= task_rq->capacity);
		break;

	case MOVE_TO_LITTLE_CPU:
		skip = (rq->capacity >= task_rq->capacity);
		break;

	default:
		skip = (cpu == task_cpu(p));
		break;
	}

	return skip;
}

/* return cheapest cpu that can fit this task */
static int select_best_cpu(struct task_struct *p, int target)
static int select_best_cpu(struct task_struct *p, int target, int reason)
{
	int i, best_cpu = -1, fallback_idle_cpu = -1;
	int prev_cpu = task_cpu(p);
@@ -1730,6 +1760,10 @@ static int select_best_cpu(struct task_struct *p, int target)

	/* Todo : Optimize this loop */
	for_each_cpu_and(i, tsk_cpus_allowed(p), cpu_online_mask) {

		if (skip_cpu(p, i, reason))
			continue;

		trace_sched_cpu_load(cpu_rq(i), idle_cpu(i),
				     mostly_idle_cpu(i), power_cost(p, i));

@@ -2007,10 +2041,11 @@ static int lower_power_cpu_available(struct task_struct *p, int cpu)
	return (lowest_power_cpu != task_cpu(p));
}


/*
 * Check if a task is on the "wrong" cpu (i.e its current cpu is not the ideal
 * cpu as per its demand or priority)
 *
 * Returns reason why task needs to be migrated
 */
static inline int migration_needed(struct rq *rq, struct task_struct *p)
{
@@ -2019,8 +2054,12 @@ static inline int migration_needed(struct rq *rq, struct task_struct *p)
	if (!sched_enable_hmp || p->state != TASK_RUNNING)
		return 0;

	if (sched_boost())
		return (rq->capacity != max_capacity);
	if (sched_boost()) {
		if (rq->capacity != max_capacity)
			return MOVE_TO_BIG_CPU;

		return 0;
	}

	if (is_small_task(p))
		return 0;
@@ -2028,21 +2067,20 @@ static inline int migration_needed(struct rq *rq, struct task_struct *p)
	/* Todo: cgroup-based control? */
	if (nice > sysctl_sched_upmigrate_min_nice &&
		rq->capacity > min_capacity)
			return 1;
			return MOVE_TO_LITTLE_CPU;

	if (!task_will_fit(p, cpu_of(rq)))
		return 1;
		return MOVE_TO_BIG_CPU;

	if (sched_enable_power_aware &&
	    lower_power_cpu_available(p, cpu_of(rq)))
		return 1;
		return MOVE_TO_POWER_EFFICIENT_CPU;

	return 0;
}

/*
 * cpu-bound tasks will not go through select_best_cpu() and hence can be stuck
 * on the wrong cpu. Check if any such tasks need to be "force-migrated"
 * Check if currently running task should be migrated to a better cpu.
 *
 * Todo: Effect this via changes to nohz_balancer_kick() and load balance?
 */
@@ -2050,10 +2088,11 @@ void check_for_migration(struct rq *rq, struct task_struct *p)
{
	int cpu = cpu_of(rq), new_cpu = cpu;
	unsigned long flags;
	int active_balance = 0;
	int active_balance = 0, rc;

	if (migration_needed(rq, p))
		new_cpu = select_best_cpu(p, cpu);
	rc = migration_needed(rq, p);
	if (rc)
		new_cpu = select_best_cpu(p, cpu, rc);

	if (new_cpu == cpu)
		return;
@@ -2088,7 +2127,7 @@ static inline int nr_big_tasks(struct rq *rq)

#define sched_enable_power_aware 0

static inline int select_best_cpu(struct task_struct *p, int target)
static inline int select_best_cpu(struct task_struct *p, int target, int reason)
{
	return 0;
}
@@ -4424,7 +4463,7 @@ select_task_rq_fair(struct task_struct *p, int sd_flag, int wake_flags)
		return prev_cpu;

	if (sched_enable_hmp)
		return select_best_cpu(p, prev_cpu);
		return select_best_cpu(p, prev_cpu, 0);

	if (sd_flag & SD_BALANCE_WAKE) {
		if (cpumask_test_cpu(cpu, tsk_cpus_allowed(p)))