Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at d986ba0329dcca102e227995371135c9bbcefb6b 135 lines 4.0 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * kref.h - library routines for handling generic reference counted objects 4 * 5 * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> 6 * Copyright (C) 2004 IBM Corp. 7 * 8 * based on kobject.h which was: 9 * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org> 10 * Copyright (C) 2002-2003 Open Source Development Labs 11 */ 12 13#ifndef _KREF_H_ 14#define _KREF_H_ 15 16#include <linux/spinlock.h> 17#include <linux/refcount.h> 18 19struct kref { 20 refcount_t refcount; 21}; 22 23#define KREF_INIT(n) { .refcount = REFCOUNT_INIT(n), } 24 25/** 26 * kref_init - initialize object. 27 * @kref: object in question. 28 */ 29static inline void kref_init(struct kref *kref) 30{ 31 refcount_set(&kref->refcount, 1); 32} 33 34static inline unsigned int kref_read(const struct kref *kref) 35{ 36 return refcount_read(&kref->refcount); 37} 38 39/** 40 * kref_get - increment refcount for object. 41 * @kref: object. 42 */ 43static inline void kref_get(struct kref *kref) 44{ 45 refcount_inc(&kref->refcount); 46} 47 48/** 49 * kref_put - Decrement refcount for object 50 * @kref: Object 51 * @release: Pointer to the function that will clean up the object when the 52 * last reference to the object is released. 53 * 54 * Decrement the refcount, and if 0, call @release. The caller may not 55 * pass NULL or kfree() as the release function. 56 * 57 * Return: 1 if this call removed the object, otherwise return 0. Beware, 58 * if this function returns 0, another caller may have removed the object 59 * by the time this function returns. The return value is only certain 60 * if you want to see if the object is definitely released. 61 */ 62static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref)) 63{ 64 if (refcount_dec_and_test(&kref->refcount)) { 65 release(kref); 66 return 1; 67 } 68 return 0; 69} 70 71/** 72 * kref_put_mutex - Decrement refcount for object 73 * @kref: Object 74 * @release: Pointer to the function that will clean up the object when the 75 * last reference to the object is released. 76 * @mutex: Mutex which protects the release function. 77 * 78 * This variant of kref_lock() calls the @release function with the @mutex 79 * held. The @release function will release the mutex. 80 */ 81static inline int kref_put_mutex(struct kref *kref, 82 void (*release)(struct kref *kref), 83 struct mutex *mutex) 84 __cond_acquires(true, mutex) 85{ 86 if (refcount_dec_and_mutex_lock(&kref->refcount, mutex)) { 87 release(kref); 88 return 1; 89 } 90 return 0; 91} 92 93/** 94 * kref_put_lock - Decrement refcount for object 95 * @kref: Object 96 * @release: Pointer to the function that will clean up the object when the 97 * last reference to the object is released. 98 * @lock: Spinlock which protects the release function. 99 * 100 * This variant of kref_lock() calls the @release function with the @lock 101 * held. The @release function will release the lock. 102 */ 103static inline int kref_put_lock(struct kref *kref, 104 void (*release)(struct kref *kref), 105 spinlock_t *lock) 106 __cond_acquires(true, lock) 107{ 108 if (refcount_dec_and_lock(&kref->refcount, lock)) { 109 release(kref); 110 return 1; 111 } 112 return 0; 113} 114 115/** 116 * kref_get_unless_zero - Increment refcount for object unless it is zero. 117 * @kref: object. 118 * 119 * This function is intended to simplify locking around refcounting for 120 * objects that can be looked up from a lookup structure, and which are 121 * removed from that lookup structure in the object destructor. 122 * Operations on such objects require at least a read lock around 123 * lookup + kref_get, and a write lock around kref_put + remove from lookup 124 * structure. Furthermore, RCU implementations become extremely tricky. 125 * With a lookup followed by a kref_get_unless_zero *with return value check* 126 * locking in the kref_put path can be deferred to the actual removal from 127 * the lookup structure and RCU lookups become trivial. 128 * 129 * Return: non-zero if the increment succeeded. Otherwise return 0. 130 */ 131static inline int __must_check kref_get_unless_zero(struct kref *kref) 132{ 133 return refcount_inc_not_zero(&kref->refcount); 134} 135#endif /* _KREF_H_ */