sched/fair: add triggers for OPP change requests
Each time a task is {en,de}queued we might need to adapt the current frequency to the new usage. Add triggers on {en,de}queue_task_fair() for this purpose. Only trigger a freq request if we are effectively waking up or going to sleep. Filter out load balancing related calls to reduce the number of triggers. [smuckle@linaro.org: resolve merge conflicts, define task_new, use renamed static key sched_freq] cc: Ingo Molnar <mingo@redhat.com> cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Juri Lelli <juri.lelli@arm.com> Signed-off-by: Steve Muckle <smuckle@linaro.org>
This commit is contained in:
parent
a967a45c71
commit
ea429ccef1
1 changed files with 45 additions and 1 deletions
|
@ -4144,6 +4144,21 @@ static inline void hrtick_update(struct rq *rq)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static unsigned long capacity_orig_of(int cpu);
|
||||||
|
static int cpu_util(int cpu);
|
||||||
|
|
||||||
|
static void update_capacity_of(int cpu)
|
||||||
|
{
|
||||||
|
unsigned long req_cap;
|
||||||
|
|
||||||
|
if (!sched_freq())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Convert scale-invariant capacity to cpu. */
|
||||||
|
req_cap = cpu_util(cpu) * SCHED_CAPACITY_SCALE / capacity_orig_of(cpu);
|
||||||
|
set_cfs_cpu_capacity(cpu, true, req_cap);
|
||||||
|
}
|
||||||
|
|
||||||
static bool cpu_overutilized(int cpu);
|
static bool cpu_overutilized(int cpu);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4193,6 +4208,20 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||||
if (!task_new && !rq->rd->overutilized &&
|
if (!task_new && !rq->rd->overutilized &&
|
||||||
cpu_overutilized(rq->cpu))
|
cpu_overutilized(rq->cpu))
|
||||||
rq->rd->overutilized = true;
|
rq->rd->overutilized = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We want to potentially trigger a freq switch
|
||||||
|
* request only for tasks that are waking up; this is
|
||||||
|
* because we get here also during load balancing, but
|
||||||
|
* in these cases it seems wise to trigger as single
|
||||||
|
* request after load balancing is done.
|
||||||
|
*
|
||||||
|
* XXX: how about fork()? Do we need a special
|
||||||
|
* flag/something to tell if we are here after a
|
||||||
|
* fork() (wakeup_task_new)?
|
||||||
|
*/
|
||||||
|
if (!task_new)
|
||||||
|
update_capacity_of(cpu_of(rq));
|
||||||
}
|
}
|
||||||
hrtick_update(rq);
|
hrtick_update(rq);
|
||||||
}
|
}
|
||||||
|
@ -4251,9 +4280,24 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
||||||
update_cfs_shares(cfs_rq);
|
update_cfs_shares(cfs_rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!se)
|
if (!se) {
|
||||||
sub_nr_running(rq, 1);
|
sub_nr_running(rq, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We want to potentially trigger a freq switch
|
||||||
|
* request only for tasks that are going to sleep;
|
||||||
|
* this is because we get here also during load
|
||||||
|
* balancing, but in these cases it seems wise to
|
||||||
|
* trigger as single request after load balancing is
|
||||||
|
* done.
|
||||||
|
*/
|
||||||
|
if (task_sleep) {
|
||||||
|
if (rq->cfs.nr_running)
|
||||||
|
update_capacity_of(cpu_of(rq));
|
||||||
|
else if (sched_freq())
|
||||||
|
set_cfs_cpu_capacity(cpu_of(rq), false, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
hrtick_update(rq);
|
hrtick_update(rq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue