On 12/20/2017 03:22 PM, Peter Zijlstra wrote:
On Fri, Dec 01, 2017 at 06:01:57PM +0000, Brendan Jackman wrote:
@@ -7913,6 +7928,29 @@ static inline void update_sd_lb_stats(struct lb_env
*env, struct sd_lb_stats *sd
if (child && child->flags & SD_PREFER_SIBLING)
prefer_sibling = 1;
+#ifdef CONFIG_NO_HZ_COMMON
+ if (env->idle == CPU_NEWLY_IDLE) {
+ int cpu;
+
+ /* Update the stats of NOHZ idle CPUs in the sd */
+ for_each_cpu_and(cpu, sched_domain_span(env->sd),
+ nohz.idle_cpus_mask) {
+ struct rq *rq = cpu_rq(cpu);
+
+ /* ... Unless we've already done since the last tick */
+ if (time_after(jiffies,
rq->last_blocked_load_update_tick))
+ update_blocked_averages(cpu);
+ }
+ }
+ /*
+ * If we've just updated all of the NOHZ idle CPUs, then we can push
+ * back the next nohz.next_update, which will prevent an unnecessary
+ * wakeup for the nohz stats kick
+ */
+ if (cpumask_subset(nohz.idle_cpus_mask, sched_domain_span(env->sd)))
+ nohz.next_update = jiffies + LOAD_AVG_PERIOD;
+#endif
+
load_idx = get_sd_load_idx(env->sd, env->idle);
do {
We're already going to be iterating all those CPUs through
update_sg_lb_stats(), why not push it all the way down there and avoid
the double iteration?
Brendan doesn't work for ARM anymore although he might still follow this
discussion.
So you think that we can do the time_after(jiffies,
rq->last_blocked_load_update_tick) check in update_sg_lb_stats() and
possibly the update_blocked_averages() for all the cpus in the sd and
then only update nohz.next_update in update_sd_lb_stats(). Let me try
this ...