summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorJoonwoo Park <joonwoop@codeaurora.org>2015-07-02 09:48:33 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:02:08 -0700
commitb1fb594df9371dcfeae484ca71ae23841f9da729 (patch)
treeb356f99da879cd1ffef1981593d9ad599a3049dc /kernel
parenta4c475e43db22d2db8bdea676536792cc6b0f724 (diff)
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 <joonwoop@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched/core.c8
1 files changed, 1 insertions, 7 deletions
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;