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 23struct kref { 24 atomic_t refcount; 25}; 26 27/** 28 * kref_init - initialize object. 29 * @kref: object in question. 30 */ 31static inline void kref_init(struct kref *kref) 32{ 33 atomic_set(&kref->refcount, 1); 34} 35 36/** 37 * kref_get - increment refcount for object. 38 * @kref: object. 39 */ 40static inline void kref_get(struct kref *kref) 41{ 42 /* If refcount was 0 before incrementing then we have a race 43 * condition when this kref is freeing by some other thread right now. 44 * In this case one should use kref_get_unless_zero() 45 */ 46 WARN_ON_ONCE(atomic_inc_return(&kref->refcount) < 2); 47} 48 49/** 50 * kref_sub - subtract a number of refcounts for object. 51 * @kref: object. 52 * @count: Number of recounts to subtract. 53 * @release: pointer to the function that will clean up the object when the 54 * last reference to the object is released. 55 * This pointer is required, and it is not acceptable to pass kfree 56 * in as this function. If the caller does pass kfree to this 57 * function, you will be publicly mocked mercilessly by the kref 58 * maintainer, and anyone else who happens to notice it. You have 59 * been warned. 60 * 61 * Subtract @count from the refcount, and if 0, call release(). 62 * Return 1 if the object was removed, otherwise return 0. Beware, if this 63 * function returns 0, you still can not count on the kref from remaining in 64 * memory. Only use the return value if you want to see if the kref is now 65 * gone, not present. 66 */ 67static inline int kref_sub(struct kref *kref, unsigned int count, 68 void (*release)(struct kref *kref)) 69{ 70 WARN_ON(release == NULL); 71 72 if (atomic_sub_and_test((int) count, &kref->refcount)) { 73 release(kref); 74 return 1; 75 } 76 return 0; 77} 78 79/** 80 * kref_put - decrement refcount for object. 81 * @kref: object. 82 * @release: pointer to the function that will clean up the object when the 83 * last reference to the object is released. 84 * This pointer is required, and it is not acceptable to pass kfree 85 * in as this function. If the caller does pass kfree to this 86 * function, you will be publicly mocked mercilessly by the kref 87 * maintainer, and anyone else who happens to notice it. You have 88 * been warned. 89 * 90 * Decrement the refcount, and if 0, call release(). 91 * Return 1 if the object was removed, otherwise return 0. Beware, if this 92 * function returns 0, you still can not count on the kref from remaining in 93 * memory. Only use the return value if you want to see if the kref is now 94 * gone, not present. 95 */ 96static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 97{ 98 return kref_sub(kref, 1, release); 99} 100 101static inline int kref_put_mutex(struct kref *kref, 102 void (*release)(struct kref *kref), 103 struct mutex *lock) 104{ 105 WARN_ON(release == NULL); 106 if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { 107 mutex_lock(lock); 108 if (unlikely(!atomic_dec_and_test(&kref->refcount))) { 109 mutex_unlock(lock); 110 return 0; 111 } 112 release(kref); 113 return 1; 114 } 115 return 0; 116} 117 118/** 119 * kref_get_unless_zero - Increment refcount for object unless it is zero. 120 * @kref: object. 121 * 122 * Return non-zero if the increment succeeded. Otherwise return 0. 123 * 124 * This function is intended to simplify locking around refcounting for 125 * objects that can be looked up from a lookup structure, and which are 126 * removed from that lookup structure in the object destructor. 127 * Operations on such objects require at least a read lock around 128 * lookup + kref_get, and a write lock around kref_put + remove from lookup 129 * structure. Furthermore, RCU implementations become extremely tricky. 130 * With a lookup followed by a kref_get_unless_zero *with return value check* 131 * locking in the kref_put path can be deferred to the actual removal from 132 * the lookup structure and RCU lookups become trivial. 133 */ 134static inline int __must_check kref_get_unless_zero(struct kref *kref) 135{ 136 return atomic_add_unless(&kref->refcount, 1, 0); 137} 138#endif /* _KREF_H_ */ 139