Skip to content

Commit

Permalink
Merge branch 'for-3.16' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
htejun committed May 13, 2014
2 parents 2b53f41 + 4fb6e25 commit d39ea87
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 3 deletions.
2 changes: 1 addition & 1 deletion include/linux/cgroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
34 changes: 33 additions & 1 deletion include/linux/percpu-refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,47 @@ 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.
*
* Completion of percpu_ref_kill() in itself doesn't guarantee that tryget
* 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;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/percpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d39ea87

Please sign in to comment.