sched: Clean up rebalance_domains() load-balance interval calculation
authorPeter Zijlstra <a.p.zijlstra@chello.nl>
Tue, 5 Apr 2011 08:14:25 +0000 (10:14 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 5 Apr 2011 08:29:36 +0000 (10:29 +0200)
Instead of the possible multiple-evaluation of num_online_cpus()
in rebalance_domains() that Linus reported, avoid it altogether
in the normal case since it's implemented with a Hamming weight
function over a cpu bitmask which can be darn expensive for those
with big iron.

This also makes it cleaner, smaller and documents the code.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1301991265.2225.12.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
kernel/sched.c
kernel/sched_fair.c

index a8845516ace6a446a8a0618c3f3d2a728e9ab36b..17b4d226ee0dae780b46cdf483c857882030043a 100644 (file)
@@ -6331,6 +6331,9 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
                break;
 #endif
        }
+
+       update_max_interval();
+
        return NOTIFY_OK;
 }
 
index c7ec5c8e7b44440c1cbf4f049083742c9ca52159..80ecd09452e0f520f1c3ba6c5518881c22d4c622 100644 (file)
@@ -3820,6 +3820,17 @@ void select_nohz_load_balancer(int stop_tick)
 
 static DEFINE_SPINLOCK(balancing);
 
+static unsigned long __read_mostly max_load_balance_interval = HZ/10;
+
+/*
+ * Scale the max load_balance interval with the number of CPUs in the system.
+ * This trades load-balance latency on larger machines for less cross talk.
+ */
+static void update_max_interval(void)
+{
+       max_load_balance_interval = HZ*num_online_cpus()/10;
+}
+
 /*
  * It checks each scheduling domain to see if it is due to be balanced,
  * and initiates a balancing operation if so.
@@ -3849,10 +3860,7 @@ static void rebalance_domains(int cpu, enum cpu_idle_type idle)
 
                /* scale ms to jiffies */
                interval = msecs_to_jiffies(interval);
-               if (unlikely(!interval))
-                       interval = 1;
-               if (interval > HZ*num_online_cpus()/10)
-                       interval = HZ*num_online_cpus()/10;
+               interval = clamp(interval, 1UL, max_load_balance_interval);
 
                need_serialize = sd->flags & SD_SERIALIZE;