ia64/xen-unstable

changeset 18926:6a3c2b4459ad

x86: Clean up and simplify rwlock implementation.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Sat Dec 13 15:56:16 2008 +0000 (2008-12-13)
parents e767f80d4bcc
children 045f70d1acdb
files xen/arch/x86/Makefile xen/arch/x86/rwlock.c xen/include/asm-x86/rwlock.h xen/include/asm-x86/spinlock.h
line diff
     1.1 --- a/xen/arch/x86/Makefile	Sat Dec 13 15:28:10 2008 +0000
     1.2 +++ b/xen/arch/x86/Makefile	Sat Dec 13 15:56:16 2008 +0000
     1.3 @@ -37,7 +37,6 @@ obj-y += nmi.o
     1.4  obj-y += numa.o
     1.5  obj-y += pci.o
     1.6  obj-y += physdev.o
     1.7 -obj-y += rwlock.o
     1.8  obj-y += setup.o
     1.9  obj-y += shutdown.o
    1.10  obj-y += smp.o
     2.1 --- a/xen/arch/x86/rwlock.c	Sat Dec 13 15:28:10 2008 +0000
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,28 +0,0 @@
     2.4 -#include <asm/atomic.h>
     2.5 -#include <asm/rwlock.h>
     2.6 -
     2.7 -#if defined(CONFIG_SMP)
     2.8 -asm(
     2.9 -".align  4\n"
    2.10 -".globl  __write_lock_failed\n"
    2.11 -"__write_lock_failed:\n"
    2.12 -"        " LOCK "addl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
    2.13 -"1:      rep; nop\n"
    2.14 -"        cmpl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
    2.15 -"        jne     1b\n"
    2.16 -"        " LOCK "subl    $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n"
    2.17 -"        jnz     __write_lock_failed\n"
    2.18 -"        ret\n"
    2.19 -
    2.20 -".align  4\n"
    2.21 -".globl  __read_lock_failed\n"
    2.22 -"__read_lock_failed:\n"
    2.23 -"        lock ; incl     (%"__OP"ax)\n"
    2.24 -"1:      rep; nop\n"
    2.25 -"        cmpl    $1,(%"__OP"ax)\n"
    2.26 -"        js      1b\n"
    2.27 -"        lock ; decl     (%"__OP"ax)\n"
    2.28 -"        js      __read_lock_failed\n"
    2.29 -"        ret\n"
    2.30 -);
    2.31 -#endif
     3.1 --- a/xen/include/asm-x86/rwlock.h	Sat Dec 13 15:28:10 2008 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,71 +0,0 @@
     3.4 -/* include/asm-x86/rwlock.h
     3.5 - *
     3.6 - *	Helpers used by both rw spinlocks and rw semaphores.
     3.7 - *
     3.8 - *	Based in part on code from semaphore.h and
     3.9 - *	spinlock.h Copyright 1996 Linus Torvalds.
    3.10 - *
    3.11 - *	Copyright 1999 Red Hat, Inc.
    3.12 - *
    3.13 - *	Written by Benjamin LaHaise.
    3.14 - *
    3.15 - *	This program is free software; you can redistribute it and/or
    3.16 - *	modify it under the terms of the GNU General Public License
    3.17 - *	as published by the Free Software Foundation; either version
    3.18 - *	2 of the License, or (at your option) any later version.
    3.19 - */
    3.20 -#ifndef _ASM_X86_RWLOCK_H
    3.21 -#define _ASM_X86_RWLOCK_H
    3.22 -
    3.23 -#define RW_LOCK_BIAS		 0x01000000
    3.24 -#define RW_LOCK_BIAS_STR	"0x01000000"
    3.25 -
    3.26 -#define __build_read_lock_ptr(rw, helper)   \
    3.27 -	asm volatile(LOCK "subl $1,(%0)\n\t" \
    3.28 -		     "jns 1f\n\t" \
    3.29 -		     "call " helper "\n\t" \
    3.30 -		     "1:\n" \
    3.31 -		     ::"a" (rw) : "memory")
    3.32 -
    3.33 -#define __build_read_lock_const(rw, helper)   \
    3.34 -	asm volatile(LOCK "subl $1,%0\n\t" \
    3.35 -		     "jns 1f\n\t" \
    3.36 -		     "push %%"__OP"ax\n\t" \
    3.37 -		     "lea %0,%%"__OP"ax\n\t" \
    3.38 -		     "call " helper "\n\t" \
    3.39 -		     "pop %%"__OP"ax\n\t" \
    3.40 -		     "1:\n" \
    3.41 -		     :"=m" (*(volatile int *)rw) : : "memory")
    3.42 -
    3.43 -#define __build_read_lock(rw, helper)	do { \
    3.44 -						if (__builtin_constant_p(rw)) \
    3.45 -							__build_read_lock_const(rw, helper); \
    3.46 -						else \
    3.47 -							__build_read_lock_ptr(rw, helper); \
    3.48 -					} while (0)
    3.49 -
    3.50 -#define __build_write_lock_ptr(rw, helper) \
    3.51 -	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
    3.52 -		     "jz 1f\n\t" \
    3.53 -		     "call " helper "\n\t" \
    3.54 -		     "1:\n" \
    3.55 -		     ::"a" (rw) : "memory")
    3.56 -
    3.57 -#define __build_write_lock_const(rw, helper) \
    3.58 -	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
    3.59 -		     "jz 1f\n\t" \
    3.60 -		     "push %%"__OP"ax\n\t" \
    3.61 -		     "lea %0,%%"__OP"ax\n\t" \
    3.62 -		     "call " helper "\n\t" \
    3.63 -		     "pop %%"__OP"ax\n\t" \
    3.64 -		     "1:\n" \
    3.65 -		     :"=m" (*(volatile int *)rw) : : "memory")
    3.66 -
    3.67 -#define __build_write_lock(rw, helper)	do { \
    3.68 -						if (__builtin_constant_p(rw)) \
    3.69 -							__build_write_lock_const(rw, helper); \
    3.70 -						else \
    3.71 -							__build_write_lock_ptr(rw, helper); \
    3.72 -					} while (0)
    3.73 -
    3.74 -#endif
     4.1 --- a/xen/include/asm-x86/spinlock.h	Sat Dec 13 15:28:10 2008 +0000
     4.2 +++ b/xen/include/asm-x86/spinlock.h	Sat Dec 13 15:56:16 2008 +0000
     4.3 @@ -4,7 +4,6 @@
     4.4  #include <xen/config.h>
     4.5  #include <xen/lib.h>
     4.6  #include <asm/atomic.h>
     4.7 -#include <asm/rwlock.h>
     4.8  
     4.9  typedef struct {
    4.10      volatile s16 lock;
    4.11 @@ -49,30 +48,50 @@ typedef struct {
    4.12      volatile unsigned int lock;
    4.13  } raw_rwlock_t;
    4.14  
    4.15 +#define RW_LOCK_BIAS		 0x01000000
    4.16  #define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { RW_LOCK_BIAS }
    4.17  
    4.18 -/*
    4.19 - * On x86, we implement read-write locks as a 32-bit counter
    4.20 - * with the high bit (sign) being the "contended" bit.
    4.21 - */
    4.22  static always_inline void _raw_read_lock(raw_rwlock_t *rw)
    4.23  {
    4.24 -    __build_read_lock(rw, "__read_lock_failed");
    4.25 +    asm volatile (
    4.26 +        "1:  lock; decl %0         \n"
    4.27 +        "    jns 3f                \n"
    4.28 +        "    lock; incl %0         \n"
    4.29 +        "2:  rep; nop              \n"
    4.30 +        "    cmpl $1,%0            \n"
    4.31 +        "    js 2b                 \n"
    4.32 +        "    jmp 1b                \n"
    4.33 +        "3:"
    4.34 +        : "=m" (rw->lock) : : "memory" );
    4.35  }
    4.36  
    4.37  static always_inline void _raw_write_lock(raw_rwlock_t *rw)
    4.38  {
    4.39 -    __build_write_lock(rw, "__write_lock_failed");
    4.40 +    asm volatile (
    4.41 +        "1:  lock; subl %1,%0      \n"
    4.42 +        "    jz 3f                 \n"
    4.43 +        "    lock; addl %1,%0      \n"
    4.44 +        "2:  rep; nop              \n"
    4.45 +        "    cmpl %1,%0            \n"
    4.46 +        "    jne 2b                \n"
    4.47 +        "    jmp 1b                \n"
    4.48 +        "3:"
    4.49 +        : "=m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory" );
    4.50  }
    4.51  
    4.52 -#define _raw_read_unlock(rw)                    \
    4.53 -    asm volatile (                              \
    4.54 -        "lock ; incl %0" :                      \
    4.55 -        "=m" ((rw)->lock) : : "memory" )
    4.56 -#define _raw_write_unlock(rw)                           \
    4.57 -    asm volatile (                                      \
    4.58 -        "lock ; addl $" RW_LOCK_BIAS_STR ",%0" :        \
    4.59 -        "=m" ((rw)->lock) : : "memory" )
    4.60 +static always_inline void _raw_read_unlock(raw_rwlock_t *rw)
    4.61 +{
    4.62 +    asm volatile (
    4.63 +        "lock ; incl %0"
    4.64 +        : "=m" ((rw)->lock) : : "memory" );
    4.65 +}
    4.66 +
    4.67 +static always_inline void _raw_write_unlock(raw_rwlock_t *rw)
    4.68 +{
    4.69 +    asm volatile (
    4.70 +        "lock ; addl %1,%0"
    4.71 +        : "=m" ((rw)->lock) : "i" (RW_LOCK_BIAS) : "memory" );
    4.72 +}
    4.73  
    4.74  #define _raw_rw_is_locked(x) ((x)->lock < RW_LOCK_BIAS)
    4.75