1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ASM_SPINLOCK_H 2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __ASM_SPINLOCK_H 3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/atomic.h> 5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/rwlock.h> 6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/page.h> 7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/processor.h> 8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/compiler.h> 9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_PARAVIRT 11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/paravirt.h> 12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STRING "cli" 14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define STI_STRING "sti" 15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STI_CLOBBERS 16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define CLI_STI_INPUT_ARGS 17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_PARAVIRT */ 18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Your basic SMP spinlocks, allowing only a single CPU anywhere 21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Simple spin lock operations. There are two variants, one clears IRQ's 23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * on the local processor, one does not. 24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * We make no fairness assumptions. They have a cost. 26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (the type definitions are in asm/spinlock_types.h) 28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_spin_is_locked(raw_spinlock_t *x) 31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return *(volatile signed char *)(&(x)->slock) <= 0; 33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_lock(raw_spinlock_t *lock) 36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("\n1:\t" 38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru LOCK_PREFIX " ; decb %0\n\t" 39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jns 3f\n" 40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\t" 41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "rep;nop\n\t" 42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "cmpb $0,%0\n\t" 43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jle 2b\n\t" 44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jmp 1b\n" 45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3:\n\t" 46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+m" (lock->slock) : : "memory"); 47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * It is easier for the lock validator if interrupts are not re-enabled 51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * in the middle of a lock-acquire. This is a performance feature anyway 52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * so we turn it off: 53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * NOTE: there's an irqs-on section here, which normally would have to be 55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * irq-traced, but on CONFIG_TRACE_IRQFLAGS we never use this variant. 56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef CONFIG_PROVE_LOCKING 58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) 59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile( 61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "\n1:\t" 62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru LOCK_PREFIX " ; decb %[slock]\n\t" 63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jns 5f\n" 64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "2:\t" 65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "testl $0x200, %[flags]\n\t" 66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jz 4f\n\t" 67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru STI_STRING "\n" 68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "3:\t" 69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "rep;nop\n\t" 70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "cmpb $0, %[slock]\n\t" 71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jle 3b\n\t" 72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru CLI_STRING "\n\t" 73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jmp 1b\n" 74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "4:\t" 75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "rep;nop\n\t" 76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "cmpb $0, %[slock]\n\t" 77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jg 1b\n\t" 78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jmp 4b\n" 79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "5:\n\t" 80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : [slock] "+m" (lock->slock) 81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : [flags] "r" (flags) 82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru CLI_STI_INPUT_ARGS 83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "memory" CLI_STI_CLOBBERS); 84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_spin_trylock(raw_spinlock_t *lock) 88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru char oldval; 90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile( 91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "xchgb %b0,%1" 92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru :"=q" (oldval), "+m" (lock->slock) 93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru :"0" (0) : "memory"); 94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return oldval > 0; 95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * __raw_spin_unlock based on writing $1 to the low byte. 99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This method works. Despite all the confusion. 100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (except on PPro SMP or if we are using OOSTORE, so we use xchgb there) 101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * (PPro errata 66, 92) 102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#if !defined(CONFIG_X86_OOSTORE) && !defined(CONFIG_X86_PPRO_FENCE) 105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock(raw_spinlock_t *lock) 107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("movb $1,%0" : "+m" (lock->slock) :: "memory"); 109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else 112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock(raw_spinlock_t *lock) 114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru char oldval = 1; 116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile("xchgb %b0, %1" 118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "=q" (oldval), "+m" (lock->slock) 119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "0" (oldval) : "memory"); 120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif 123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_spin_unlock_wait(raw_spinlock_t *lock) 125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru while (__raw_spin_is_locked(lock)) 127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru cpu_relax(); 128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* 131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Read-write spinlocks, allowing multiple readers 132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * but only one writer. 133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * NOTE! it is quite common to have readers in interrupts 135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * but no interrupt writers. For those circumstances we 136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * can "mix" irq-safe locks - any writer needs to get a 137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * irq-safe write-lock, but readers can get non-irqsafe 138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * read-locks. 139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * On x86, we implement read-write locks as a 32-bit counter 141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * with the high bit (sign) being the "contended" bit. 142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The inline assembly is non-obvious. Think about it. 144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Changed to use the same technique as rw semaphores. See 146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * semaphore.h for details. -ben 147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * 148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the helpers are in arch/i386/kernel/semaphore.c 149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/** 152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * read_can_lock - would read_trylock() succeed? 153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * @lock: the rwlock in question. 154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_read_can_lock(raw_rwlock_t *x) 156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return (int)(x)->lock > 0; 158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/** 161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * write_can_lock - would write_trylock() succeed? 162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * @lock: the rwlock in question. 163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */ 164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_write_can_lock(raw_rwlock_t *x) 165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return (x)->lock == RW_LOCK_BIAS; 167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_lock(raw_rwlock_t *rw) 170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t" 172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jns 1f\n" 173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "call __read_lock_failed\n\t" 174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1:\n" 175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ::"a" (rw) : "memory"); 176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_lock(raw_rwlock_t *rw) 179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile(LOCK_PREFIX " subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" 181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "jz 1f\n" 182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "call __write_lock_failed\n\t" 183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru "1:\n" 184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru ::"a" (rw) : "memory"); 185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_read_trylock(raw_rwlock_t *lock) 188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru atomic_t *count = (atomic_t *)lock; 190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru atomic_dec(count); 191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (atomic_read(count) >= 0) 192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 1; 193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru atomic_inc(count); 194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 0; 195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline int __raw_write_trylock(raw_rwlock_t *lock) 198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru atomic_t *count = (atomic_t *)lock; 200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru if (atomic_sub_and_test(RW_LOCK_BIAS, count)) 201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 1; 202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru atomic_add(RW_LOCK_BIAS, count); 203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru return 0; 204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_read_unlock(raw_rwlock_t *rw) 207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory"); 209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void __raw_write_unlock(raw_rwlock_t *rw) 212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{ 213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru asm volatile(LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ", %0" 214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru : "+m" (rw->lock) : : "memory"); 215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} 216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_spin_relax(lock) cpu_relax() 218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_read_relax(lock) cpu_relax() 219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _raw_write_relax(lock) cpu_relax() 220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru 221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* __ASM_SPINLOCK_H */ 222