From: Jeremy Fitzhardinge Date: Fri, 26 Aug 2011 21:20:35 +0000 (-0700) Subject: Merge branch 'upstream/ticketlock-cleanup' into upstream/xen X-Git-Tag: next-20110829~16^2 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=fa40b015c1b500d22d17f7d20166f0070f23efa2;p=karo-tx-linux.git Merge branch 'upstream/ticketlock-cleanup' into upstream/xen * upstream/ticketlock-cleanup: x86/ticketlock: make __ticket_spin_trylock common x86/ticketlock: convert __ticket_spin_lock to use xadd() x86/ticketlock: convert spin loop to C x86/ticketlock: clean up types and accessors x86: use xadd helper more widely x86: add xadd helper macro x86/cmpxchg: unify cmpxchg into cmpxchg.h x86/cmpxchg: move 64-bit set64_bit() to match 32-bit x86/cmpxchg: move 32-bit __cmpxchg_wrong_size to match 64 bit. x86/cmpxchg: linux/alternative.h has LOCK_PREFIX --- fa40b015c1b500d22d17f7d20166f0070f23efa2 diff --cc arch/x86/include/asm/spinlock_types.h index 7c7a486fcb68,72e154eb939d..8ebd5df7451e --- a/arch/x86/include/asm/spinlock_types.h +++ b/arch/x86/include/asm/spinlock_types.h @@@ -5,12 -5,34 +5,30 @@@ # error "please don't include this file directly" #endif + #include + + #if (CONFIG_NR_CPUS < 256) + typedef u8 __ticket_t; + typedef u16 __ticketpair_t; + #else + typedef u16 __ticket_t; + typedef u32 __ticketpair_t; + #endif + + #define TICKET_SHIFT (sizeof(__ticket_t) * 8) + #define TICKET_MASK ((__ticket_t)((1 << TICKET_SHIFT) - 1)) + typedef struct arch_spinlock { - unsigned int slock; + union { + __ticketpair_t head_tail; + struct __raw_tickets { + __ticket_t head, tail; + } tickets; + }; } arch_spinlock_t; - #define __ARCH_SPIN_LOCK_UNLOCKED { 0 } + #define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } } -typedef struct { - unsigned int lock; -} arch_rwlock_t; - -#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } +#include #endif /* _ASM_X86_SPINLOCK_TYPES_H */ diff --cc arch/x86/include/asm/uv/uv_bau.h index 37d369859c8e,ebc9344da98a..c568ccca6e0e --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h @@@ -654,35 -485,9 +654,31 @@@ static inline int atomic_read_short(con * * Atomically adds @i to @v and returns @i + @v */ -static inline int atomic_add_short_return(short i, struct atomic_short *v) +static inline int atom_asr(short i, struct atomic_short *v) { - short __i = i; - asm volatile(LOCK_PREFIX "xaddw %0, %1" - : "+r" (i), "+m" (v->counter) - : : "memory"); - return i + __i; + return i + xadd(&v->counter, i); } +/* + * conditionally add 1 to *v, unless *v is >= u + * return 0 if we cannot add 1 to *v because it is >= u + * return 1 if we can add 1 to *v because it is < u + * the add is atomic + * + * This is close to atomic_add_unless(), but this allows the 'u' value + * to be lowered below the current 'v'. atomic_add_unless can only stop + * on equal. + */ +static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u) +{ + spin_lock(lock); + if (atomic_read(v) >= u) { + spin_unlock(lock); + return 0; + } + atomic_inc(v); + spin_unlock(lock); + return 1; +} + #endif /* _ASM_X86_UV_UV_BAU_H */