From 59b697874529f5c3cbcaf5816b3d6c584af521e8 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Fri, 26 Feb 2010 22:37:40 +0100 Subject: [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 Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sigp.h | 40 +++++++++++++++++++--------------------- arch/s390/include/asm/smp.h | 24 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 21 deletions(-) (limited to 'arch/s390/include') diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 8aa46ce4229..e3bffd4e2d6 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 c2d0e638f89..edc03cb9cd7 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 -- cgit v1.2.3