By allowing a different unless value than 1, we can do dec_and_lock like things on higher values, like 2, which is useful if the data structure we lock also owns a reference (because in that case we'd never hit 1). Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx> --- include/linux/refcount.h | 8 +++++++- lib/refcount.c | 14 ++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) --- a/include/linux/refcount.h +++ b/include/linux/refcount.h @@ -35,7 +35,13 @@ extern __must_check bool refcount_dec_an extern void refcount_dec(refcount_t *r); extern __must_check bool refcount_dec_if_one(refcount_t *r); -extern __must_check bool refcount_dec_not_one(refcount_t *r); +extern __must_check bool refcount_dec_unless(refcount_t *r, unsigned int unless); + +static inline __must_check bool refcount_dec_not_one(refcount_t *r) +{ + return refcount_dec_unless(r, 1); +} + extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); --- a/lib/refcount.c +++ b/lib/refcount.c @@ -174,12 +174,14 @@ bool refcount_dec_if_one(refcount_t *r) EXPORT_SYMBOL_GPL(refcount_dec_if_one); /* - * No atomic_t counterpart, it decrements unless the value is 1, in which case - * it will return false. + * No atomic_t counterpart, it decrements unless the value is as specified, in + * which case it will return false. * - * Was often done like: atomic_add_unless(&var, -1, 1) + * Was often done like: atomic_add_unless(&var, -1, unless), where the most + * common variant has unless==1 is provided as a convenience wrapper, see + * refcount_dec_not_one(). */ -bool refcount_dec_not_one(refcount_t *r) +bool refcount_dec_unless(refcount_t *r, unsigned int unless) { unsigned int new, val = atomic_read(&r->refs); @@ -187,7 +189,7 @@ bool refcount_dec_not_one(refcount_t *r) if (unlikely(val == UINT_MAX)) return true; - if (val == 1) + if (val == unless) return false; new = val - 1; @@ -200,7 +202,7 @@ bool refcount_dec_not_one(refcount_t *r) return true; } -EXPORT_SYMBOL_GPL(refcount_dec_not_one); +EXPORT_SYMBOL_GPL(refcount_dec_unless); /* * Similar to atomic_dec_and_mutex_lock(), it will WARN on underflow and fail