lkml.org 
[lkml]   [2010]   [Sep]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH tip/core/rcu 5/8] rcu: only one evaluation of arg in rcu_dereference_check() unless sparse
    Date
    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: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
    Cc: Arnd Bergmann <arnd@arndb.de>
    ---
    include/linux/rcupdate.h | 14 +++++++++++---
    1 files changed, 11 insertions(+), 3 deletions(-)

    diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
    index 89414d6..03cda7b 100644
    --- a/include/linux/rcupdate.h
    +++ b/include/linux/rcupdate.h
    @@ -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
    * 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) \
    ({ \
    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)); \
    })
    #define __rcu_dereference_check(p, c, space) \
    ({ \
    typeof(*p) *_________p1 = (typeof(*p)*__force )ACCESS_ONCE(p); \
    rcu_lockdep_assert(c); \
    - (void) (((typeof (*p) space *)p) == p); \
    + rcu_dereference_sparse(p, space); \
    smp_read_barrier_depends(); \
    ((typeof(*p) __force __kernel *)(_________p1)); \
    })
    #define __rcu_dereference_protected(p, c, space) \
    ({ \
    rcu_lockdep_assert(c); \
    - (void) (((typeof (*p) space *)p) == p); \
    + rcu_dereference_sparse(p, space); \
    ((typeof(*p) __force __kernel *)(p)); \
    })

    --
    1.7.0.6


    \
     
     \ /
      Last update: 2010-09-23 02:55    [W:0.028 / U:0.112 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site