Skip to content

Commit

Permalink
percpu-refcount: use unsigned long for pcpu_count pointer
Browse files Browse the repository at this point in the history
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 <tj@kernel.org>
Cc: Kent Overstreet <kmo@daterainc.com>
Cc: Christoph Lameter <cl@linux-foundation.org>
  • Loading branch information
Tejun Heo committed Jun 28, 2014
1 parent eae7975 commit 7d74207
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 8 deletions.
4 changes: 2 additions & 2 deletions include/linux/percpu-refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct percpu_ref {
* hack because we need to keep the pointer around for
* percpu_ref_kill_rcu())
*/
unsigned __percpu *pcpu_count;
unsigned long pcpu_count_ptr;
percpu_ref_func_t *release;
percpu_ref_func_t *confirm_kill;
struct rcu_head rcu;
Expand Down Expand Up @@ -99,7 +99,7 @@ static inline void percpu_ref_kill(struct percpu_ref *ref)
static inline bool __pcpu_ref_alive(struct percpu_ref *ref,
unsigned __percpu **pcpu_countp)
{
unsigned long pcpu_ptr = (unsigned long)ACCESS_ONCE(ref->pcpu_count);
unsigned long pcpu_ptr = ACCESS_ONCE(ref->pcpu_count_ptr);

if (unlikely(pcpu_ptr & PCPU_REF_DEAD))
return false;
Expand Down
11 changes: 5 additions & 6 deletions lib/percpu-refcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

static unsigned __percpu *pcpu_count_ptr(struct percpu_ref *ref)
{
return (unsigned __percpu *)((unsigned long)ref->pcpu_count & ~PCPU_REF_DEAD);
return (unsigned __percpu *)(ref->pcpu_count_ptr & ~PCPU_REF_DEAD);
}

/**
Expand All @@ -51,8 +51,8 @@ int percpu_ref_init(struct percpu_ref *ref, percpu_ref_func_t *release)
{
atomic_set(&ref->count, 1 + PCPU_COUNT_BIAS);

ref->pcpu_count = alloc_percpu(unsigned);
if (!ref->pcpu_count)
ref->pcpu_count_ptr = (unsigned long)alloc_percpu(unsigned);
if (!ref->pcpu_count_ptr)
return -ENOMEM;

ref->release = release;
Expand Down Expand Up @@ -153,11 +153,10 @@ static void percpu_ref_kill_rcu(struct rcu_head *rcu)
void percpu_ref_kill_and_confirm(struct percpu_ref *ref,
percpu_ref_func_t *confirm_kill)
{
WARN_ONCE((unsigned long)ref->pcpu_count & PCPU_REF_DEAD,
WARN_ONCE(ref->pcpu_count_ptr & PCPU_REF_DEAD,
"percpu_ref_kill() called more than once!\n");

ref->pcpu_count = (unsigned __percpu *)
(((unsigned long) ref->pcpu_count)|PCPU_REF_DEAD);
ref->pcpu_count_ptr |= PCPU_REF_DEAD;
ref->confirm_kill = confirm_kill;

call_rcu_sched(&ref->rcu, percpu_ref_kill_rcu);
Expand Down

0 comments on commit 7d74207

Please sign in to comment.