提交 53ecfba2 编写于 作者: P Paul E. McKenney

rcu: only one evaluation of arg in rcu_dereference_check() unless sparse

The current version of the __rcu_access_pointer(), __rcu_dereference_check(),
and __rcu_dereference_protected() macros evaluate their "p" argument
three times, not counting typeof()s.  This is bad news if that argument
contains a side effect.  This commit therefore evaluates this argument
only once in normal kernel builds.  However, the straightforward approach
defeats sparse's RCU-pointer checking, so when __CHECKER__ is defined,
the additional pair of evaluations of the "p" argument are performed in
order to permit sparse to detect misuse of RCU-protected pointers.
Signed-off-by: NPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Arnd Bergmann <arnd@arndb.de>
上级 829f8ed2
...@@ -310,24 +310,32 @@ extern int rcu_my_thread_group_empty(void); ...@@ -310,24 +310,32 @@ extern int rcu_my_thread_group_empty(void);
* (e.g., __rcu_bh, * __rcu_sched, and __srcu), should this make sense in * (e.g., __rcu_bh, * __rcu_sched, and __srcu), should this make sense in
* the future. * the future.
*/ */
#ifdef __CHECKER__
#define rcu_dereference_sparse(p, space) \
((void)(((typeof(*p) space *)p) == p))
#else /* #ifdef __CHECKER__ */
#define rcu_dereference_sparse(p, space)
#endif /* #else #ifdef __CHECKER__ */
#define __rcu_access_pointer(p, space) \ #define __rcu_access_pointer(p, space) \
({ \ ({ \
typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \ typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
(void) (((typeof (*p) space *)p) == p); \ rcu_dereference_sparse(p, space); \
((typeof(*p) __force __kernel *)(_________p1)); \ ((typeof(*p) __force __kernel *)(_________p1)); \
}) })
#define __rcu_dereference_check(p, c, space) \ #define __rcu_dereference_check(p, c, space) \
({ \ ({ \
typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \ typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
rcu_lockdep_assert(c); \ rcu_lockdep_assert(c); \
(void) (((typeof (*p) space *)p) == p); \ rcu_dereference_sparse(p, space); \
smp_read_barrier_depends(); \ smp_read_barrier_depends(); \
((typeof(*p) __force __kernel *)(_________p1)); \ ((typeof(*p) __force __kernel *)(_________p1)); \
}) })
#define __rcu_dereference_protected(p, c, space) \ #define __rcu_dereference_protected(p, c, space) \
({ \ ({ \
rcu_lockdep_assert(c); \ rcu_lockdep_assert(c); \
(void) (((typeof (*p) space *)p) == p); \ rcu_dereference_sparse(p, space); \
((typeof(*p) __force __kernel *)(p)); \ ((typeof(*p) __force __kernel *)(p)); \
}) })
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册