On Wed, Sep 16, 2020 at 11:45:27AM -0700, Jakub Kicinski wrote: > When CONFIG_LOCKDEP is not set, lock_is_held() and lockdep_is_held() > are not declared or defined. This forces all callers to use ifdefs > around these checks. > > Recent RCU changes added a lot of lockdep_is_held() calls inside > rcu_dereference_protected(). rcu_dereference_protected() hides > its argument on !LOCKDEP builds, but this may lead to unused variable > warnings. > > Provide forward declarations of lock_is_held() and lockdep_is_held() > but never define them. This way callers can keep them visible to > the compiler on !LOCKDEP builds and instead depend on dead code > elimination to remove the references before the linker barfs. > > We need lock_is_held() for RCU. > > Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> > -- > CC: peterz@xxxxxxxxxxxxx > CC: mingo@xxxxxxxxxx > CC: will@xxxxxxxxxx > --- > include/linux/lockdep.h | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h > index 6a584b3e5c74..6b5bbc536bf6 100644 > --- a/include/linux/lockdep.h > +++ b/include/linux/lockdep.h > @@ -371,6 +371,12 @@ static inline void lockdep_unregister_key(struct lock_class_key *key) > > #define lockdep_depth(tsk) (0) > > +/* > + * Dummy forward declarations, allow users to write less ifdef-y code > + * and depend on dead code elimination. > + */ > +int lock_is_held(const void *); extern int lock_is_held(const struct lockdep_map *); > +int lockdep_is_held(const void *); extern I suppose we can't pull the lockdep_is_held() definition out from under CONFIG_LOCKDEP because it does the ->dep_map dereference and many types will simply not have that member. > #define lockdep_is_held_type(l, r) (1) > > #define lockdep_assert_held(l) do { (void)(l); } while (0)