From d95e31c577cafc14c94910c474c42f346629d0b1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 31 May 2004 23:56:21 -0700 Subject: [PATCH] Add comments on load balancing special cases. Ingo explains: The condition is 'impossible', but the whole balancing code is (intentionally) a bit racy: cpus_and(tmp, group->cpumask, cpu_online_map); if (!cpus_weight(tmp)) goto next_group; for_each_cpu_mask(i, tmp) { if (!idle_cpu(i)) goto next_group; push_cpu = i; } rq = cpu_rq(push_cpu); double_lock_balance(busiest, rq); move_tasks(rq, push_cpu, busiest, 1, sd, IDLE); in the for_each_cpu_mask() loop we specifically check for each CPU in the target group to be idle - so push_cpu's runqueue == busiest [== current runqueue] cannot be true because the current CPU is not idle, we are running in the migration thread ... But this is not a real problem, load-balancing we do in a racy way to reduce overhead [and it's all statistics anyway so absolute accuracy is impossible], and active balancing itself is somewhat racy due to the migration-thread wakeup (and the active_balance flag) going outside the runqueue locks [for similar reasons]. so it all looks quite plausible - the normal SMP boxes dont trigger it, but Bjorn's 128-CPU setup with a non-trivial domain hiearachy triggers it. Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- kernel/sched.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/sched.c b/kernel/sched.c index af767b38ca060..019e0db3e0bf9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1681,6 +1681,11 @@ static int load_balance(int this_cpu, runqueue_t *this_rq, busiest = find_busiest_queue(group); if (!busiest) goto out_balanced; + /* + * This should be "impossible", but since load + * balancing is inherently racy and statistical, + * it could happen in theory. + */ if (unlikely(busiest == this_rq)) { WARN_ON(1); goto out_balanced; @@ -1844,7 +1849,14 @@ static void active_load_balance(runqueue_t *busiest, int busiest_cpu) } rq = cpu_rq(push_cpu); - if (busiest == rq) + + /* + * This condition is "impossible", but since load + * balancing is inherently a bit racy and statistical, + * it can trigger.. Reported by Bjorn Helgaas on a + * 128-cpu setup. + */ + if (unlikely(busiest == rq)) goto next_group; double_lock_balance(busiest, rq); move_tasks(rq, push_cpu, busiest, 1, sd, IDLE); -- 2.53.0