[PATCH] kref: avoid an atomic operation in kref_put()
authorEric Dumazet <dada1@cosmosbay.com>
Mon, 30 Jan 2006 05:19:35 +0000 (06:19 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 20 Mar 2006 21:42:57 +0000 (13:42 -0800)
Avoid an atomic operation in kref_put() when the last reference is
dropped. On most platforms, atomic_read() is a plan read of the counter
and involves no atomic at all.

Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
lib/kref.c

index 0d07cc31c818108a5d9e3bc26444957108bad721..4a467faf1367bb031d49eb136ac16de0551a1629 100644 (file)
@@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
        WARN_ON(release == NULL);
        WARN_ON(release == (void (*)(struct kref *))kfree);
 
-       if (atomic_dec_and_test(&kref->refcount)) {
+       /*
+        * if current count is one, we are the last user and can release object
+        * right now, avoiding an atomic operation on 'refcount'
+        */
+       if ((atomic_read(&kref->refcount) == 1) ||
+           (atomic_dec_and_test(&kref->refcount))) {
                release(kref);
                return 1;
        }