diff options
| author | Peter Zijlstra <peterz@infradead.org> | 2016-05-24 07:17:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-06-14 05:55:14 -0400 |
| commit | 33ac279677dcc2441cb93d8cb9cf7a74df62814d (patch) | |
| tree | bcf918587b2425d1294b780b31ab67761e068e26 /ipc/sem.c | |
| parent | 1f03e8d2919270bd6ef64f39a45ce8df8a9f012a (diff) | |
locking/barriers: Introduce smp_acquire__after_ctrl_dep()
Introduce smp_acquire__after_ctrl_dep(), this construct is not
uncommon, but the lack of this barrier is.
Use it to better express smp_rmb() uses in WRITE_ONCE(), the IPC
semaphore code and the qspinlock code.
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'ipc/sem.c')
| -rw-r--r-- | ipc/sem.c | 14 |
1 files changed, 2 insertions, 12 deletions
| @@ -260,16 +260,6 @@ static void sem_rcu_free(struct rcu_head *head) | |||
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | /* | 262 | /* |
| 263 | * spin_unlock_wait() and !spin_is_locked() are not memory barriers, they | ||
| 264 | * are only control barriers. | ||
| 265 | * The code must pair with spin_unlock(&sem->lock) or | ||
| 266 | * spin_unlock(&sem_perm.lock), thus just the control barrier is insufficient. | ||
| 267 | * | ||
| 268 | * smp_rmb() is sufficient, as writes cannot pass the control barrier. | ||
| 269 | */ | ||
| 270 | #define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb() | ||
| 271 | |||
| 272 | /* | ||
| 273 | * Wait until all currently ongoing simple ops have completed. | 263 | * Wait until all currently ongoing simple ops have completed. |
| 274 | * Caller must own sem_perm.lock. | 264 | * Caller must own sem_perm.lock. |
| 275 | * New simple ops cannot start, because simple ops first check | 265 | * New simple ops cannot start, because simple ops first check |
| @@ -292,7 +282,7 @@ static void sem_wait_array(struct sem_array *sma) | |||
| 292 | sem = sma->sem_base + i; | 282 | sem = sma->sem_base + i; |
| 293 | spin_unlock_wait(&sem->lock); | 283 | spin_unlock_wait(&sem->lock); |
| 294 | } | 284 | } |
| 295 | ipc_smp_acquire__after_spin_is_unlocked(); | 285 | smp_acquire__after_ctrl_dep(); |
| 296 | } | 286 | } |
| 297 | 287 | ||
| 298 | /* | 288 | /* |
| @@ -350,7 +340,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, | |||
| 350 | * complex_count++; | 340 | * complex_count++; |
| 351 | * spin_unlock(sem_perm.lock); | 341 | * spin_unlock(sem_perm.lock); |
| 352 | */ | 342 | */ |
| 353 | ipc_smp_acquire__after_spin_is_unlocked(); | 343 | smp_acquire__after_ctrl_dep(); |
| 354 | 344 | ||
| 355 | /* | 345 | /* |
| 356 | * Now repeat the test of complex_count: | 346 | * Now repeat the test of complex_count: |
