diff options
Diffstat (limited to 'kernel/locking')
| -rw-r--r-- | kernel/locking/rwsem-spinlock.c | 7 | ||||
| -rw-r--r-- | kernel/locking/rwsem-xadd.c | 7 |
2 files changed, 14 insertions, 0 deletions
diff --git a/kernel/locking/rwsem-spinlock.c b/kernel/locking/rwsem-spinlock.c index 2555ae15ec14..3a5048572065 100644 --- a/kernel/locking/rwsem-spinlock.c +++ b/kernel/locking/rwsem-spinlock.c | |||
| @@ -85,6 +85,13 @@ __rwsem_do_wake(struct rw_semaphore *sem, int wakewrite) | |||
| 85 | 85 | ||
| 86 | list_del(&waiter->list); | 86 | list_del(&waiter->list); |
| 87 | tsk = waiter->task; | 87 | tsk = waiter->task; |
| 88 | /* | ||
| 89 | * Make sure we do not wakeup the next reader before | ||
| 90 | * setting the nil condition to grant the next reader; | ||
| 91 | * otherwise we could miss the wakeup on the other | ||
| 92 | * side and end up sleeping again. See the pairing | ||
| 93 | * in rwsem_down_read_failed(). | ||
| 94 | */ | ||
| 88 | smp_mb(); | 95 | smp_mb(); |
| 89 | waiter->task = NULL; | 96 | waiter->task = NULL; |
| 90 | wake_up_process(tsk); | 97 | wake_up_process(tsk); |
diff --git a/kernel/locking/rwsem-xadd.c b/kernel/locking/rwsem-xadd.c index 2f7cc4076f50..82aba467564a 100644 --- a/kernel/locking/rwsem-xadd.c +++ b/kernel/locking/rwsem-xadd.c | |||
| @@ -186,6 +186,13 @@ __rwsem_do_wake(struct rw_semaphore *sem, enum rwsem_wake_type wake_type) | |||
| 186 | waiter = list_entry(next, struct rwsem_waiter, list); | 186 | waiter = list_entry(next, struct rwsem_waiter, list); |
| 187 | next = waiter->list.next; | 187 | next = waiter->list.next; |
| 188 | tsk = waiter->task; | 188 | tsk = waiter->task; |
| 189 | /* | ||
| 190 | * Make sure we do not wakeup the next reader before | ||
| 191 | * setting the nil condition to grant the next reader; | ||
| 192 | * otherwise we could miss the wakeup on the other | ||
| 193 | * side and end up sleeping again. See the pairing | ||
| 194 | * in rwsem_down_read_failed(). | ||
| 195 | */ | ||
| 189 | smp_mb(); | 196 | smp_mb(); |
| 190 | waiter->task = NULL; | 197 | waiter->task = NULL; |
| 191 | wake_up_process(tsk); | 198 | wake_up_process(tsk); |
