git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
lib
/
kref.c
diff --git
a/lib/kref.c
b/lib/kref.c
index
2218b7a
..
4a467fa
100644
(file)
--- a/
lib/kref.c
+++ b/
lib/kref.c
@@
-42,14
+42,26
@@
void kref_get(struct kref *kref)
* in as this function.
*
* Decrement the refcount, and if 0, call release().
* in as this function.
*
* Decrement the refcount, and if 0, call release().
+ * Return 1 if the object was removed, otherwise return 0. Beware, if this
+ * function returns 0, you still can not count on the kref from remaining in
+ * memory. Only use the return value if you want to see if the kref is now
+ * gone, not present.
*/
*/
-
void kref_put(struct kref *kref, void (*release)
(struct kref *kref))
+
int kref_put(struct kref *kref, void (*release)
(struct kref *kref))
{
WARN_ON(release == NULL);
WARN_ON(release == (void (*)(struct kref *))kfree);
{
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);
release(kref);
+ return 1;
+ }
+ return 0;
}
EXPORT_SYMBOL(kref_init);
}
EXPORT_SYMBOL(kref_init);