@ -536,6 +536,11 @@ static inline int rcu_read_lock_sched_held(void)
# endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
/* Deprecate rcu_lockdep_assert(): Use RCU_LOCKDEP_WARN() instead. */
static inline void __attribute ( ( deprecated ) ) deprecate_rcu_lockdep_assert ( void )
{
}
# ifdef CONFIG_PROVE_RCU
/**
@ -546,17 +551,32 @@ static inline int rcu_read_lock_sched_held(void)
# define rcu_lockdep_assert(c, s) \
do { \
static bool __section ( . data . unlikely ) __warned ; \
deprecate_rcu_lockdep_assert ( ) ; \
if ( debug_lockdep_rcu_enabled ( ) & & ! __warned & & ! ( c ) ) { \
__warned = true ; \
lockdep_rcu_suspicious ( __FILE__ , __LINE__ , s ) ; \
} \
} while ( 0 )
/**
* RCU_LOCKDEP_WARN - emit lockdep splat if specified condition is met
* @ c : condition to check
* @ s : informative message
*/
# define RCU_LOCKDEP_WARN(c, s) \
do { \
static bool __section ( . data . unlikely ) __warned ; \
if ( debug_lockdep_rcu_enabled ( ) & & ! __warned & & ( c ) ) { \
__warned = true ; \
lockdep_rcu_suspicious ( __FILE__ , __LINE__ , s ) ; \
} \
} while ( 0 )
# if defined(CONFIG_PROVE_RCU) && !defined(CONFIG_PREEMPT_RCU)
static inline void rcu_preempt_sleep_check ( void )
{
rcu_lockdep_assert ( ! lock_is_held ( & rcu_lock_map ) ,
" Illegal context switch in RCU read-side critical section " ) ;
RCU_LOCKDEP_WARN( lock_is_held ( & rcu_lock_map ) ,
" Illegal context switch in RCU read-side critical section " ) ;
}
# else /* #ifdef CONFIG_PROVE_RCU */
static inline void rcu_preempt_sleep_check ( void )
@ -567,15 +587,16 @@ static inline void rcu_preempt_sleep_check(void)
# define rcu_sleep_check() \
do { \
rcu_preempt_sleep_check ( ) ; \
rcu_lockdep_assert( ! lock_is_held ( & rcu_bh_lock_map ) , \
" Illegal context switch in RCU-bh read-side critical section " ) ; \
rcu_lockdep_assert( ! lock_is_held ( & rcu_sched_lock_map ) , \
" Illegal context switch in RCU-sched read-side critical section " ) ; \
RCU_LOCKDEP_WARN( lock_is_held ( & rcu_bh_lock_map ) , \
" Illegal context switch in RCU-bh read-side critical section " ) ; \
RCU_LOCKDEP_WARN( lock_is_held ( & rcu_sched_lock_map ) , \
" Illegal context switch in RCU-sched read-side critical section " ) ; \
} while ( 0 )
# else /* #ifdef CONFIG_PROVE_RCU */
# define rcu_lockdep_assert(c, s) do { } while (0)
# define rcu_lockdep_assert(c, s) deprecate_rcu_lockdep_assert()
# define RCU_LOCKDEP_WARN(c, s) do { } while (0)
# define rcu_sleep_check() do { } while (0)
# endif /* #else #ifdef CONFIG_PROVE_RCU */
@ -606,13 +627,13 @@ static inline void rcu_preempt_sleep_check(void)
( { \
/* Dependency order vs. p above. */ \
typeof ( * p ) * ________p1 = ( typeof ( * p ) * __force ) lockless_dereference ( p ) ; \
rcu_lockdep_assert( c , " suspicious rcu_dereference_check() usage " ) ; \
RCU_LOCKDEP_WARN( ! ( c ) , " suspicious rcu_dereference_check() usage " ) ; \
rcu_dereference_sparse ( p , space ) ; \
( ( typeof ( * p ) __force __kernel * ) ( ________p1 ) ) ; \
} )
# define __rcu_dereference_protected(p, c, space) \
( { \
rcu_lockdep_assert( c , " suspicious rcu_dereference_protected() usage " ) ; \
RCU_LOCKDEP_WARN( ! ( c ) , " suspicious rcu_dereference_protected() usage " ) ; \
rcu_dereference_sparse ( p , space ) ; \
( ( typeof ( * p ) __force __kernel * ) ( p ) ) ; \
} )
@ -836,8 +857,8 @@ static inline void rcu_read_lock(void)
__rcu_read_lock ( ) ;
__acquire ( RCU ) ;
rcu_lock_acquire ( & rcu_lock_map ) ;
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_lock() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_lock() used illegally while idle " ) ;
}
/*
@ -887,8 +908,8 @@ static inline void rcu_read_lock(void)
*/
static inline void rcu_read_unlock ( void )
{
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_unlock() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_unlock() used illegally while idle " ) ;
__release ( RCU ) ;
__rcu_read_unlock ( ) ;
rcu_lock_release ( & rcu_lock_map ) ; /* Keep acq info for rls diags. */
@ -916,8 +937,8 @@ static inline void rcu_read_lock_bh(void)
local_bh_disable ( ) ;
__acquire ( RCU_BH ) ;
rcu_lock_acquire ( & rcu_bh_lock_map ) ;
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_lock_bh() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_lock_bh() used illegally while idle " ) ;
}
/*
@ -927,8 +948,8 @@ static inline void rcu_read_lock_bh(void)
*/
static inline void rcu_read_unlock_bh ( void )
{
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_unlock_bh() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_unlock_bh() used illegally while idle " ) ;
rcu_lock_release ( & rcu_bh_lock_map ) ;
__release ( RCU_BH ) ;
local_bh_enable ( ) ;
@ -952,8 +973,8 @@ static inline void rcu_read_lock_sched(void)
preempt_disable ( ) ;
__acquire ( RCU_SCHED ) ;
rcu_lock_acquire ( & rcu_sched_lock_map ) ;
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_lock_sched() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_lock_sched() used illegally while idle " ) ;
}
/* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
@ -970,8 +991,8 @@ static inline notrace void rcu_read_lock_sched_notrace(void)
*/
static inline void rcu_read_unlock_sched ( void )
{
rcu_lockdep_assert( rcu_is_watching ( ) ,
" rcu_read_unlock_sched() used illegally while idle " ) ;
RCU_LOCKDEP_WARN( ! rcu_is_watching ( ) ,
" rcu_read_unlock_sched() used illegally while idle " ) ;
rcu_lock_release ( & rcu_sched_lock_map ) ;
__release ( RCU_SCHED ) ;
preempt_enable ( ) ;