]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
sched: Request for idle balance during nohz idle load balance
authorSuresh Siddha <suresh.b.siddha@intel.com>
Mon, 3 Oct 2011 22:09:01 +0000 (15:09 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 6 Oct 2011 10:46:27 +0000 (12:46 +0200)
rq's idle_at_tick is set to idle/busy during the timer tick
depending on the cpu was idle or not. This will be used later in the load
balance that will be done in the softirq context (which is a process
context in -RT kernels).

For nohz kernels, for the cpu doing nohz idle load balance on behalf of
all the idle cpu's, its rq->idle_at_tick might have a stale value (which is
recorded when it got the timer tick presumably when it is busy).

As the nohz idle load balancing is also being done at the same place
as the regular load balancing, nohz idle load balancing was bailing out
when it sees rq's idle_at_tick not set.

Thus leading to poor system utilization.

Rename rq's idle_at_tick to idle_balance and set it when someone requests
for nohz idle balance on an idle cpu.

Reported-by: Srivatsa Vaddagiri <vatsa@linux.vnet.ibm.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20111003220934.892350549@sbsiddha-desk.sc.intel.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
kernel/sched.c
kernel/sched_fair.c

index 9e49af00ae3e41240af20e25e8462734ab4a108b..7bc9b0e84eb36ed459f3c0169526c225fb39683e 100644 (file)
@@ -644,7 +644,7 @@ struct rq {
 
        unsigned long cpu_power;
 
-       unsigned char idle_at_tick;
+       unsigned char idle_balance;
        /* For active balancing */
        int post_schedule;
        int active_balance;
@@ -2751,8 +2751,10 @@ void scheduler_ipi(void)
        /*
         * Check if someone kicked us for doing the nohz idle load balance.
         */
-       if (unlikely(got_nohz_idle_kick() && !need_resched()))
+       if (unlikely(got_nohz_idle_kick() && !need_resched())) {
+               this_rq()->idle_balance = 1;
                raise_softirq_irqoff(SCHED_SOFTIRQ);
+       }
        irq_exit();
 }
 
@@ -4247,7 +4249,7 @@ void scheduler_tick(void)
        perf_event_task_tick();
 
 #ifdef CONFIG_SMP
-       rq->idle_at_tick = idle_cpu(cpu);
+       rq->idle_balance = idle_cpu(cpu);
        trigger_load_balance(rq, cpu);
 #endif
 }
index 6c5fa1099229191e98e4daec7e01c8f6b8dac70f..506db0966eb8e97b23743ce598a686d22f9d5d46 100644 (file)
@@ -4676,7 +4676,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu)
        if (time_before(now, nohz.next_balance))
                return 0;
 
-       if (rq->idle_at_tick)
+       if (idle_cpu(cpu))
                return 0;
 
        first_pick_cpu = atomic_read(&nohz.first_pick_cpu);
@@ -4712,7 +4712,7 @@ static void run_rebalance_domains(struct softirq_action *h)
 {
        int this_cpu = smp_processor_id();
        struct rq *this_rq = cpu_rq(this_cpu);
-       enum cpu_idle_type idle = this_rq->idle_at_tick ?
+       enum cpu_idle_type idle = this_rq->idle_balance ?
                                                CPU_IDLE : CPU_NOT_IDLE;
 
        rebalance_domains(this_cpu, idle);