]> err.no Git - linux-2.6/commitdiff
[S390] Make sure enabled wait psw is loaded in default_idle.
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 19 Feb 2008 14:29:26 +0000 (15:29 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 19 Feb 2008 14:29:33 +0000 (15:29 +0100)
If both NO_IDLE_HZ and VIRT_TIMER are disabled default_idle won't load
an enabled wait psw and busy loop instead. This is because the
idle_chain is empty and the return value of atomic_notifier_call_chain
will be NOTIFY_DONE, which causes default_idle to return instead of
loading an enabled wait psw.
Fix this by calling __atomic_notifier_call_chain instead and add proper
return value handling.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/process.c

index a6a4729e0e942bcc23a49ad3c7a17f2ac56bbfd8..1c59ec161cf8772e5ac260aa0cce812c4db84ba8 100644 (file)
@@ -114,24 +114,27 @@ extern void s390_handle_mcck(void);
 static void default_idle(void)
 {
        int cpu, rc;
+       int nr_calls = 0;
+       void *hcpu;
 #ifdef CONFIG_SMP
        struct s390_idle_data *idle;
 #endif
 
        /* CPU is going idle. */
        cpu = smp_processor_id();
-
+       hcpu = (void *)(long)cpu;
        local_irq_disable();
        if (need_resched()) {
                local_irq_enable();
                return;
        }
 
-       rc = atomic_notifier_call_chain(&idle_chain,
-                                       S390_CPU_IDLE, (void *)(long) cpu);
-       if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
-               BUG();
-       if (rc != NOTIFY_OK) {
+       rc = __atomic_notifier_call_chain(&idle_chain, S390_CPU_IDLE, hcpu, -1,
+                                         &nr_calls);
+       if (rc == NOTIFY_BAD) {
+               nr_calls--;
+               __atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
+                                            hcpu, nr_calls, NULL);
                local_irq_enable();
                return;
        }