projects
/
firefly-linux-kernel-4.4.55.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
tracing: Update the TRACE_EVENT fields available in the sample code
[firefly-linux-kernel-4.4.55.git]
/
ipc
/
sem.c
diff --git
a/ipc/sem.c
b/ipc/sem.c
index 53c3310f41c6867fd4b5f3f0493a150184b8c617..6115146563f94e5bfab0973be730b3388fb3fc59 100644
(file)
--- a/
ipc/sem.c
+++ b/
ipc/sem.c
@@
-326,10
+326,17
@@
static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
/* Then check that the global lock is free */
if (!spin_is_locked(&sma->sem_perm.lock)) {
/* Then check that the global lock is free */
if (!spin_is_locked(&sma->sem_perm.lock)) {
- /* spin_is_locked() is not a memory barrier */
- smp_mb();
+ /*
+ * The ipc object lock check must be visible on all
+ * cores before rechecking the complex count. Otherwise
+ * we can race with another thread that does:
+ * complex_count++;
+ * spin_unlock(sem_perm.lock);
+ */
+ smp_rmb();
- /* Now repeat the test of complex_count:
+ /*
+ * Now repeat the test of complex_count:
* It can't change anymore until we drop sem->lock.
* Thus: if is now 0, then it will stay 0.
*/
* It can't change anymore until we drop sem->lock.
* Thus: if is now 0, then it will stay 0.
*/