]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
locking/atomic, kref: Implement kref_put_lock()
authorPeter Zijlstra <peterz@infradead.org>
Mon, 14 Nov 2016 17:03:11 +0000 (18:03 +0100)
committerIngo Molnar <mingo@kernel.org>
Wed, 18 Jan 2017 09:03:29 +0000 (10:03 +0100)
Because home-rolling your own is _awesome_, stop doing it. Provide
kref_put_lock(), just like kref_put_mutex() but for a spinlock.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
include/linux/kref.h
net/sunrpc/svcauth.c

index 31c49a64cdf935ddf0b168d0f1a2cdea5c75c95a..9db9685fed847491a294e229f7d752a8a21cd755 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/atomic.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
+#include <linux/spinlock.h>
 
 struct kref {
        atomic_t refcount;
@@ -86,12 +87,21 @@ static inline int kref_put_mutex(struct kref *kref,
                                 struct mutex *lock)
 {
        WARN_ON(release == NULL);
-       if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) {
-               mutex_lock(lock);
-               if (unlikely(!atomic_dec_and_test(&kref->refcount))) {
-                       mutex_unlock(lock);
-                       return 0;
-               }
+
+       if (atomic_dec_and_mutex_lock(&kref->refcount, lock)) {
+               release(kref);
+               return 1;
+       }
+       return 0;
+}
+
+static inline int kref_put_lock(struct kref *kref,
+                               void (*release)(struct kref *kref),
+                               spinlock_t *lock)
+{
+       WARN_ON(release == NULL);
+
+       if (atomic_dec_and_lock(&kref->refcount, lock)) {
                release(kref);
                return 1;
        }
index e112da8005b5c8f8f70a94124705b6c8c941c555..bb8db3cb8032ee0a4714cf3b49aeb83cb73037bd 100644 (file)
@@ -126,13 +126,18 @@ EXPORT_SYMBOL_GPL(svc_auth_unregister);
 static struct hlist_head       auth_domain_table[DN_HASHMAX];
 static DEFINE_SPINLOCK(auth_domain_lock);
 
+static void auth_domain_release(struct kref *kref)
+{
+       struct auth_domain *dom = container_of(kref, struct auth_domain, ref);
+
+       hlist_del(&dom->hash);
+       dom->flavour->domain_release(dom);
+       spin_unlock(&auth_domain_lock);
+}
+
 void auth_domain_put(struct auth_domain *dom)
 {
-       if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) {
-               hlist_del(&dom->hash);
-               dom->flavour->domain_release(dom);
-               spin_unlock(&auth_domain_lock);
-       }
+       kref_put_lock(&dom->ref, auth_domain_release, &auth_domain_lock);
 }
 EXPORT_SYMBOL_GPL(auth_domain_put);