Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * kref.h - library routines for handling generic reference counted objects
0004  *
0005  * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
0006  * Copyright (C) 2004 IBM Corp.
0007  *
0008  * based on kobject.h which was:
0009  * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
0010  * Copyright (C) 2002-2003 Open Source Development Labs
0011  */
0012 
0013 #ifndef _KREF_H_
0014 #define _KREF_H_
0015 
0016 #include <linux/spinlock.h>
0017 #include <linux/refcount.h>
0018 
0019 struct kref {
0020     refcount_t refcount;
0021 };
0022 
0023 #define KREF_INIT(n)    { .refcount = REFCOUNT_INIT(n), }
0024 
0025 /**
0026  * kref_init - initialize object.
0027  * @kref: object in question.
0028  */
0029 static inline void kref_init(struct kref *kref)
0030 {
0031     refcount_set(&kref->refcount, 1);
0032 }
0033 
0034 static inline unsigned int kref_read(const struct kref *kref)
0035 {
0036     return refcount_read(&kref->refcount);
0037 }
0038 
0039 /**
0040  * kref_get - increment refcount for object.
0041  * @kref: object.
0042  */
0043 static inline void kref_get(struct kref *kref)
0044 {
0045     refcount_inc(&kref->refcount);
0046 }
0047 
0048 /**
0049  * kref_put - decrement refcount for object.
0050  * @kref: object.
0051  * @release: pointer to the function that will clean up the object when the
0052  *       last reference to the object is released.
0053  *       This pointer is required, and it is not acceptable to pass kfree
0054  *       in as this function.
0055  *
0056  * Decrement the refcount, and if 0, call release().
0057  * Return 1 if the object was removed, otherwise return 0.  Beware, if this
0058  * function returns 0, you still can not count on the kref from remaining in
0059  * memory.  Only use the return value if you want to see if the kref is now
0060  * gone, not present.
0061  */
0062 static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref))
0063 {
0064     if (refcount_dec_and_test(&kref->refcount)) {
0065         release(kref);
0066         return 1;
0067     }
0068     return 0;
0069 }
0070 
0071 static inline int kref_put_mutex(struct kref *kref,
0072                  void (*release)(struct kref *kref),
0073                  struct mutex *lock)
0074 {
0075     if (refcount_dec_and_mutex_lock(&kref->refcount, lock)) {
0076         release(kref);
0077         return 1;
0078     }
0079     return 0;
0080 }
0081 
0082 static inline int kref_put_lock(struct kref *kref,
0083                 void (*release)(struct kref *kref),
0084                 spinlock_t *lock)
0085 {
0086     if (refcount_dec_and_lock(&kref->refcount, lock)) {
0087         release(kref);
0088         return 1;
0089     }
0090     return 0;
0091 }
0092 
0093 /**
0094  * kref_get_unless_zero - Increment refcount for object unless it is zero.
0095  * @kref: object.
0096  *
0097  * Return non-zero if the increment succeeded. Otherwise return 0.
0098  *
0099  * This function is intended to simplify locking around refcounting for
0100  * objects that can be looked up from a lookup structure, and which are
0101  * removed from that lookup structure in the object destructor.
0102  * Operations on such objects require at least a read lock around
0103  * lookup + kref_get, and a write lock around kref_put + remove from lookup
0104  * structure. Furthermore, RCU implementations become extremely tricky.
0105  * With a lookup followed by a kref_get_unless_zero *with return value check*
0106  * locking in the kref_put path can be deferred to the actual removal from
0107  * the lookup structure and RCU lookups become trivial.
0108  */
0109 static inline int __must_check kref_get_unless_zero(struct kref *kref)
0110 {
0111     return refcount_inc_not_zero(&kref->refcount);
0112 }
0113 #endif /* _KREF_H_ */