X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fkref.c;h=9ecd6e86561034f2a097bcc027765704e124f7df;hb=be821b78af9de886571e3565515a59f966d66f42;hp=4a467faf1367bb031d49eb136ac16de0551a1629;hpb=5501972e0b5857bc8354770d900ceb9b40c7f6b7;p=linux-2.6-omap-h63xx.git diff --git a/lib/kref.c b/lib/kref.c index 4a467faf136..9ecd6e86561 100644 --- a/lib/kref.c +++ b/lib/kref.c @@ -14,13 +14,24 @@ #include #include +/** + * kref_set - initialize object and set refcount to requested number. + * @kref: object in question. + * @num: initial reference counter + */ +void kref_set(struct kref *kref, int num) +{ + atomic_set(&kref->refcount, num); + smp_mb(); +} + /** * kref_init - initialize object. * @kref: object in question. */ void kref_init(struct kref *kref) { - atomic_set(&kref->refcount,1); + kref_set(kref, 1); } /** @@ -31,6 +42,7 @@ void kref_get(struct kref *kref) { WARN_ON(!atomic_read(&kref->refcount)); atomic_inc(&kref->refcount); + smp_mb__after_atomic_inc(); } /** @@ -52,18 +64,14 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref)) WARN_ON(release == NULL); WARN_ON(release == (void (*)(struct kref *))kfree); - /* - * 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))) { + if (atomic_dec_and_test(&kref->refcount)) { release(kref); return 1; } return 0; } +EXPORT_SYMBOL(kref_set); EXPORT_SYMBOL(kref_init); EXPORT_SYMBOL(kref_get); EXPORT_SYMBOL(kref_put);