From b1fb594df9371dcfeae484ca71ae23841f9da729 Mon Sep 17 00:00:00 2001 From: Joonwoo Park Date: Thu, 2 Jul 2015 09:48:33 -0700 Subject: 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: Joonwoo Park --- kernel/sched/core.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 6f47fa3dbf41..bdf8b6fe5f27 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1611,14 +1611,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; -- cgit v1.2.3