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

Commit eb128bbb 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 frequent migration of running task"

parents 49b80e86 32c6ac7c
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1250,6 +1250,24 @@ Non-small tasks will prefer to wake up on idle CPUs if this tunable is set to 1.
If the tunable is set to 0, non-small tasks will prefer to wake up on mostly
idle CPUs which are not completely idle, increasing task packing behavior.

** 7.24 sched_min_runtime

Appears at: /proc/sys/kernel/sched_min_runtime

Default value: 200000000 (200ms)

This tunable helps avouid frequent migration of task on account of
energy-awareness. During scheduler tick, a check is made (in migration_needed())
whether the running task needs to be migrated to a "better" cpu, which could
either offer better performance or power. When deciding to migrate task on
account of power, we want to avoid "frequent" migration of task (say every
tick), which could be add more overhead for comparatively little gains. A task's
'run_start' attribute is set when it starts running on a cpu. This information
is used in migration_needed() to avoid "frequent" migrations. Once a task has
been associated with a cpu (in either running or runnable state) for more than
'sched_min_vruntime' ns, it is considered eligible for migration in tick path on
account of energy awareness reasons.

=========================
8. HMP SCHEDULER TRACE POINTS
=========================
+1 −0
Original line number Diff line number Diff line
@@ -1168,6 +1168,7 @@ struct task_struct {
	 * of this task
	 */
	u32 init_load_pct;
	u64 run_start;
#endif
#ifdef CONFIG_CGROUP_SCHED
	struct task_group *sched_task_group;
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ extern unsigned int sysctl_sched_cpu_high_irqload;
extern unsigned int sysctl_sched_freq_account_wait_time;
extern unsigned int sysctl_sched_migration_fixup;
extern unsigned int sysctl_sched_heavy_task_pct;
extern unsigned int sysctl_sched_min_runtime;

#if defined(CONFIG_SCHED_FREQ_INPUT) || defined(CONFIG_SCHED_HMP)
extern unsigned int sysctl_sched_init_task_load_pct;
+16 −0
Original line number Diff line number Diff line
@@ -2519,6 +2519,16 @@ static void restore_orig_mark_start(struct task_struct *p, u64 mark_start)
	p->ravg.mark_start = mark_start;
}

/*
 * Note down when task started running on a cpu. This information will be handy
 * to avoid "too" frequent task migrations for a running task on account of
 * power.
 */
static inline void note_run_start(struct task_struct *p, u64 wallclock)
{
	p->run_start = wallclock;
}

#else	/* CONFIG_SCHED_HMP */

static inline void fixup_busy_time(struct task_struct *p, int new_cpu) { }
@@ -2550,6 +2560,8 @@ restore_orig_mark_start(struct task_struct *p, u64 mark_start)
{
}

static inline void note_run_start(struct task_struct *p, u64 wallclock) { }

#endif	/* CONFIG_SCHED_HMP */

#ifdef CONFIG_SMP
@@ -2581,6 +2593,8 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)

	trace_sched_migrate_task(p, new_cpu, pct_task_load(p));

	note_run_start(p, -1);

	if (task_cpu(p) != new_cpu) {
		struct task_migration_notifier tmn;

@@ -4664,6 +4678,7 @@ need_resched:
			prev->state = TASK_RUNNING;
		} else {
			deactivate_task(rq, prev, DEQUEUE_SLEEP);
			note_run_start(prev, -1);
			prev->on_rq = 0;

			/*
@@ -4694,6 +4709,7 @@ need_resched:
	update_task_ravg(next, rq, PICK_NEXT_TASK, wallclock, 0);
	clear_tsk_need_resched(prev);
	rq->skip_clock_update = 0;
	note_run_start(next, wallclock);

	BUG_ON(task_cpu(next) != cpu_of(rq));

+6 −0
Original line number Diff line number Diff line
@@ -1229,6 +1229,8 @@ unsigned int __read_mostly sched_init_task_load_pelt;
unsigned int __read_mostly sched_init_task_load_windows;
unsigned int __read_mostly sysctl_sched_init_task_load_pct = 15;

unsigned int __read_mostly sysctl_sched_min_runtime = 200000000; /* 200 ms */

static inline unsigned int task_load(struct task_struct *p)
{
	if (sched_use_pelt)
@@ -2287,6 +2289,10 @@ static int lower_power_cpu_available(struct task_struct *p, int cpu)
	int i;
	int lowest_power_cpu = task_cpu(p);
	int lowest_power = power_cost(p, task_cpu(p));
	u64 delta = sched_clock() - p->run_start;

	if (delta < sysctl_sched_min_runtime)
		return 0;

	/* Is a lower-powered idle CPU available which will fit this task? */
	for_each_cpu_and(i, tsk_cpus_allowed(p), cpu_online_mask) {
Loading