summaryrefslogtreecommitdiff
path: root/lib/locking-selftest.c
diff options
context:
space:
mode:
authorBoqun Feng <boqun.feng@gmail.com>2020-12-10 11:15:00 +0100
committerPeter Zijlstra <peterz@infradead.org>2021-01-14 11:20:17 +0100
commit5f2962401c6e195222f320d12b3a55377b2d4653 (patch)
tree6cb7bcb9ae9e84185c866db87529c4be3348a38e /lib/locking-selftest.c
parent175b1a60e8805617d74aefe17ce0d3a32eceb55c (diff)
locking/lockdep: Exclude local_lock_t from IRQ inversions
The purpose of local_lock_t is to abstract: preempt_disable() / local_bh_disable() / local_irq_disable(). These are the traditional means of gaining access to per-cpu data, but are fundamentally non-preemptible. local_lock_t provides a per-cpu lock, that on !PREEMPT_RT reduces to no-ops, just like regular spinlocks do on UP. This gives rise to: CPU0 CPU1 local_lock(B) spin_lock_irq(A) <IRQ> spin_lock(A) local_lock(B) Where lockdep then figures things will lock up; which would be true if B were any other kind of lock. However this is a false positive, no such deadlock actually exists. For !RT the above local_lock(B) is preempt_disable(), and there's obviously no deadlock; alternatively, CPU0's B != CPU1's B. For RT the argument is that since local_lock() nests inside spin_lock(), it cannot be used in hardirq context, and therefore CPU0 cannot in fact happen. Even though B is a real lock, it is a preemptible lock and any threaded-irq would simply schedule out and let the preempted task (which holds B) continue such that the task on CPU1 can make progress, after which the threaded-irq resumes and can finish. This means that we can never form an IRQ inversion on a local_lock dependency, so terminate the graph walk when looking for IRQ inversions when we encounter one. One consequence is that (for LOCKDEP_SMALL) when we look for redundant dependencies, A -> B is not redundant in the presence of A -> L -> B. Signed-off-by: Boqun Feng <boqun.feng@gmail.com> [peterz: Changelog] Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Diffstat (limited to 'lib/locking-selftest.c')
0 files changed, 0 insertions, 0 deletions