diff options
Diffstat (limited to 'lib/rwsem.c')
-rw-r--r-- | lib/rwsem.c | 22 |
1 files changed, 2 insertions, 20 deletions
diff --git a/lib/rwsem.c b/lib/rwsem.c index fb658af1c12c..66f307e90761 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c | |||
@@ -182,7 +182,6 @@ try_again_write: | |||
182 | */ | 182 | */ |
183 | struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | 183 | struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) |
184 | { | 184 | { |
185 | enum rwsem_waiter_type type = RWSEM_WAITING_FOR_READ; | ||
186 | signed long adjustment = -RWSEM_ACTIVE_READ_BIAS; | 185 | signed long adjustment = -RWSEM_ACTIVE_READ_BIAS; |
187 | struct rwsem_waiter waiter; | 186 | struct rwsem_waiter waiter; |
188 | struct task_struct *tsk = current; | 187 | struct task_struct *tsk = current; |
@@ -190,7 +189,7 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
190 | 189 | ||
191 | /* set up my own style of waitqueue */ | 190 | /* set up my own style of waitqueue */ |
192 | waiter.task = tsk; | 191 | waiter.task = tsk; |
193 | waiter.type = type; | 192 | waiter.type = RWSEM_WAITING_FOR_READ; |
194 | get_task_struct(tsk); | 193 | get_task_struct(tsk); |
195 | 194 | ||
196 | raw_spin_lock_irq(&sem->wait_lock); | 195 | raw_spin_lock_irq(&sem->wait_lock); |
@@ -201,17 +200,9 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
201 | /* we're now waiting on the lock, but no longer actively locking */ | 200 | /* we're now waiting on the lock, but no longer actively locking */ |
202 | count = rwsem_atomic_update(adjustment, sem); | 201 | count = rwsem_atomic_update(adjustment, sem); |
203 | 202 | ||
204 | /* If there are no active locks, wake the front queued process(es) up. | 203 | /* If there are no active locks, wake the front queued process(es). */ |
205 | * | ||
206 | * Alternatively, if we're called from a failed down_write(), there | ||
207 | * were already threads queued before us and there are no active | ||
208 | * writers, the lock must be read owned; so we try to wake any read | ||
209 | * locks that were queued ahead of us. */ | ||
210 | if (count == RWSEM_WAITING_BIAS) | 204 | if (count == RWSEM_WAITING_BIAS) |
211 | sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE); | 205 | sem = __rwsem_do_wake(sem, RWSEM_WAKE_NO_ACTIVE); |
212 | else if (count > RWSEM_WAITING_BIAS && | ||
213 | adjustment == -RWSEM_ACTIVE_WRITE_BIAS) | ||
214 | sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED); | ||
215 | 206 | ||
216 | raw_spin_unlock_irq(&sem->wait_lock); | 207 | raw_spin_unlock_irq(&sem->wait_lock); |
217 | 208 | ||
@@ -220,15 +211,6 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem) | |||
220 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); | 211 | set_task_state(tsk, TASK_UNINTERRUPTIBLE); |
221 | if (!waiter.task) | 212 | if (!waiter.task) |
222 | break; | 213 | break; |
223 | |||
224 | raw_spin_lock_irq(&sem->wait_lock); | ||
225 | /* Try to get the writer sem, may steal from the head writer: */ | ||
226 | if (type == RWSEM_WAITING_FOR_WRITE) | ||
227 | if (try_get_writer_sem(sem, &waiter)) { | ||
228 | raw_spin_unlock_irq(&sem->wait_lock); | ||
229 | return sem; | ||
230 | } | ||
231 | raw_spin_unlock_irq(&sem->wait_lock); | ||
232 | schedule(); | 214 | schedule(); |
233 | } | 215 | } |
234 | 216 | ||