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

Commit 11677c13 authored by Joonwoo Park's avatar Joonwoo Park Committed by Gerrit - the friendly Code Review server
Browse files

sched: fix incorrect prev_runnable_sum accounting with long ISR run



At present, when IRQ handler spans multiple scheduler windows, HMP
scheduler resets the IRQ CPU's prev_runnable_sum with its current max
capacity under the assumption that there is no other possible contribution
to the CPU's prev_runnable_sum.  This isn't correct as another CPU can
migrate tasks to the IRQ CPU.

Furthermore such incorrectness can trigger BUG_ON() if the migrated task's
prev_window is larger than migrating CPU's current capacity in following
scenario.

1. ISR on the power efficient CPU has been running for multiple windows.
2. A task which has prev_window higher than IRQ CPU's current capacity
   migrated to the IRQ CPU.
3. Servicing IRQ is done and the IRQ CPU resets its prev_runnable_rum =
   CPU's current capacity.
4. Before window rollover, the task on the IRQ CPU migrates to other CPU
   and fixes up source and destnation CPUs' busy time.
5. BUG_ON(src_rq->prev_runnable_sum < 0) triggers as p->ravg.prev_window
   is larger than src_rq->prev_runnable_sum.

Fix such incorrectness by preserving prev_runnable_sum when ISR spans
multiple scheduler windows.  There is no need to reset it.

CRs-fixed: 828055
Change-Id: I1f95ece026493e49d3810f9c940ec5f698cc0b81
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent 35afb780
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -1600,14 +1600,8 @@ static void update_cpu_busy_time(struct task_struct *p, struct rq *rq,
		/* The IRQ busy time spanned multiple windows. Process the
		 * busy time preceding the current window start first. */
		delta = window_start - mark_start;
		if (delta > window_size) {
		if (delta > window_size)
			delta = window_size;
			/* If there's 1 or more full windows of IRQ busy time
			 * then the entire prev_runnable_sum will be a window
			 * of IRQ time - there should be no contribution from
			 * anything else. */
			rq->prev_runnable_sum = 0;
		}
		delta = scale_exec_time(delta, rq);
		rq->prev_runnable_sum += delta;