diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2009-10-29 10:04:13 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2009-10-29 10:05:13 -0400 |
commit | f8501ba77d69c88a65e4ebbe03bdc65b1edb0b86 (patch) | |
tree | 27e42cf7bd5171c5b17c2d423b6ae5d3394cb6ef /arch/s390 | |
parent | 70f5dc514c0b183ee813dc3b3983b04891fd1e7a (diff) |
[S390] smp: fix sigp stop handling
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>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/ipl.c | 7 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/swsusp_asm64.S | 1 |
3 files changed, 6 insertions, 6 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index ee57a42e6e93..4890ac6d7faa 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -1595,10 +1595,9 @@ static void stop_run(struct shutdown_trigger *trigger) | |||
1595 | { | 1595 | { |
1596 | if (strcmp(trigger->name, ON_PANIC_STR) == 0) | 1596 | if (strcmp(trigger->name, ON_PANIC_STR) == 0) |
1597 | disabled_wait((unsigned long) __builtin_return_address(0)); | 1597 | disabled_wait((unsigned long) __builtin_return_address(0)); |
1598 | else { | 1598 | while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) |
1599 | signal_processor(smp_processor_id(), sigp_stop); | 1599 | cpu_relax(); |
1600 | for (;;); | 1600 | for (;;); |
1601 | } | ||
1602 | } | 1601 | } |
1603 | 1602 | ||
1604 | static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR, | 1603 | static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR, |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index c699ac538c49..c99c45b848e3 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -647,8 +647,8 @@ void __cpu_die(unsigned int cpu) | |||
647 | void cpu_die(void) | 647 | void cpu_die(void) |
648 | { | 648 | { |
649 | idle_task_exit(); | 649 | idle_task_exit(); |
650 | signal_processor(smp_processor_id(), sigp_stop); | 650 | while (signal_processor(smp_processor_id(), sigp_stop) == sigp_busy) |
651 | BUG(); | 651 | cpu_relax(); |
652 | for (;;); | 652 | for (;;); |
653 | } | 653 | } |
654 | 654 | ||
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index 7c8653e27db6..0f4ef3b856d9 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -199,6 +199,7 @@ pgm_check_entry: | |||
199 | brc 2,4b /* busy, try again */ | 199 | brc 2,4b /* busy, try again */ |
200 | 5: | 200 | 5: |
201 | sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */ | 201 | sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */ |
202 | brc 2,5b /* busy, try again */ | ||
202 | 6: j 6b | 203 | 6: j 6b |
203 | 204 | ||
204 | restart_suspend: | 205 | restart_suspend: |