[PATCH 1/4] sched: Don't account tickless CPU load on tick

From: Frederic Weisbecker
Date: Wed Jan 13 2016 - 11:02:36 EST


The cpu load update on tick doesn't care about dynticks and as such is
buggy when occuring on nohz ticks (including idle ticks) as it resets
the jiffies snapshot that was recorded on nohz entry. We eventually
ignore the potentially long tickless load that happened before the
tick.

We can fix this in two ways:

1) Handle the tickless load, but then we must make sure that a freshly
woken task's load doesn't get accounted as the whole previous tickless
load.

2) Ignore nohz ticks and delay the accounting to the nohz exit point.

For simplicity, this patch propose to fix the issue with the second
solution.

Cc: Byungchul Park <byungchul.park@xxxxxxx>
Cc: Mike Galbraith <efault@xxxxxx>
Cc: Chris Metcalf <cmetcalf@xxxxxxxxxx>
Cc: Christoph Lameter <cl@xxxxxxxxx>
Cc: Luiz Capitulino <lcapitulino@xxxxxxxxxx>
Cc: Paul E . McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
Cc: Rik van Riel <riel@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Frederic Weisbecker <fweisbec@xxxxxxxxx>
---
kernel/sched/fair.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 1093873..b849ea8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -4518,10 +4518,20 @@ void update_cpu_load_nohz(int active)
*/
void update_cpu_load_active(struct rq *this_rq)
{
- unsigned long load = weighted_cpuload(cpu_of(this_rq));
+ unsigned long load;
+
+ /*
+ * If the tick is stopped, we can't reliably update the
+ * load without risking to spuriously account the weight
+ * of a freshly woken task as the whole weight of a long
+ * tickless period.
+ */
+ if (tick_nohz_tick_stopped())
+ return;
/*
* See the mess around update_idle_cpu_load() / update_cpu_load_nohz().
*/
+ load = weighted_cpuload(cpu_of(this_rq));
this_rq->last_load_update_tick = jiffies;
__update_cpu_load(this_rq, load, 1, 1);
}
--
2.6.4