diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2010-02-27 00:37:40 +0300 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-02-27 00:37:31 +0300 |
commit | 59b697874529f5c3cbcaf5816b3d6c584af521e8 (patch) | |
tree | c395952c2a0bb9a3027a37a30dd37cc93b1a7c3f /arch/s390/include/asm | |
parent | 8387c736fcbaec17890b8d075ee4f4623518b54a (diff) | |
download | linux-59b697874529f5c3cbcaf5816b3d6c584af521e8.tar.xz |
[S390] spinlock: check virtual cpu running status
This patch introduces a new function that checks the running status
of a cpu in a hypervisor. This status is not virtualized, so the check
is only correct if running in an LPAR. On acquiring a spinlock, if the
cpu holding the lock is scheduled by the hypervisor, we do a busy wait
on the lock. If it is not scheduled, we yield over to that cpu.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm')
-rw-r--r-- | arch/s390/include/asm/sigp.h | 40 | ||||
-rw-r--r-- | arch/s390/include/asm/smp.h | 24 |
2 files changed, 43 insertions, 21 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 8aa46ce4229c..e3bffd4e2d66 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -25,29 +25,28 @@ static inline int cpu_logical_map(int cpu) } enum { - sigp_unassigned=0x0, - sigp_sense, - sigp_external_call, - sigp_emergency_signal, - sigp_start, - sigp_stop, - sigp_restart, - sigp_unassigned1, - sigp_unassigned2, - sigp_stop_and_store_status, - sigp_unassigned3, - sigp_initial_cpu_reset, - sigp_cpu_reset, - sigp_set_prefix, - sigp_store_status_at_address, - sigp_store_extended_status_at_address + sigp_sense = 1, + sigp_external_call = 2, + sigp_emergency_signal = 3, + sigp_start = 4, + sigp_stop = 5, + sigp_restart = 6, + sigp_stop_and_store_status = 9, + sigp_initial_cpu_reset = 11, + sigp_cpu_reset = 12, + sigp_set_prefix = 13, + sigp_store_status_at_address = 14, + sigp_store_extended_status_at_address = 15, + sigp_set_architecture = 18, + sigp_conditional_emergency_signal = 19, + sigp_sense_running = 21, }; enum { - sigp_order_code_accepted=0, - sigp_status_stored, - sigp_busy, - sigp_not_operational + sigp_order_code_accepted = 0, + sigp_status_stored = 1, + sigp_busy = 2, + sigp_not_operational = 3, }; /* @@ -57,7 +56,6 @@ enum { ec_schedule = 0, ec_call_function, ec_call_function_single, - ec_bit_last }; /* diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index c2d0e638f892..edc03cb9cd79 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -36,6 +36,28 @@ extern void smp_switch_to_cpu(void (*)(void *), void *, unsigned long sp, int from, int to); extern void smp_restart_cpu(void); +/* + * returns 1 if (virtual) cpu is scheduled + * returns 0 otherwise + */ +static inline int smp_vcpu_scheduled(int cpu) +{ + u32 status; + + switch (sigp_ps(&status, 0, cpu, sigp_sense_running)) { + case sigp_status_stored: + /* Check for running status */ + if (status & 0x400) + return 0; + break; + case sigp_not_operational: + return 0; + default: + break; + } + return 1; +} + #else /* CONFIG_SMP */ static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) @@ -43,6 +65,8 @@ static inline void smp_switch_to_ipl_cpu(void (*func)(void *), void *data) func(data); } +#define smp_vcpu_scheduled (1) + #endif /* CONFIG_SMP */ #ifdef CONFIG_HOTPLUG_CPU |