[PATCH] kref: avoid an atomic operation in kref_put()
Eric Dumazet [Mon, 30 Jan 2006 05:19:35 +0000 (06:19 +0100)]
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 0d07cc3..4a467fa 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;
        }