diff options
author | Tejun Heo <tj@kernel.org> | 2014-05-13 11:27:24 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-05-13 11:27:24 -0400 |
commit | d39ea871c3c1269e2852ea096fff492ea034df8a (patch) | |
tree | 762859cc57b776048a968f1ab9ceb06d06d4ffb4 | |
parent | 2b53f41fa8604845f4f7c538723694a453088b15 (diff) | |
parent | 4fb6e25049cb6fa0accc7f1b7c192b952fad7ac8 (diff) |
Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu into for-3.16
Pull to receive percpu_ref_tryget[_live]() changes. Planned cgroup
changes will make use of them.
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | include/linux/cgroup.h | 2 | ||||
-rw-r--r-- | include/linux/percpu-refcount.h | 34 | ||||
-rw-r--r-- | include/linux/percpu.h | 2 |
3 files changed, 35 insertions, 3 deletions
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index f482f95c2c72..6ab3ee5d4a14 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -108,7 +108,7 @@ static inline bool css_tryget(struct cgroup_subsys_state *css) { if (css->flags & CSS_ROOT) return true; - return percpu_ref_tryget(&css->refcnt); + return percpu_ref_tryget_live(&css->refcnt); } /** diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index 95961f0bf62d..dba35c411e8c 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h @@ -121,6 +121,36 @@ static inline void percpu_ref_get(struct percpu_ref *ref) * percpu_ref_tryget - try to increment a percpu refcount * @ref: percpu_ref to try-get * + * Increment a percpu refcount unless its count already reached zero. + * Returns %true on success; %false on failure. + * + * The caller is responsible for ensuring that @ref stays accessible. + */ +static inline bool percpu_ref_tryget(struct percpu_ref *ref) +{ + unsigned __percpu *pcpu_count; + int ret = false; + + rcu_read_lock_sched(); + + pcpu_count = ACCESS_ONCE(ref->pcpu_count); + + if (likely(REF_STATUS(pcpu_count) == PCPU_REF_PTR)) { + __this_cpu_inc(*pcpu_count); + ret = true; + } else { + ret = atomic_inc_not_zero(&ref->count); + } + + rcu_read_unlock_sched(); + + return ret; +} + +/** + * percpu_ref_tryget_live - try to increment a live percpu refcount + * @ref: percpu_ref to try-get + * * Increment a percpu refcount unless it has already been killed. Returns * %true on success; %false on failure. * @@ -128,8 +158,10 @@ static inline void percpu_ref_get(struct percpu_ref *ref) * will fail. For such guarantee, percpu_ref_kill_and_confirm() should be * used. After the confirm_kill callback is invoked, it's guaranteed that * no new reference will be given out by percpu_ref_tryget(). + * + * The caller is responsible for ensuring that @ref stays accessible. */ -static inline bool percpu_ref_tryget(struct percpu_ref *ref) +static inline bool percpu_ref_tryget_live(struct percpu_ref *ref) { unsigned __percpu *pcpu_count; int ret = false; diff --git a/include/linux/percpu.h b/include/linux/percpu.h index e7a0b95ed527..539b3caa5748 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -29,7 +29,7 @@ */ #define get_cpu_var(var) (*({ \ preempt_disable(); \ - &__get_cpu_var(var); })) + this_cpu_ptr(&var); })) /* * The weird & is necessary because sparse considers (void)(var) to be |