forked from mirrors/linux
		
	 55716d2643
			
		
	
	
		55716d2643
		
	
	
	
	
		
			
			Based on 1 normalized pattern(s): this file is released under the gplv2 extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 68 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Armijn Hemel <armijn@tjaldur.nl> Reviewed-by: Allison Randal <allison@lohutok.net> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190531190114.292346262@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
		
			
				
	
	
		
			113 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: GPL-2.0-only */
 | |
| /*
 | |
|  * kref.h - library routines for handling generic reference counted objects
 | |
|  *
 | |
|  * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
 | |
|  * Copyright (C) 2004 IBM Corp.
 | |
|  *
 | |
|  * based on kobject.h which was:
 | |
|  * Copyright (C) 2002-2003 Patrick Mochel <mochel@osdl.org>
 | |
|  * Copyright (C) 2002-2003 Open Source Development Labs
 | |
|  */
 | |
| 
 | |
| #ifndef _KREF_H_
 | |
| #define _KREF_H_
 | |
| 
 | |
| #include <linux/spinlock.h>
 | |
| #include <linux/refcount.h>
 | |
| 
 | |
| struct kref {
 | |
| 	refcount_t refcount;
 | |
| };
 | |
| 
 | |
| #define KREF_INIT(n)	{ .refcount = REFCOUNT_INIT(n), }
 | |
| 
 | |
| /**
 | |
|  * kref_init - initialize object.
 | |
|  * @kref: object in question.
 | |
|  */
 | |
| static inline void kref_init(struct kref *kref)
 | |
| {
 | |
| 	refcount_set(&kref->refcount, 1);
 | |
| }
 | |
| 
 | |
| static inline unsigned int kref_read(const struct kref *kref)
 | |
| {
 | |
| 	return refcount_read(&kref->refcount);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * kref_get - increment refcount for object.
 | |
|  * @kref: object.
 | |
|  */
 | |
| static inline void kref_get(struct kref *kref)
 | |
| {
 | |
| 	refcount_inc(&kref->refcount);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * kref_put - decrement refcount for object.
 | |
|  * @kref: object.
 | |
|  * @release: pointer to the function that will clean up the object when the
 | |
|  *	     last reference to the object is released.
 | |
|  *	     This pointer is required, and it is not acceptable to pass kfree
 | |
|  *	     in as this function.
 | |
|  *
 | |
|  * Decrement the refcount, and if 0, call release().
 | |
|  * Return 1 if the object was removed, otherwise return 0.  Beware, if this
 | |
|  * function returns 0, you still can not count on the kref from remaining in
 | |
|  * memory.  Only use the return value if you want to see if the kref is now
 | |
|  * gone, not present.
 | |
|  */
 | |
| static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref))
 | |
| {
 | |
| 	if (refcount_dec_and_test(&kref->refcount)) {
 | |
| 		release(kref);
 | |
| 		return 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static inline int kref_put_mutex(struct kref *kref,
 | |
| 				 void (*release)(struct kref *kref),
 | |
| 				 struct mutex *lock)
 | |
| {
 | |
| 	if (refcount_dec_and_mutex_lock(&kref->refcount, lock)) {
 | |
| 		release(kref);
 | |
| 		return 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| static inline int kref_put_lock(struct kref *kref,
 | |
| 				void (*release)(struct kref *kref),
 | |
| 				spinlock_t *lock)
 | |
| {
 | |
| 	if (refcount_dec_and_lock(&kref->refcount, lock)) {
 | |
| 		release(kref);
 | |
| 		return 1;
 | |
| 	}
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * kref_get_unless_zero - Increment refcount for object unless it is zero.
 | |
|  * @kref: object.
 | |
|  *
 | |
|  * Return non-zero if the increment succeeded. Otherwise return 0.
 | |
|  *
 | |
|  * This function is intended to simplify locking around refcounting for
 | |
|  * objects that can be looked up from a lookup structure, and which are
 | |
|  * removed from that lookup structure in the object destructor.
 | |
|  * Operations on such objects require at least a read lock around
 | |
|  * lookup + kref_get, and a write lock around kref_put + remove from lookup
 | |
|  * structure. Furthermore, RCU implementations become extremely tricky.
 | |
|  * With a lookup followed by a kref_get_unless_zero *with return value check*
 | |
|  * locking in the kref_put path can be deferred to the actual removal from
 | |
|  * the lookup structure and RCU lookups become trivial.
 | |
|  */
 | |
| static inline int __must_check kref_get_unless_zero(struct kref *kref)
 | |
| {
 | |
| 	return refcount_inc_not_zero(&kref->refcount);
 | |
| }
 | |
| #endif /* _KREF_H_ */
 |