diff options
Diffstat (limited to 'kernel/locking/rwsem.c')
| -rw-r--r-- | kernel/locking/rwsem.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index cfff1435bdfb..42f806de49d4 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c | |||
| @@ -12,6 +12,27 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
| 14 | 14 | ||
| 15 | #if defined(CONFIG_SMP) && defined(CONFIG_RWSEM_XCHGADD_ALGORITHM) | ||
| 16 | static inline void rwsem_set_owner(struct rw_semaphore *sem) | ||
| 17 | { | ||
| 18 | sem->owner = current; | ||
| 19 | } | ||
| 20 | |||
| 21 | static inline void rwsem_clear_owner(struct rw_semaphore *sem) | ||
| 22 | { | ||
| 23 | sem->owner = NULL; | ||
| 24 | } | ||
| 25 | |||
| 26 | #else | ||
| 27 | static inline void rwsem_set_owner(struct rw_semaphore *sem) | ||
| 28 | { | ||
| 29 | } | ||
| 30 | |||
| 31 | static inline void rwsem_clear_owner(struct rw_semaphore *sem) | ||
| 32 | { | ||
| 33 | } | ||
| 34 | #endif | ||
| 35 | |||
| 15 | /* | 36 | /* |
| 16 | * lock for reading | 37 | * lock for reading |
| 17 | */ | 38 | */ |
| @@ -48,6 +69,7 @@ void __sched down_write(struct rw_semaphore *sem) | |||
| 48 | rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); | 69 | rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_); |
| 49 | 70 | ||
| 50 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | 71 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); |
| 72 | rwsem_set_owner(sem); | ||
| 51 | } | 73 | } |
| 52 | 74 | ||
| 53 | EXPORT_SYMBOL(down_write); | 75 | EXPORT_SYMBOL(down_write); |
| @@ -59,8 +81,11 @@ int down_write_trylock(struct rw_semaphore *sem) | |||
| 59 | { | 81 | { |
| 60 | int ret = __down_write_trylock(sem); | 82 | int ret = __down_write_trylock(sem); |
| 61 | 83 | ||
| 62 | if (ret == 1) | 84 | if (ret == 1) { |
| 63 | rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_); | 85 | rwsem_acquire(&sem->dep_map, 0, 1, _RET_IP_); |
| 86 | rwsem_set_owner(sem); | ||
| 87 | } | ||
| 88 | |||
| 64 | return ret; | 89 | return ret; |
| 65 | } | 90 | } |
| 66 | 91 | ||
| @@ -85,6 +110,7 @@ void up_write(struct rw_semaphore *sem) | |||
| 85 | { | 110 | { |
| 86 | rwsem_release(&sem->dep_map, 1, _RET_IP_); | 111 | rwsem_release(&sem->dep_map, 1, _RET_IP_); |
| 87 | 112 | ||
| 113 | rwsem_clear_owner(sem); | ||
| 88 | __up_write(sem); | 114 | __up_write(sem); |
| 89 | } | 115 | } |
| 90 | 116 | ||
| @@ -99,6 +125,7 @@ void downgrade_write(struct rw_semaphore *sem) | |||
| 99 | * lockdep: a downgraded write will live on as a write | 125 | * lockdep: a downgraded write will live on as a write |
| 100 | * dependency. | 126 | * dependency. |
| 101 | */ | 127 | */ |
| 128 | rwsem_clear_owner(sem); | ||
| 102 | __downgrade_write(sem); | 129 | __downgrade_write(sem); |
| 103 | } | 130 | } |
| 104 | 131 | ||
| @@ -122,6 +149,7 @@ void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) | |||
| 122 | rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); | 149 | rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); |
| 123 | 150 | ||
| 124 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | 151 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); |
| 152 | rwsem_set_owner(sem); | ||
| 125 | } | 153 | } |
| 126 | 154 | ||
| 127 | EXPORT_SYMBOL(_down_write_nest_lock); | 155 | EXPORT_SYMBOL(_down_write_nest_lock); |
| @@ -141,6 +169,7 @@ void down_write_nested(struct rw_semaphore *sem, int subclass) | |||
| 141 | rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_); | 169 | rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_); |
| 142 | 170 | ||
| 143 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | 171 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); |
| 172 | rwsem_set_owner(sem); | ||
| 144 | } | 173 | } |
| 145 | 174 | ||
| 146 | EXPORT_SYMBOL(down_write_nested); | 175 | EXPORT_SYMBOL(down_write_nested); |
