diff options
Diffstat (limited to 'lib/rwsem.c')
-rw-r--r-- | lib/rwsem.c | 26 |
1 files changed, 6 insertions, 20 deletions
diff --git a/lib/rwsem.c b/lib/rwsem.c index 2360bf204098..64c2dc007be2 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -142,25 +142,6 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wake_type) | |||
142 | return sem; | 142 | return sem; |
143 | } | 143 | } |
144 | 144 | ||
145 | /* Try to get write sem, caller holds sem->wait_lock: */ | ||
146 | static int try_get_writer_sem(struct rw_semaphore *sem) | ||
147 | { | ||
148 | long oldcount, adjustment; | ||
149 | |||
150 | adjustment = RWSEM_ACTIVE_WRITE_BIAS; | ||
151 | if (list_is_singular(&sem->wait_list)) | ||
152 | adjustment -= RWSEM_WAITING_BIAS; | ||
153 | |||
154 | try_again_write: | ||
155 | oldcount = rwsem_atomic_update(adjustment, sem) - adjustment; | ||
156 | if (!(oldcount & RWSEM_ACTIVE_MASK)) | ||
157 | return 1; | ||
158 | /* some one grabbed the sem already */ | ||
159 | if (rwsem_atomic_update(-adjustment, sem) & RWSEM_ACTIVE_MASK) | ||
160 | return 0; | ||
161 | goto try_again_write; | ||
162 | } | ||
163 | |||
164 | /* | 145 | /* |
165 | * wait for the read lock to be granted | 146 | * wait for the read lock to be granted |
166 | */ | 147 | */ |
@@ -236,7 +217,12 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem) | |||
236 | while (true) { | 217 | while (true) { |
237 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 218 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
238 | 219 | ||
239 | if (try_get_writer_sem(sem)) | 220 | /* Try acquiring the write lock. */ |
221 | count = RWSEM_ACTIVE_WRITE_BIAS; | ||
222 | if (!list_is_singular(&sem->wait_list)) | ||
223 | count += RWSEM_WAITING_BIAS; | ||
224 | if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) == | ||
225 | RWSEM_WAITING_BIAS) | ||
240 | break; | 226 | break; |
241 | 227 | ||
242 | raw_spin_unlock_irq(&sem->wait_lock); | 228 | raw_spin_unlock_irq(&sem->wait_lock); |