diff options
author | James Morris <james.l.morris@oracle.com> | 2012-09-28 13:37:32 +1000 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2012-09-28 13:37:32 +1000 |
commit | bf5308344527d015ac9a6d2bda4ad4d40fd7d943 (patch) | |
tree | 566e61e2cfc648c374d15cfc8c661b73e1a471f8 /include/linux/kref.h | |
parent | 3585e96cd1049682b8a19a0b699422156e9d735b (diff) | |
parent | 979570e02981d4a8fc20b3cc8fd651856c98ee9d (diff) | |
download | kernel_replicant_linux-bf5308344527d015ac9a6d2bda4ad4d40fd7d943.tar.gz kernel_replicant_linux-bf5308344527d015ac9a6d2bda4ad4d40fd7d943.tar.bz2 kernel_replicant_linux-bf5308344527d015ac9a6d2bda4ad4d40fd7d943.zip |
Merge tag 'v3.6-rc7' into next
Linux 3.6-rc7
Requested by David Howells so he can merge his key susbsystem work into
my tree with requisite -linus changesets.
Diffstat (limited to 'include/linux/kref.h')
-rw-r--r-- | include/linux/kref.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/include/linux/kref.h b/include/linux/kref.h index 9c07dcebded7..65af6887872f 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h @@ -18,6 +18,7 @@ #include <linux/bug.h> #include <linux/atomic.h> #include <linux/kernel.h> +#include <linux/mutex.h> struct kref { atomic_t refcount; @@ -93,4 +94,21 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) { return kref_sub(kref, 1, release); } + +static inline int kref_put_mutex(struct kref *kref, + void (*release)(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; + } + release(kref); + return 1; + } + return 0; +} #endif /* _KREF_H_ */ |