[S390] smp: fix sigp stop handling
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Thu, 29 Oct 2009 14:04:13 +0000 (15:04 +0100)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Thu, 29 Oct 2009 14:05:13 +0000 (15:05 +0100)
According to the architecture a cpu must not necessarily enter stopped
state after completion of a sigp instruction with "stop" order code.
So remove the BUG() statement after self sending sigp stop to avoid
that it ever gets reached.
Also add a sigp busy check to make sure that the order gets delivered.

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

index ee57a42e6e930a9a6be4a985ab6d938bfd97eac8..4890ac6d7faa6da171b096e2e870cc291ffe4c93 100644 (file)
@@ -1595,10 +1595,9 @@ static void stop_run(struct shutdown_trigger *trigger)
 {
        if (strcmp(trigger->name, ON_PANIC_STR) == 0)
                disabled_wait((unsigned long) __builtin_return_address(0));
-       else {
-               signal_processor(smp_processor_id(), sigp_stop);
-               for (;;);
-       }
+       while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+               cpu_relax();
+       for (;;);
 }
 
 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
index c699ac538c499b3bebfe813ad69ada249bc6e110..c99c45b848e34f7ee01e81dcb4a7f2bb24b378a4 100644 (file)
@@ -647,8 +647,8 @@ void __cpu_die(unsigned int cpu)
 void cpu_die(void)
 {
        idle_task_exit();
-       signal_processor(smp_processor_id(), sigp_stop);
-       BUG();
+       while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy)
+               cpu_relax();
        for (;;);
 }
 
index 7c8653e27db669cc53e65d1f49aa0418efba634a..0f4ef3b856d9709a2e769f32d4a521a155754d7d 100644 (file)
@@ -199,6 +199,7 @@ pgm_check_entry:
        brc     2,4b                    /* busy, try again */
 5:
        sigp    %r9,%r2,__SIGP_STOP     /* stop resume (current) CPU */
+       brc     2,5b                    /* busy, try again */
 6:     j       6b
 
 restart_suspend: