• Boqun Feng's avatar
    locking/lockdep: Avoid recursion in lockdep_count_{for,back}ward_deps() · 25016bd7
    Boqun Feng authored
    Qian Cai reported a bug when PROVE_RCU_LIST=y, and read on /proc/lockdep
    triggered a warning:
    
      [ ] DEBUG_LOCKS_WARN_ON(current->hardirqs_enabled)
      ...
      [ ] Call Trace:
      [ ]  lock_is_held_type+0x5d/0x150
      [ ]  ? rcu_lockdep_current_cpu_online+0x64/0x80
      [ ]  rcu_read_lock_any_held+0xac/0x100
      [ ]  ? rcu_read_lock_held+0xc0/0xc0
      [ ]  ? __slab_free+0x421/0x540
      [ ]  ? kasan_kmalloc+0x9/0x10
      [ ]  ? __kmalloc_node+0x1d7/0x320
      [ ]  ? kvmalloc_node+0x6f/0x80
      [ ]  __bfs+0x28a/0x3c0
      [ ]  ? class_equal+0x30/0x30
      [ ]  lockdep_count_forward_deps+0x11a/0x1a0
    
    The warning got triggered because lockdep_count_forward_deps() call
    __bfs() without current->lockdep_recursion being set, as a result
    a lockdep internal function (__bfs()) is checked by lockdep, which is
    unexpected, and the inconsistency between the irq-off state and the
    state traced by lockdep caused the warning.
    
    Apart from this warning, lockdep internal functions like __bfs() should
    always be protected by current->lockdep_recursion to avoid potential
    deadlocks and data inconsistency, therefore add the
    current->lockdep_recursion on-and-off section to protect __bfs() in both
    lockdep_count_forward_deps() and lockdep_count_backward_deps()
    Reported-by: default avatarQian Cai <cai@lca.pw>
    Signed-off-by: default avatarBoqun Feng <boqun.feng@gmail.com>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20200312151258.128036-1-boqun.feng@gmail.com
    25016bd7
lockdep.c 139 KB