lkml.org 
[lkml]   [2010]   [Nov]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 06/14] x86/ticketlock: make __ticket_spin_trylock common
    Date
    From: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>

    Make trylock code common regardless of ticket size.

    Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
    ---
    arch/x86/include/asm/spinlock.h | 49 +++++++--------------------------
    arch/x86/include/asm/spinlock_types.h | 6 +++-
    2 files changed, 14 insertions(+), 41 deletions(-)

    diff --git a/arch/x86/include/asm/spinlock.h b/arch/x86/include/asm/spinlock.h
    index f722f96..3afb1a7 100644
    --- a/arch/x86/include/asm/spinlock.h
    +++ b/arch/x86/include/asm/spinlock.h
    @@ -98,48 +98,19 @@ static __always_inline void __ticket_spin_lock(struct arch_spinlock *lock)
    out: barrier(); /* make sure nothing creeps before the lock is taken */
    }

    -#if (NR_CPUS < 256)
    static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
    {
    - unsigned int tmp, new;
    -
    - asm volatile("movzwl %2, %0\n\t"
    - "cmpb %h0,%b0\n\t"
    - "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"
    - "jne 1f\n\t"
    - LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
    - "1:"
    - "sete %b1\n\t"
    - "movzbl %b1,%0\n\t"
    - : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
    - :
    - : "memory", "cc");
    -
    - return tmp;
    -}
    -#else
    -static __always_inline int __ticket_spin_trylock(arch_spinlock_t *lock)
    -{
    - unsigned tmp;
    - unsigned new;
    -
    - asm volatile("movl %2,%0\n\t"
    - "movl %0,%1\n\t"
    - "roll $16, %0\n\t"
    - "cmpl %0,%1\n\t"
    - "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
    - "jne 1f\n\t"
    - LOCK_PREFIX "cmpxchgl %1,%2\n\t"
    - "1:"
    - "sete %b1\n\t"
    - "movzbl %b1,%0\n\t"
    - : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
    - :
    - : "memory", "cc");
    -
    - return tmp;
    + arch_spinlock_t old, new;
    +
    + old.tickets = ACCESS_ONCE(lock->tickets);
    + if (old.tickets.head != old.tickets.tail)
    + return 0;
    +
    + new.head_tail = old.head_tail + (1 << TICKET_SHIFT);
    +
    + /* cmpxchg is a full barrier, so nothing can move before it */
    + return cmpxchg(&lock->head_tail, old.head_tail, new.head_tail) == old.head_tail;
    }
    -#endif

    static __always_inline void __ticket_spin_unlock(arch_spinlock_t *lock)
    {
    diff --git a/arch/x86/include/asm/spinlock_types.h b/arch/x86/include/asm/spinlock_types.h
    index e3ad1e3..72e154e 100644
    --- a/arch/x86/include/asm/spinlock_types.h
    +++ b/arch/x86/include/asm/spinlock_types.h
    @@ -9,8 +9,10 @@

    #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)
    @@ -18,14 +20,14 @@ typedef u16 __ticket_t;

    typedef struct arch_spinlock {
    union {
    - unsigned int slock;
    + __ticketpair_t head_tail;
    struct __raw_tickets {
    __ticket_t head, tail;
    } tickets;
    };
    } arch_spinlock_t;

    -#define __ARCH_SPIN_LOCK_UNLOCKED { { .slock = 0 } }
    +#define __ARCH_SPIN_LOCK_UNLOCKED { { 0 } }

    typedef struct {
    unsigned int lock;
    --
    1.7.2.3


    \
     
     \ /
      Last update: 2010-11-16 22:13    [W:0.027 / U:30.516 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site