| .. | .. |
|---|
| 56 | 56 | #include <linux/kernel.h> |
|---|
| 57 | 57 | #include <linux/stringify.h> |
|---|
| 58 | 58 | #include <linux/bottom_half.h> |
|---|
| 59 | +#include <linux/lockdep.h> |
|---|
| 59 | 60 | #include <asm/barrier.h> |
|---|
| 61 | +#include <asm/mmiowb.h> |
|---|
| 60 | 62 | |
|---|
| 61 | 63 | |
|---|
| 62 | 64 | /* |
|---|
| .. | .. |
|---|
| 74 | 76 | #define LOCK_SECTION_END \ |
|---|
| 75 | 77 | ".previous\n\t" |
|---|
| 76 | 78 | |
|---|
| 77 | | -#define __lockfunc __attribute__((section(".spinlock.text"))) |
|---|
| 79 | +#define __lockfunc __section(".spinlock.text") |
|---|
| 78 | 80 | |
|---|
| 79 | 81 | /* |
|---|
| 80 | 82 | * Pull the arch_spinlock_t and arch_rwlock_t definitions: |
|---|
| .. | .. |
|---|
| 92 | 94 | |
|---|
| 93 | 95 | #ifdef CONFIG_DEBUG_SPINLOCK |
|---|
| 94 | 96 | extern void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, |
|---|
| 95 | | - struct lock_class_key *key); |
|---|
| 96 | | -# define raw_spin_lock_init(lock) \ |
|---|
| 97 | | -do { \ |
|---|
| 98 | | - static struct lock_class_key __key; \ |
|---|
| 99 | | - \ |
|---|
| 100 | | - __raw_spin_lock_init((lock), #lock, &__key); \ |
|---|
| 97 | + struct lock_class_key *key, short inner); |
|---|
| 98 | + |
|---|
| 99 | +# define raw_spin_lock_init(lock) \ |
|---|
| 100 | +do { \ |
|---|
| 101 | + static struct lock_class_key __key; \ |
|---|
| 102 | + \ |
|---|
| 103 | + __raw_spin_lock_init((lock), #lock, &__key, LD_WAIT_SPIN); \ |
|---|
| 101 | 104 | } while (0) |
|---|
| 102 | 105 | |
|---|
| 103 | 106 | #else |
|---|
| .. | .. |
|---|
| 178 | 181 | { |
|---|
| 179 | 182 | __acquire(lock); |
|---|
| 180 | 183 | arch_spin_lock(&lock->raw_lock); |
|---|
| 184 | + mmiowb_spin_lock(); |
|---|
| 181 | 185 | } |
|---|
| 182 | 186 | |
|---|
| 183 | 187 | #ifndef arch_spin_lock_flags |
|---|
| .. | .. |
|---|
| 189 | 193 | { |
|---|
| 190 | 194 | __acquire(lock); |
|---|
| 191 | 195 | arch_spin_lock_flags(&lock->raw_lock, *flags); |
|---|
| 196 | + mmiowb_spin_lock(); |
|---|
| 192 | 197 | } |
|---|
| 193 | 198 | |
|---|
| 194 | 199 | static inline int do_raw_spin_trylock(raw_spinlock_t *lock) |
|---|
| 195 | 200 | { |
|---|
| 196 | | - return arch_spin_trylock(&(lock)->raw_lock); |
|---|
| 201 | + int ret = arch_spin_trylock(&(lock)->raw_lock); |
|---|
| 202 | + |
|---|
| 203 | + if (ret) |
|---|
| 204 | + mmiowb_spin_lock(); |
|---|
| 205 | + |
|---|
| 206 | + return ret; |
|---|
| 197 | 207 | } |
|---|
| 198 | 208 | |
|---|
| 199 | 209 | static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) |
|---|
| 200 | 210 | { |
|---|
| 211 | + mmiowb_spin_unlock(); |
|---|
| 201 | 212 | arch_spin_unlock(&lock->raw_lock); |
|---|
| 202 | 213 | __release(lock); |
|---|
| 203 | 214 | } |
|---|
| .. | .. |
|---|
| 205 | 216 | |
|---|
| 206 | 217 | /* |
|---|
| 207 | 218 | * Define the various spin_lock methods. Note we define these |
|---|
| 208 | | - * regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The |
|---|
| 219 | + * regardless of whether CONFIG_SMP or CONFIG_PREEMPTION are set. The |
|---|
| 209 | 220 | * various methods are defined as nops in the case they are not |
|---|
| 210 | 221 | * required. |
|---|
| 211 | 222 | */ |
|---|
| .. | .. |
|---|
| 318 | 329 | return &lock->rlock; |
|---|
| 319 | 330 | } |
|---|
| 320 | 331 | |
|---|
| 321 | | -#define spin_lock_init(_lock) \ |
|---|
| 322 | | -do { \ |
|---|
| 323 | | - spinlock_check(_lock); \ |
|---|
| 324 | | - raw_spin_lock_init(&(_lock)->rlock); \ |
|---|
| 332 | +#ifdef CONFIG_DEBUG_SPINLOCK |
|---|
| 333 | + |
|---|
| 334 | +# define spin_lock_init(lock) \ |
|---|
| 335 | +do { \ |
|---|
| 336 | + static struct lock_class_key __key; \ |
|---|
| 337 | + \ |
|---|
| 338 | + __raw_spin_lock_init(spinlock_check(lock), \ |
|---|
| 339 | + #lock, &__key, LD_WAIT_CONFIG); \ |
|---|
| 325 | 340 | } while (0) |
|---|
| 326 | 341 | |
|---|
| 342 | +#else |
|---|
| 343 | + |
|---|
| 344 | +# define spin_lock_init(_lock) \ |
|---|
| 345 | +do { \ |
|---|
| 346 | + spinlock_check(_lock); \ |
|---|
| 347 | + *(_lock) = __SPIN_LOCK_UNLOCKED(_lock); \ |
|---|
| 348 | +} while (0) |
|---|
| 349 | + |
|---|
| 350 | +#endif |
|---|
| 351 | + |
|---|
| 327 | 352 | static __always_inline void spin_lock(spinlock_t *lock) |
|---|
| 328 | 353 | { |
|---|
| 329 | 354 | raw_spin_lock(&lock->rlock); |
|---|