From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751550AbdBXSpf (ORCPT ); Fri, 24 Feb 2017 13:45:35 -0500 Received: from merlin.infradead.org ([205.233.59.134]:59438 "EHLO merlin.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751348AbdBXSoX (ORCPT ); Fri, 24 Feb 2017 13:44:23 -0500 Message-Id: <20170224162044.479190330@infradead.org> User-Agent: quilt/0.63-1 Date: Fri, 24 Feb 2017 16:43:38 +0100 From: Peter Zijlstra To: Al Viro , Linus Torvalds , Chris Mason Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, David Howells , elena.reshetova@intel.com, ishkamiel@gmail.com, dwindsor@gmail.com, gregkh@linuxfoundation.org, peterz@infradead.org Subject: [RFC][PATCH 09/10] locking/refcount: Provide refcount_dec_unless() References: <20170224154329.478276481@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline; filename=peterz-ref-9.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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) --- 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