1/* 2 * kref.h - library routines for handling generic reference counted objects 3 * 4 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 5 * Copyright (C) 2004 IBM Corp. 6 * 7 * based on kobject.h which was: 8 * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org> 9 * Copyright (C) 2002-2003 Open Source Development Labs 10 * 11 * This file is released under the GPLv2. 12 * 13 */ 14 15#ifndef _KREF_H_ 16#define _KREF_H_ 17 18#include <linux/bug.h> 19#include <linux/atomic.h> 20#include <linux/kernel.h> 21#include <linux/mutex.h> 22#include <linux/spinlock.h> 23 24struct kref { 25 atomic_t refcount; 26}; 27 28/** 29 * kref_init - initialize object. 30 * @kref: object in question. 31 */ 32static inline void kref_init(struct kref *kref) 33{ 34 atomic_set(&kref->refcount, 1); 35} 36 37/** 38 * kref_get - increment refcount for object. 39 * @kref: object. 40 */ 41static inline void kref_get(struct kref *kref) 42{ 43 /* If refcount was 0 before incrementing then we have a race 44 * condition when this kref is freeing by some other thread right now. 45 * In this case one should use kref_get_unless_zero() 46 */ 47 WARN_ON_ONCE(atomic_inc_return(&kref->refcount) < 2); 48} 49 50/** 51 * kref_sub - subtract a number of refcounts for object. 52 * @kref: object. 53 * @count: Number of recounts to subtract. 54 * @release: pointer to the function that will clean up the object when the 55 * last reference to the object is released. 56 * This pointer is required, and it is not acceptable to pass kfree 57 * in as this function. If the caller does pass kfree to this 58 * function, you will be publicly mocked mercilessly by the kref 59 * maintainer, and anyone else who happens to notice it. You have 60 * been warned. 61 * 62 * Subtract @count from the refcount, and if 0, call release(). 63 * Return 1 if the object was removed, otherwise return 0. Beware, if this 64 * function returns 0, you still can not count on the kref from remaining in 65 * memory. Only use the return value if you want to see if the kref is now 66 * gone, not present. 67 */ 68static inline int kref_sub(struct kref *kref, unsigned int count, 69 void (*release)(struct kref *kref)) 70{ 71 WARN_ON(release == NULL); 72 73 if (atomic_sub_and_test((int) count, &kref->refcount)) { 74 release(kref); 75 return 1; 76 } 77 return 0; 78} 79 80/** 81 * kref_put - decrement refcount for object. 82 * @kref: object. 83 * @release: pointer to the function that will clean up the object when the 84 * last reference to the object is released. 85 * This pointer is required, and it is not acceptable to pass kfree 86 * in as this function. If the caller does pass kfree to this 87 * function, you will be publicly mocked mercilessly by the kref 88 * maintainer, and anyone else who happens to notice it. You have 89 * been warned. 90 * 91 * Decrement the refcount, and if 0, call release(). 92 * Return 1 if the object was removed, otherwise return 0. Beware, if this 93 * function returns 0, you still can not count on the kref from remaining in 94 * memory. Only use the return value if you want to see if the kref is now 95 * gone, not present. 96 */ 97static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 98{ 99 return kref_sub(kref, 1, release); 100} 101 102/** 103 * kref_put_spinlock_irqsave - decrement refcount for object. 104 * @kref: object. 105 * @release: pointer to the function that will clean up the object when the 106 * last reference to the object is released. 107 * This pointer is required, and it is not acceptable to pass kfree 108 * in as this function. 109 * @lock: lock to take in release case 110 * 111 * Behaves identical to kref_put with one exception. If the reference count 112 * drops to zero, the lock will be taken atomically wrt dropping the reference 113 * count. The release function has to call spin_unlock() without _irqrestore. 114 */ 115static inline int kref_put_spinlock_irqsave(struct kref *kref, 116 void (*release)(struct kref *kref), 117 spinlock_t *lock) 118{ 119 unsigned long flags; 120 121 WARN_ON(release == NULL); 122 if (atomic_add_unless(&kref->refcount, -1, 1)) 123 return 0; 124 spin_lock_irqsave(lock, flags); 125 if (atomic_dec_and_test(&kref->refcount)) { 126 release(kref); 127 local_irq_restore(flags); 128 return 1; 129 } 130 spin_unlock_irqrestore(lock, flags); 131 return 0; 132} 133 134static inline int kref_put_mutex(struct kref *kref, 135 void (*release)(struct kref *kref), 136 struct mutex *lock) 137{ 138 WARN_ON(release == NULL); 139 if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { 140 mutex_lock(lock); 141 if (unlikely(!atomic_dec_and_test(&kref->refcount))) { 142 mutex_unlock(lock); 143 return 0; 144 } 145 release(kref); 146 return 1; 147 } 148 return 0; 149} 150 151/** 152 * kref_get_unless_zero - Increment refcount for object unless it is zero. 153 * @kref: object. 154 * 155 * Return non-zero if the increment succeeded. Otherwise return 0. 156 * 157 * This function is intended to simplify locking around refcounting for 158 * objects that can be looked up from a lookup structure, and which are 159 * removed from that lookup structure in the object destructor. 160 * Operations on such objects require at least a read lock around 161 * lookup + kref_get, and a write lock around kref_put + remove from lookup 162 * structure. Furthermore, RCU implementations become extremely tricky. 163 * With a lookup followed by a kref_get_unless_zero *with return value check* 164 * locking in the kref_put path can be deferred to the actual removal from 165 * the lookup structure and RCU lookups become trivial. 166 */ 167static inline int __must_check kref_get_unless_zero(struct kref *kref) 168{ 169 return atomic_add_unless(&kref->refcount, 1, 0); 170} 171#endif /* _KREF_H_ */ 172