diff options
| author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-12-04 09:40:33 -0500 |
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-12-04 09:40:33 -0500 |
| commit | c6b5b847a7cf11f131c43fe0041443ec11697fc7 (patch) | |
| tree | d15fb7302bd446394ab373128be0a77826566e30 /drivers | |
| parent | 740b5706b9c4b3767f597b3ea76654c6f2a800b2 (diff) | |
[S390] cpu shutdown rework
Let one master cpu kill all other cpus instead of sending an external
interrupt to all other cpus so they can kill themselves.
Simplifies reipl/shutdown functions a lot.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/s390/char/sclp_quiesce.c | 37 |
1 files changed, 1 insertions, 36 deletions
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c index 32004aae95..ffa9282ce9 100644 --- a/drivers/s390/char/sclp_quiesce.c +++ b/drivers/s390/char/sclp_quiesce.c | |||
| @@ -19,52 +19,17 @@ | |||
| 19 | 19 | ||
| 20 | #include "sclp.h" | 20 | #include "sclp.h" |
| 21 | 21 | ||
| 22 | |||
| 23 | #ifdef CONFIG_SMP | ||
| 24 | /* Signal completion of shutdown process. All CPUs except the first to enter | ||
| 25 | * this function: go to stopped state. First CPU: wait until all other | ||
| 26 | * CPUs are in stopped or check stop state. Afterwards, load special PSW | ||
| 27 | * to indicate completion. */ | ||
| 28 | static void | ||
| 29 | do_load_quiesce_psw(void * __unused) | ||
| 30 | { | ||
| 31 | static atomic_t cpuid = ATOMIC_INIT(-1); | ||
| 32 | psw_t quiesce_psw; | ||
| 33 | int cpu; | ||
| 34 | |||
| 35 | if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1) | ||
| 36 | signal_processor(smp_processor_id(), sigp_stop); | ||
| 37 | /* Wait for all other cpus to enter stopped state */ | ||
| 38 | for_each_online_cpu(cpu) { | ||
| 39 | if (cpu == smp_processor_id()) | ||
| 40 | continue; | ||
| 41 | while(!smp_cpu_not_running(cpu)) | ||
| 42 | cpu_relax(); | ||
| 43 | } | ||
| 44 | /* Quiesce the last cpu with the special psw */ | ||
| 45 | quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; | ||
| 46 | quiesce_psw.addr = 0xfff; | ||
| 47 | __load_psw(quiesce_psw); | ||
| 48 | } | ||
| 49 | |||
| 50 | /* Shutdown handler. Perform shutdown function on all CPUs. */ | ||
| 51 | static void | ||
| 52 | do_machine_quiesce(void) | ||
| 53 | { | ||
| 54 | on_each_cpu(do_load_quiesce_psw, NULL, 0, 0); | ||
| 55 | } | ||
| 56 | #else | ||
| 57 | /* Shutdown handler. Signal completion of shutdown by loading special PSW. */ | 22 | /* Shutdown handler. Signal completion of shutdown by loading special PSW. */ |
| 58 | static void | 23 | static void |
| 59 | do_machine_quiesce(void) | 24 | do_machine_quiesce(void) |
| 60 | { | 25 | { |
| 61 | psw_t quiesce_psw; | 26 | psw_t quiesce_psw; |
| 62 | 27 | ||
| 28 | smp_send_stop(); | ||
| 63 | quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; | 29 | quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; |
| 64 | quiesce_psw.addr = 0xfff; | 30 | quiesce_psw.addr = 0xfff; |
| 65 | __load_psw(quiesce_psw); | 31 | __load_psw(quiesce_psw); |
| 66 | } | 32 | } |
| 67 | #endif | ||
| 68 | 33 | ||
| 69 | /* Handler for quiesce event. Start shutdown procedure. */ | 34 | /* Handler for quiesce event. Start shutdown procedure. */ |
| 70 | static void | 35 | static void |
