sched: fix CPU frequency estimation while idle
CPU cycle counter won't increase when CPU or cluster is idle depending on hardware. Thus using cycle counter in that period of time can result in incorrect CPU frequency estimation. Use previously calculated CPU frequency when CPU was idle. Change-Id: I732b50c974a73c08038995900e008b4e16e9437b Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
This commit is contained in:
parent
54c0b0001b
commit
6e8c9ac98d
1 changed files with 19 additions and 9 deletions
|
@ -2702,7 +2702,7 @@ static void update_task_cpu_cycles(struct task_struct *p, int cpu)
|
|||
|
||||
static void
|
||||
update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event,
|
||||
u64 wallclock)
|
||||
u64 wallclock, u64 irqtime)
|
||||
{
|
||||
u64 cur_cycles;
|
||||
int cpu = cpu_of(rq);
|
||||
|
@ -2716,13 +2716,23 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event,
|
|||
}
|
||||
|
||||
cur_cycles = cpu_cycle_counter_cb.get_cpu_cycle_counter(cpu);
|
||||
if (unlikely(cur_cycles < p->cpu_cycles))
|
||||
rq->cc.cycles = cur_cycles + (U64_MAX - p->cpu_cycles);
|
||||
else
|
||||
rq->cc.cycles = cur_cycles - p->cpu_cycles;
|
||||
rq->cc.cycles = rq->cc.cycles * NSEC_PER_MSEC;
|
||||
rq->cc.time = wallclock - p->ravg.mark_start;
|
||||
BUG_ON((s64)rq->cc.time < 0);
|
||||
|
||||
/*
|
||||
* If current task is idle task and irqtime == 0 CPU was
|
||||
* indeed idle and probably its cycle counter was not
|
||||
* increasing. We still need estimatied CPU frequency
|
||||
* for IO wait time accounting. Use the previously
|
||||
* calculated frequency in such a case.
|
||||
*/
|
||||
if (!is_idle_task(rq->curr) || irqtime) {
|
||||
if (unlikely(cur_cycles < p->cpu_cycles))
|
||||
rq->cc.cycles = cur_cycles + (U64_MAX - p->cpu_cycles);
|
||||
else
|
||||
rq->cc.cycles = cur_cycles - p->cpu_cycles;
|
||||
rq->cc.cycles = rq->cc.cycles * NSEC_PER_MSEC;
|
||||
rq->cc.time = wallclock - p->ravg.mark_start;
|
||||
BUG_ON((s64)rq->cc.time < 0);
|
||||
}
|
||||
|
||||
p->cpu_cycles = cur_cycles;
|
||||
|
||||
|
@ -2941,7 +2951,7 @@ update_task_ravg(struct task_struct *p, struct rq *rq, int event,
|
|||
goto done;
|
||||
}
|
||||
|
||||
update_task_rq_cpu_cycles(p, rq, event, wallclock);
|
||||
update_task_rq_cpu_cycles(p, rq, event, wallclock, irqtime);
|
||||
update_task_demand(p, rq, event, wallclock);
|
||||
update_cpu_busy_time(p, rq, event, wallclock, irqtime);
|
||||
update_task_pred_demand(rq, p, event);
|
||||
|
|
Loading…
Add table
Reference in a new issue