summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Lelli <juri.lelli@redhat.com>2018-02-13 13:55:19 -0500
committerIngo Molnar <mingo@kernel.org>2018-02-14 06:01:22 -0500
commita1ea544fe0911492b9f8d101bcbf46cc8c47fbc5 (patch)
tree6ec7c592250f11c9f0118982ce141d1aeae30fd0
parente5684bbfc3f03480d6ba2150f133630fb510d3eb (diff)
Documentation/locking/lockdep: Add section about available annotations
Add section about annotations that can be used to perform additional runtime checking of locking correctness: assert that certain locks are held and prevent accidental unlocking. Signed-off-by: Juri Lelli <juri.lelli@redhat.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-doc@vger.kernel.org Link: http://lkml.kernel.org/r/20180213185519.18186-3-juri.lelli@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--Documentation/locking/lockdep-design.txt47
1 files changed, 47 insertions, 0 deletions
diff --git a/Documentation/locking/lockdep-design.txt b/Documentation/locking/lockdep-design.txt
index e341c2f34e68..49f58a07ee7b 100644
--- a/Documentation/locking/lockdep-design.txt
+++ b/Documentation/locking/lockdep-design.txt
@@ -169,6 +169,53 @@ Note: When changing code to use the _nested() primitives, be careful and
169check really thoroughly that the hierarchy is correctly mapped; otherwise 169check really thoroughly that the hierarchy is correctly mapped; otherwise
170you can get false positives or false negatives. 170you can get false positives or false negatives.
171 171
172Annotations
173-----------
174
175Two constructs can be used to annotate and check where and if certain locks
176must be held: lockdep_assert_held*(&lock) and lockdep_*pin_lock(&lock).
177
178As the name suggests, lockdep_assert_held* family of macros assert that a
179particular lock is held at a certain time (and generate a WARN() otherwise).
180This annotation is largely used all over the kernel, e.g. kernel/sched/
181core.c
182
183 void update_rq_clock(struct rq *rq)
184 {
185 s64 delta;
186
187 lockdep_assert_held(&rq->lock);
188 [...]
189 }
190
191where holding rq->lock is required to safely update a rq's clock.
192
193The other family of macros is lockdep_*pin_lock(), which is admittedly only
194used for rq->lock ATM. Despite their limited adoption these annotations
195generate a WARN() if the lock of interest is "accidentally" unlocked. This turns
196out to be especially helpful to debug code with callbacks, where an upper
197layer assumes a lock remains taken, but a lower layer thinks it can maybe drop
198and reacquire the lock ("unwittingly" introducing races). lockdep_pin_lock()
199returns a 'struct pin_cookie' that is then used by lockdep_unpin_lock() to check
200that nobody tampered with the lock, e.g. kernel/sched/sched.h
201
202 static inline void rq_pin_lock(struct rq *rq, struct rq_flags *rf)
203 {
204 rf->cookie = lockdep_pin_lock(&rq->lock);
205 [...]
206 }
207
208 static inline void rq_unpin_lock(struct rq *rq, struct rq_flags *rf)
209 {
210 [...]
211 lockdep_unpin_lock(&rq->lock, rf->cookie);
212 }
213
214While comments about locking requirements might provide useful information,
215the runtime checks performed by annotations are invaluable when debugging
216locking problems and they carry the same level of details when inspecting
217code. Always prefer annotations when in doubt!
218
172Proof of 100% correctness: 219Proof of 100% correctness:
173-------------------------- 220--------------------------
174 221