25 Sep, 2014

11 commits

  • Currently, a percpu_ref which is initialized with
    PERPCU_REF_INIT_ATOMIC or switched to atomic mode via
    switch_to_atomic() automatically reverts to percpu mode on the first
    percpu_ref_reinit(). This makes the atomic mode difficult to use for
    cases where a percpu_ref is used as a persistent on/off switch which
    may be cycled multiple times.

    This patch makes such atomic state sticky so that it survives through
    kill/reinit cycles. After this patch, atomic state is cleared only by
    an explicit percpu_ref_switch_to_percpu() call.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet
    Cc: Jens Axboe
    Cc: Christoph Hellwig
    Cc: Johannes Weiner

    Tejun Heo
     
  • With the recent addition of percpu_ref_reinit(), percpu_ref now can be
    used as a persistent switch which can be turned on and off repeatedly
    where turning off maps to killing the ref and waiting for it to drain;
    however, there currently isn't a way to initialize a percpu_ref in its
    off (killed and drained) state, which can be inconvenient for certain
    persistent switch use cases.

    Similarly, percpu_ref_switch_to_atomic/percpu() allow dynamic
    selection of operation mode; however, currently a newly initialized
    percpu_ref is always in percpu mode making it impossible to avoid the
    latency overhead of switching to atomic mode.

    This patch adds @flags to percpu_ref_init() and implements the
    following flags.

    * PERCPU_REF_INIT_ATOMIC : start ref in atomic mode
    * PERCPU_REF_INIT_DEAD : start ref killed and drained

    These flags should be able to serve the above two use cases.

    v2: target_core_tpg.c conversion was missing. Fixed.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet
    Cc: Jens Axboe
    Cc: Christoph Hellwig
    Cc: Johannes Weiner

    Tejun Heo
     
  • percpu_ref has treated the dropping of the base reference and
    switching to atomic mode as an integral operation; however, there's
    nothing inherent tying the two together.

    The use cases for percpu_ref have been expanding continuously. While
    the current init/kill/reinit/exit model can cover a lot, the coupling
    of kill/reinit with atomic/percpu mode switching is turning out to be
    too restrictive for use cases where many percpu_refs are created and
    destroyed back-to-back with only some of them reaching extended
    operation. The coupling also makes implementing always-atomic debug
    mode difficult.

    This patch separates out percpu mode switching into
    percpu_ref_switch_to_percpu() and reimplements percpu_ref_reinit() on
    top of it.

    * DEAD still requires ATOMIC. A dead ref can't be switched to percpu
    mode w/o going through reinit.

    v2: __percpu_ref_switch_to_percpu() was missing static. Fixed.
    Reported by Fengguang aka kbuild test robot.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet
    Cc: Jens Axboe
    Cc: Christoph Hellwig
    Cc: Johannes Weiner
    Cc: kbuild test robot

    Tejun Heo
     
  • percpu_ref has treated the dropping of the base reference and
    switching to atomic mode as an integral operation; however, there's
    nothing inherent tying the two together.

    The use cases for percpu_ref have been expanding continuously. While
    the current init/kill/reinit/exit model can cover a lot, the coupling
    of kill/reinit with atomic/percpu mode switching is turning out to be
    too restrictive for use cases where many percpu_refs are created and
    destroyed back-to-back with only some of them reaching extended
    operation. The coupling also makes implementing always-atomic debug
    mode difficult.

    This patch separates out atomic mode switching into
    percpu_ref_switch_to_atomic() and reimplements
    percpu_ref_kill_and_confirm() on top of it.

    * The handling of __PERCPU_REF_ATOMIC and __PERCPU_REF_DEAD is now
    differentiated. Among get/put operations, percpu_ref_tryget_live()
    is the only one which cares about DEAD.

    * percpu_ref_switch_to_atomic() can be called multiple times on the
    same ref. This means that multiple @confirm_switch may get queued
    up which we can't do reliably without extra memory area. This is
    handled by making the later invocation synchronously wait for the
    completion of the previous one. This isn't particularly desirable
    but such synchronous waits shouldn't happen in most cases.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet
    Cc: Jens Axboe
    Cc: Christoph Hellwig
    Cc: Johannes Weiner

    Tejun Heo
     
  • percpu_ref will be restructured so that percpu/atomic mode switching
    and reference killing are dedoupled. In preparation, add
    PCPU_REF_DEAD and PCPU_REF_ATOMIC_DEAD which is OR of ATOMIC and DEAD.
    For now, ATOMIC and DEAD are changed together and all PCPU_REF_ATOMIC
    uses are converted to PCPU_REF_ATOMIC_DEAD without causing any
    behavior changes.

    percpu_ref_init() now specifies an explicit alignment when allocating
    the percpu counters so that the pointer has enough unused low bits to
    accomodate the flags. Note that one flag was fine as min alignment
    for percpu memory is 2 bytes but two flags are already too many for
    the natural alignment of unsigned longs on archs like cris and m68k.

    v2: The original patch had BUILD_BUG_ON() which triggers if unsigned
    long's alignment isn't enough to accomodate the flags, which
    triggered on cris and m64k. percpu_ref_init() updated to specify
    the required alignment explicitly. Reported by Fengguang.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet
    Cc: kbuild test robot

    Tejun Heo
     
  • percpu_ref will be restructured so that percpu/atomic mode switching
    and reference killing are dedoupled. In preparation, do the following
    renames.

    * percpu_ref->confirm_kill -> percpu_ref->confirm_switch
    * __PERCPU_REF_DEAD -> __PERCPU_REF_ATOMIC
    * __percpu_ref_alive() -> __ref_is_percpu()

    This patch is pure rename and doesn't introduce any functional
    changes.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet

    Tejun Heo
     
  • percpu_ref uses pcpu_ prefix for internal stuff and percpu_ for
    externally visible ones. This is the same convention used in the
    percpu allocator implementation. It works fine there but percpu_ref
    doesn't have too much internal-only stuff and scattered usages of
    pcpu_ prefix are confusing than helpful.

    This patch replaces all pcpu_ prefixes with percpu_. This is pure
    rename and there's no functional change. Note that PCPU_REF_DEAD is
    renamed to __PERCPU_REF_DEAD to signify that the flag is internal.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet

    Tejun Heo
     
  • * Some comments became stale. Updated.
    * percpu_ref_tryget() unnecessarily initializes @ret. Removed.
    * A blank line removed from percpu_ref_kill_rcu().
    * Explicit function name in a WARN format string replaced with __func__.
    * WARN_ON() in percpu_ref_reinit() converted to WARN_ON_ONCE().

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet

    Tejun Heo
     
  • percpu_ref is gonna go through restructuring. Move
    percpu_ref_reinit() after percpu_ref_kill_and_confirm(). This will
    make later changes easier to follow and result in cleaner
    organization.

    Signed-off-by: Tejun Heo
    Reviewed-by: Kent Overstreet

    Tejun Heo
     
  • This reverts commit 0a30288da1aec914e158c2d7a3482a85f632750f, which
    was a temporary fix for SCSI blk-mq stall issue. The following
    patches will fix the issue properly by introducing atomic mode to
    percpu_ref.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Jens Axboe
    Cc: Christoph Hellwig

    Tejun Heo
     
  • …linux-block into for-3.18

    This is to receive 0a30288da1ae ("blk-mq, percpu_ref: implement a
    kludge for SCSI blk-mq stall during probe") which implements
    __percpu_ref_kill_expedited() to work around SCSI blk-mq stall. The
    commit reverted and patches to implement proper fix will be added.

    Signed-off-by: Tejun Heo <tj@kernel.org>
    Cc: Kent Overstreet <kmo@daterainc.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Christoph Hellwig <hch@lst.de>

    Tejun Heo
     

24 Sep, 2014

1 commit

  • blk-mq uses percpu_ref for its usage counter which tracks the number
    of in-flight commands and used to synchronously drain the queue on
    freeze. percpu_ref shutdown takes measureable wallclock time as it
    involves a sched RCU grace period. This means that draining a blk-mq
    takes measureable wallclock time. One would think that this shouldn't
    matter as queue shutdown should be a rare event which takes place
    asynchronously w.r.t. userland.

    Unfortunately, SCSI probing involves synchronously setting up and then
    tearing down a lot of request_queues back-to-back for non-existent
    LUNs. This means that SCSI probing may take more than ten seconds
    when scsi-mq is used.

    This will be properly fixed by implementing a mechanism to keep
    q->mq_usage_counter in atomic mode till genhd registration; however,
    that involves rather big updates to percpu_ref which is difficult to
    apply late in the devel cycle (v3.17-rc6 at the moment). As a
    stop-gap measure till the proper fix can be implemented in the next
    cycle, this patch introduces __percpu_ref_kill_expedited() and makes
    blk_mq_freeze_queue() use it. This is heavy-handed but should work
    for testing the experimental SCSI blk-mq implementation.

    Signed-off-by: Tejun Heo
    Reported-by: Christoph Hellwig
    Link: http://lkml.kernel.org/g/20140919113815.GA10791@lst.de
    Fixes: add703fda981 ("blk-mq: use percpu_ref for mq usage count")
    Cc: Kent Overstreet
    Cc: Jens Axboe
    Tested-by: Christoph Hellwig
    Signed-off-by: Jens Axboe

    Tejun Heo
     

20 Sep, 2014

2 commits

  • percpu_ref is currently based on ints and the number of refs it can
    cover is (1 << 31). This makes it impossible to use a percpu_ref to
    count memory objects or pages on 64bit machines as it may overflow.
    This forces those users to somehow aggregate the references before
    contributing to the percpu_ref which is often cumbersome and sometimes
    challenging to get the same level of performance as using the
    percpu_ref directly.

    While using ints for the percpu counters makes them pack tighter on
    64bit machines, the possible gain from using ints instead of longs is
    extremely small compared to the overall gain from per-cpu operation.
    This patch makes percpu_ref based on longs so that it can be used to
    directly count memory objects or pages.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Johannes Weiner

    Tejun Heo
     
  • percpu_ref's WARN messages can be a lot more helpful by indicating
    who's the culprit. Make them report the release function that the
    offending percpu-refcount is associated with. This should make it a
    lot easier to track down the reported invalid refcnting operations.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet

    Tejun Heo
     

08 Sep, 2014

1 commit

  • Percpu allocator now supports allocation mask. Add @gfp to
    percpu_ref_init() so that !GFP_KERNEL allocation masks can be used
    with percpu_refs too.

    This patch doesn't make any functional difference.

    v2: blk-mq conversion was missing. Updated.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Benjamin LaHaise
    Cc: Li Zefan
    Cc: Nicholas A. Bellinger
    Cc: Jens Axboe

    Tejun Heo
     

28 Jun, 2014

5 commits

  • Now that explicit invocation of percpu_ref_exit() is necessary to free
    the percpu counter, we can implement percpu_ref_reinit() which
    reinitializes a released percpu_ref. This can be used implement
    scalable gating switch which can be drained and then re-opened without
    worrying about memory allocation failures.

    percpu_ref_is_zero() is added to be used in a sanity check in
    percpu_ref_exit(). As this function will be useful for other purposes
    too, make it a public interface.

    v2: Use smp_read_barrier_depends() instead of smp_load_acquire(). We
    only need data dep barrier and smp_load_acquire() is stronger and
    heavier on some archs. Spotted by Lai Jiangshan.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Christoph Lameter
    Cc: Lai Jiangshan

    Tejun Heo
     
  • Currently, a percpu_ref undoes percpu_ref_init() automatically by
    freeing the allocated percpu area when the percpu_ref is killed.
    While seemingly convenient, this has the following niggles.

    * It's impossible to re-init a released reference counter without
    going through re-allocation.

    * In the similar vein, it's impossible to initialize a percpu_ref
    count with static percpu variables.

    * We need and have an explicit destructor anyway for failure paths -
    percpu_ref_cancel_init().

    This patch removes the automatic percpu counter freeing in
    percpu_ref_kill_rcu() and repurposes percpu_ref_cancel_init() into a
    generic destructor now named percpu_ref_exit(). percpu_ref_destroy()
    is considered but it gets confusing with percpu_ref_kill() while
    "exit" clearly indicates that it's the counterpart of
    percpu_ref_init().

    All percpu_ref_cancel_init() users are updated to invoke
    percpu_ref_exit() instead and explicit percpu_ref_exit() calls are
    added to the destruction path of all percpu_ref users.

    Signed-off-by: Tejun Heo
    Acked-by: Benjamin LaHaise
    Cc: Kent Overstreet
    Cc: Christoph Lameter
    Cc: Benjamin LaHaise
    Cc: Nicholas A. Bellinger
    Cc: Li Zefan

    Tejun Heo
     
  • percpu_ref->pcpu_count is a percpu pointer with a status flag in its
    lowest bit. As such, it always goes through arithmetic operations
    which is very cumbersome to do on a pointer. It has to be first
    casted to unsigned long and then back.

    Let's just make the field unsigned long so that we can skip the first
    casts. While at it, rename it to pcpu_counter_ptr to clarify that
    it's a pointer value.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Christoph Lameter

    Tejun Heo
     
  • * All four percpu_ref_*() operations implemented in the header file
    perform the same operation to determine whether the percpu_ref is
    alive and extract the percpu pointer. Factor out the common logic
    into __pcpu_ref_alive(). This doesn't change the generated code.

    * There are a couple places in percpu-refcount.c which masks out
    PCPU_REF_DEAD to obtain the percpu pointer. Factor it out into
    pcpu_count_ptr().

    * The above changes make the WARN_ON_ONCE() conditional at the top of
    percpu_ref_kill_and_confirm() the only user of REF_STATUS(). Test
    PCPU_REF_DEAD directly and remove REF_STATUS().

    This patch doesn't introduce any functional change.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Christoph Lameter

    Tejun Heo
     
  • percpu-refcount currently reserves two lowest bits of its percpu
    pointer to indicate its state; however, only one bit is used for
    PCPU_REF_DEAD.

    Simplify it by removing PCPU_STATUS_BITS/MASK and testing
    PCPU_REF_DEAD directly. This also allows the compiler to choose a
    more efficient instruction depending on the architecture.

    Signed-off-by: Tejun Heo
    Cc: Kent Overstreet
    Cc: Christoph Lameter

    Tejun Heo
     

21 Jan, 2014

1 commit

  • AIO had a missing get, which led to an ioctx leak - after percpu_ref_kill() the
    ref was 0 so percpu_ref_put() never saw it hit 0.

    This wasn't noticed at the time because it all happened completely silently,
    this adds a WARN() which would've caught the aio bug.

    tj: Used WARN_ONCE() instead of WARN().

    Signed-off-by: Kent Overstreet
    Signed-off-by: Tejun Heo

    Kent Overstreet
     

17 Oct, 2013

1 commit


17 Jun, 2013

1 commit

  • percpu-refcount was incorrectly using preempt_disable/enable() for RCU
    critical sections against call_rcu(). 6a24474da8 ("percpu-refcount:
    consistently use plain (non-sched) RCU") fixed it by converting the
    preepmtion operations with rcu_read_[un]lock() citing that there isn't
    any advantage in using sched-RCU over using the usual one; however,
    rcu_read_[un]lock() for the preemptible RCU implementation -
    CONFIG_TREE_PREEMPT_RCU, chosen when CONFIG_PREEMPT - are slightly
    more expensive than preempt_disable/enable().

    In a contrived microbench which repeats the followings,

    - percpu_ref_get()
    - copy 32 bytes of data into percpu buffer
    - percpu_put_get()
    - copy 32 bytes of data into percpu buffer

    rcu_read_[un]lock() used in percpu_ref_get/put() makes it go slower by
    about 15% when compared to using sched-RCU.

    As the RCU critical sections are extremely short, using sched-RCU
    shouldn't have any latency implications. Convert to RCU-sched.

    Signed-off-by: Tejun Heo
    Acked-by: Kent Overstreet
    Acked-by: "Paul E. McKenney"
    Cc: Michal Hocko
    Cc: Rusty Russell

    Tejun Heo
     

14 Jun, 2013

3 commits

  • Implement percpu_tryget() which stops giving out references once the
    percpu_ref is visible as killed. Because the refcnt is per-cpu,
    different CPUs will start to see a refcnt as killed at different
    points in time and tryget() may continue to succeed on subset of cpus
    for a while after percpu_ref_kill() returns.

    For use cases where it's necessary to know when all CPUs start to see
    the refcnt as dead, percpu_ref_kill_and_confirm() is added. The new
    function takes an extra argument @confirm_kill which is invoked when
    the refcnt is guaranteed to be viewed as killed on all CPUs.

    While this isn't the prettiest interface, it doesn't force synchronous
    wait and is much safer than requiring the caller to do its own
    call_rcu().

    v2: Patch description rephrased to emphasize that tryget() may
    continue to succeed on some CPUs after kill() returns as suggested
    by Kent.

    v3: Function comment in percpu_ref_kill_and_confirm() updated warning
    people to not depend on the implied RCU grace period from the
    confirm callback as it's an implementation detail.

    Signed-off-by: Tejun Heo
    Slightly-Grumpily-Acked-by: Kent Overstreet

    Tejun Heo
     
  • Normally, percpu_ref_init() initializes and percpu_ref_kill()
    initiates destruction which completes asynchronously. The
    asynchronous destruction can be problematic in init failure path where
    the caller wants to destroy half-constructed object - distinguishing
    half-constructed objects from the usual release method can be painful
    for complex objects.

    This patch implements percpu_ref_cancel_init() which synchronously
    destroys the percpu_ref without invoking release. To avoid
    unintentional misuses, the function requires the ref to have finished
    percpu_ref_init() but never used and triggers WARN otherwise.

    v2: Explain the weird name and usage restriction in the function
    comment.

    Signed-off-by: Tejun Heo
    Acked-by: Kent Overstreet

    Tejun Heo
     
  • …() in percpu_ref_kill_rcu()

    Two small changes.

    * Unlike most init functions, percpu_ref_init() allocates memory and
    may fail. Let's mark it with __must_check in case the caller
    forgets.

    * percpu_ref_kill_rcu() is unnecessarily using ACCESS_ONCE() to
    dereference @ref->pcpu_count, which can be misleading. The pointer
    is guaranteed to be valid and visible and can't change underneath
    the function. Drop ACCESS_ONCE().

    Signed-off-by: Tejun Heo <tj@kernel.org>

    Tejun Heo
     

13 Jun, 2013

1 commit

  • * s/percpu_ref_release/percpu_ref_func_t/ as it's customary to have _t
    postfix for types and the type is gonna be used for a different type
    of callback too.

    * Add @ARG to function comments.

    * Drop unnecessary and unaligned indentation from percpu_ref_init()
    function comment.

    Signed-off-by: Tejun Heo
    Acked-by: Kent Overstreet

    Tejun Heo
     

04 Jun, 2013

2 commits

  • The cmpxchg() was just to ensure the debug check didn't race, which was
    a bit excessive. The caller is supposed to do the appropriate
    synchronization, which means percpu_ref_kill() can just do a simple
    store.

    Signed-off-by: Kent Overstreet
    Signed-off-by: Tejun Heo

    Kent Overstreet
     
  • This implements a refcount with similar semantics to
    atomic_get()/atomic_dec_and_test() - but percpu.

    It also implements two stage shutdown, as we need it to tear down the
    percpu counts. Before dropping the initial refcount, you must call
    percpu_ref_kill(); this puts the refcount in "shutting down mode" and
    switches back to a single atomic refcount with the appropriate
    barriers (synchronize_rcu()).

    It's also legal to call percpu_ref_kill() multiple times - it only
    returns true once, so callers don't have to reimplement shutdown
    synchronization.

    [akpm@linux-foundation.org: fix build]
    [akpm@linux-foundation.org: coding-style tweak]
    Signed-off-by: Kent Overstreet
    Cc: Zach Brown
    Cc: Felipe Balbi
    Cc: Greg Kroah-Hartman
    Cc: Mark Fasheh
    Cc: Joel Becker
    Cc: Rusty Russell
    Cc: Jens Axboe
    Cc: Asai Thambi S P
    Cc: Selvan Mani
    Cc: Sam Bradshaw
    Cc: Jeff Moyer
    Cc: Al Viro
    Cc: Benjamin LaHaise
    Cc: Tejun Heo
    Cc: Oleg Nesterov
    Cc: Christoph Lameter
    Cc: Ingo Molnar
    Reviewed-by: "Theodore Ts'o"
    Signed-off-by: Tejun Heo

    Kent Overstreet