2 * Dynamic percpu refcounts:
3 * (C) 2012 Google, Inc.
4 * Author: Kent Overstreet <koverstreet@google.com>
6 * This implements a refcount with similar semantics to atomic_t - atomic_inc(),
7 * atomic_dec_and_test() - but potentially percpu.
9 * There's one important difference between percpu refs and normal atomic_t
10 * refcounts; you have to keep track of your initial refcount, and then when you
11 * start shutting down you call percpu_ref_kill() _before_ dropping the initial
14 * Before you call percpu_ref_kill(), percpu_ref_put() does not check for the
15 * refcount hitting 0 - it can't, if it was in percpu mode. percpu_ref_kill()
16 * puts the ref back in single atomic_t mode, collecting the per cpu refs and
17 * issuing the appropriate barriers, and then marks the ref as shutting down so
18 * that percpu_ref_put() will check for the ref hitting 0. After it returns,
19 * it's safe to drop the initial ref.
23 * Percpu refcounts are quite useful for performance, but if we blindly
24 * converted all refcounts to percpu counters we'd waste quite a bit of memory.
26 * Think about all the refcounts embedded in kobjects, files, etc. most of which
27 * aren't used much. These start out as simple atomic counters - a little bigger
28 * than a bare atomic_t, 16 bytes instead of 4 - but if we exceed some arbitrary
29 * number of gets in one second, we then switch to percpu counters.
31 * This heuristic isn't perfect because it'll fire if the refcount was only
32 * being used on one cpu; ideally we'd be able to count the number of cache
33 * misses on percpu_ref_get() or something similar, but that'd make the non
34 * percpu path significantly heavier/more complex. We can count the number of
35 * gets() without any extra atomic instructions on arches that support
36 * atomic64_t - simply by changing the atomic_inc() to atomic_add_return().
40 * See fs/aio.c for some example usage; it's used there for struct kioctx, which
41 * is created when userspaces calls io_setup(), and destroyed when userspace
42 * calls io_destroy() or the process exits.
44 * In the aio code, kill_ioctx() is called when we wish to destroy a kioctx; it
45 * calls percpu_ref_kill(), then hlist_del_rcu() and sychronize_rcu() to remove
46 * the kioctx from the proccess's list of kioctxs - after that, there can't be
47 * any new users of the kioctx (from lookup_ioctx()) and it's then safe to drop
48 * the initial ref with percpu_ref_put().
50 * Code that does a two stage shutdown like this often needs some kind of
51 * explicit synchronization to ensure the initial refcount can only be dropped
52 * once - percpu_ref_kill() does this for you, it returns true once and false if
53 * someone else already called it. The aio code uses it this way, but it's not
54 * necessary if the code has some other mechanism to synchronize teardown.
56 * As mentioned previously, we decide when to convert a ref to percpu counters
57 * in percpu_ref_get(). However, since percpu_ref_get() will often be called
58 * with rcu_read_lock() held, it's not done there - percpu_ref_get() returns
59 * true if the ref should be converted to percpu counters.
61 * The caller should then call percpu_ref_alloc() after dropping
62 * rcu_read_lock(); if there is an uncommonly used codepath where it's
63 * inconvenient to call percpu_ref_alloc() after get(), it may be safely skipped
64 * and percpu_ref_get() will return true again the next time the counter wraps
68 #ifndef _LINUX_PERCPU_REFCOUNT_H
69 #define _LINUX_PERCPU_REFCOUNT_H
71 #include <linux/atomic.h>
72 #include <linux/percpu.h>
76 unsigned long pcpu_count;
79 void percpu_ref_init(struct percpu_ref *ref);
80 void __percpu_ref_get(struct percpu_ref *ref, bool alloc);
81 int percpu_ref_put(struct percpu_ref *ref);
83 int percpu_ref_kill(struct percpu_ref *ref);
84 int percpu_ref_dead(struct percpu_ref *ref);
87 * percpu_ref_get - increment a dynamic percpu refcount
89 * Increments @ref and possibly converts it to percpu counters. Must be called
90 * with rcu_read_lock() held, and may potentially drop/reacquire rcu_read_lock()
91 * to allocate percpu counters - if sleeping/allocation isn't safe for some
92 * other reason (e.g. a spinlock), see percpu_ref_get_noalloc().
94 * Analagous to atomic_inc().
96 static inline void percpu_ref_get(struct percpu_ref *ref)
98 __percpu_ref_get(ref, true);
102 * percpu_ref_get_noalloc - increment a dynamic percpu refcount
104 * Increments @ref, to be used when it's not safe to allocate percpu counters.
105 * Must be called with rcu_read_lock() held.
107 * Analagous to atomic_inc().
109 static inline void percpu_ref_get_noalloc(struct percpu_ref *ref)
111 __percpu_ref_get(ref, false);