Skip to content
  • Tejun Heo's avatar
    percpu-ref: fix DEAD flag contamination of percpu pointer · 4aab3b5b
    Tejun Heo authored
    While decoupling ATOMIC and DEAD flags, f47ad457
    
     ("percpu_ref:
    decouple switching to percpu mode and reinit") updated
    __ref_is_percpu() so that it only tests ATOMIC flag to determine
    whether the ref is in percpu mode or not; however, while DEAD implies
    ATOMIC, the two flags are set separately during percpu_ref_kill() and
    if __ref_is_percpu() races percpu_ref_kill(), it may see DEAD w/o
    ATOMIC.  Because __ref_is_percpu() returns @ref->percpu_count_ptr
    value verbatim as the percpu pointer after testing ATOMIC, the pointer
    may now be contaminated with the DEAD flag.
    
    This can be fixed by clearing the flag bits before returning the
    pointer which was the fix proposed by Shaohua; however, as DEAD
    implies ATOMIC, we can just test for both flags at once and avoid the
    explicit masking.
    
    Update __ref_is_percpu() so that it tests that both ATOMIC and DEAD
    are clear before returning @ref->percpu_count_ptr as the percpu
    pointer.
    
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-and-Reviewed-by: default avatarShaohua Li <shli@kernel.org>
    Link: http://lkml.kernel.org/r/995deb699f5b873c45d667df4add3b06f73c2c25.1416638887.git.shli@kernel.org
    Fixes: f47ad457 ("percpu_ref: decouple switching to percpu mode and reinit")
    4aab3b5b