Skip to content

Commit 3b13c16

Browse files
isilenceaxboe
authored andcommitted
percpu_ref: percpu_ref_tryget_live() version holding RCU
Add percpu_ref_tryget_live_rcu(), which is a version of percpu_ref_tryget_live() but the user is responsible for enclosing it in a RCU read lock section. Signed-off-by: Pavel Begunkov <[email protected]> Acked-by: Dennis Zhou <[email protected]> Link: https://lore.kernel.org/r/3066500d7a6eb3e03f10adf98b87fdb3b1c49db8.1634822969.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 6549a87 commit 3b13c16

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

include/linux/percpu-refcount.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,28 @@ static inline bool percpu_ref_tryget(struct percpu_ref *ref)
266266
return percpu_ref_tryget_many(ref, 1);
267267
}
268268

269+
/**
270+
* percpu_ref_tryget_live_rcu - same as percpu_ref_tryget_live() but the
271+
* caller is responsible for taking RCU.
272+
*
273+
* This function is safe to call as long as @ref is between init and exit.
274+
*/
275+
static inline bool percpu_ref_tryget_live_rcu(struct percpu_ref *ref)
276+
{
277+
unsigned long __percpu *percpu_count;
278+
bool ret = false;
279+
280+
WARN_ON_ONCE(!rcu_read_lock_held());
281+
282+
if (likely(__ref_is_percpu(ref, &percpu_count))) {
283+
this_cpu_inc(*percpu_count);
284+
ret = true;
285+
} else if (!(ref->percpu_count_ptr & __PERCPU_REF_DEAD)) {
286+
ret = atomic_long_inc_not_zero(&ref->data->count);
287+
}
288+
return ret;
289+
}
290+
269291
/**
270292
* percpu_ref_tryget_live - try to increment a live percpu refcount
271293
* @ref: percpu_ref to try-get
@@ -283,20 +305,11 @@ static inline bool percpu_ref_tryget(struct percpu_ref *ref)
283305
*/
284306
static inline bool percpu_ref_tryget_live(struct percpu_ref *ref)
285307
{
286-
unsigned long __percpu *percpu_count;
287308
bool ret = false;
288309

289310
rcu_read_lock();
290-
291-
if (__ref_is_percpu(ref, &percpu_count)) {
292-
this_cpu_inc(*percpu_count);
293-
ret = true;
294-
} else if (!(ref->percpu_count_ptr & __PERCPU_REF_DEAD)) {
295-
ret = atomic_long_inc_not_zero(&ref->data->count);
296-
}
297-
311+
ret = percpu_ref_tryget_live_rcu(ref);
298312
rcu_read_unlock();
299-
300313
return ret;
301314
}
302315

0 commit comments

Comments
 (0)