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

Commit a87828a7 authored by Joonwoo Park's avatar Joonwoo Park
Browse files

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: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent 4dd4632f
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -2716,7 +2716,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);
@@ -2730,6 +2730,15 @@ 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 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
@@ -2737,6 +2746,7 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event,
		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;

@@ -2955,7 +2965,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);