aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2014-01-12 18:31:24 -0500
committerIngo Molnar <mingo@kernel.org>2014-01-13 05:45:19 -0500
commit99b60ce69734dfeda58c6184a326b9475ce1dba3 (patch)
treef9e4c7f179859f3e20bdd5e7c501196f0a07eddf
parenta52b89ebb6d4499be38780db8d176c5d3a6fbc17 (diff)
futexes: Document multiprocessor ordering guarantees
That's essential, if you want to hack on futexes. Reviewed-by: Darren Hart <dvhart@linux.intel.com> Reviewed-by: Peter Zijlstra <peterz@infradead.org> Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Jeff Mahoney <jeffm@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Randy Dunlap <rdunlap@infradead.org> Cc: Scott Norton <scott.norton@hp.com> Cc: Tom Vaden <tom.vaden@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Waiman Long <Waiman.Long@hp.com> Cc: Jason Low <jason.low2@hp.com> Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/1389569486-25487-4-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--kernel/futex.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 577481d5c59d..fcc6850483fb 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -69,6 +69,63 @@
69 69
70#include "locking/rtmutex_common.h" 70#include "locking/rtmutex_common.h"
71 71
72/*
73 * Basic futex operation and ordering guarantees:
74 *
75 * The waiter reads the futex value in user space and calls
76 * futex_wait(). This function computes the hash bucket and acquires
77 * the hash bucket lock. After that it reads the futex user space value
78 * again and verifies that the data has not changed. If it has not
79 * changed it enqueues itself into the hash bucket, releases the hash
80 * bucket lock and schedules.
81 *
82 * The waker side modifies the user space value of the futex and calls
83 * futex_wake(). This functions computes the hash bucket and acquires
84 * the hash bucket lock. Then it looks for waiters on that futex in the
85 * hash bucket and wakes them.
86 *
87 * Note that the spin_lock serializes waiters and wakers, so that the
88 * following scenario is avoided:
89 *
90 * CPU 0 CPU 1
91 * val = *futex;
92 * sys_futex(WAIT, futex, val);
93 * futex_wait(futex, val);
94 * uval = *futex;
95 * *futex = newval;
96 * sys_futex(WAKE, futex);
97 * futex_wake(futex);
98 * if (queue_empty())
99 * return;
100 * if (uval == val)
101 * lock(hash_bucket(futex));
102 * queue();
103 * unlock(hash_bucket(futex));
104 * schedule();
105 *
106 * This would cause the waiter on CPU 0 to wait forever because it
107 * missed the transition of the user space value from val to newval
108 * and the waker did not find the waiter in the hash bucket queue.
109 * The spinlock serializes that:
110 *
111 * CPU 0 CPU 1
112 * val = *futex;
113 * sys_futex(WAIT, futex, val);
114 * futex_wait(futex, val);
115 * lock(hash_bucket(futex));
116 * uval = *futex;
117 * *futex = newval;
118 * sys_futex(WAKE, futex);
119 * futex_wake(futex);
120 * lock(hash_bucket(futex));
121 * if (uval == val)
122 * queue();
123 * unlock(hash_bucket(futex));
124 * schedule(); if (!queue_empty())
125 * wake_waiters(futex);
126 * unlock(hash_bucket(futex));
127 */
128
72int __read_mostly futex_cmpxchg_enabled; 129int __read_mostly futex_cmpxchg_enabled;
73 130
74/* 131/*