brintos

brintos / linux-shallow public Read only

0
0
Text · 12.1 KiB · 038b2d5 Raw
390 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _LINUX_CLEANUP_H3#define _LINUX_CLEANUP_H4 5#include <linux/compiler.h>6 7/**8 * DOC: scope-based cleanup helpers9 *10 * The "goto error" pattern is notorious for introducing subtle resource11 * leaks. It is tedious and error prone to add new resource acquisition12 * constraints into code paths that already have several unwind13 * conditions. The "cleanup" helpers enable the compiler to help with14 * this tedium and can aid in maintaining LIFO (last in first out)15 * unwind ordering to avoid unintentional leaks.16 *17 * As drivers make up the majority of the kernel code base, here is an18 * example of using these helpers to clean up PCI drivers. The target of19 * the cleanups are occasions where a goto is used to unwind a device20 * reference (pci_dev_put()), or unlock the device (pci_dev_unlock())21 * before returning.22 *23 * The DEFINE_FREE() macro can arrange for PCI device references to be24 * dropped when the associated variable goes out of scope::25 *26 *	DEFINE_FREE(pci_dev_put, struct pci_dev *, if (_T) pci_dev_put(_T))27 *	...28 *	struct pci_dev *dev __free(pci_dev_put) =29 *		pci_get_slot(parent, PCI_DEVFN(0, 0));30 *31 * The above will automatically call pci_dev_put() if @dev is non-NULL32 * when @dev goes out of scope (automatic variable scope). If a function33 * wants to invoke pci_dev_put() on error, but return @dev (i.e. without34 * freeing it) on success, it can do::35 *36 *	return no_free_ptr(dev);37 *38 * ...or::39 *40 *	return_ptr(dev);41 *42 * The DEFINE_GUARD() macro can arrange for the PCI device lock to be43 * dropped when the scope where guard() is invoked ends::44 *45 *	DEFINE_GUARD(pci_dev, struct pci_dev *, pci_dev_lock(_T), pci_dev_unlock(_T))46 *	...47 *	guard(pci_dev)(dev);48 *49 * The lifetime of the lock obtained by the guard() helper follows the50 * scope of automatic variable declaration. Take the following example::51 *52 *	func(...)53 *	{54 *		if (...) {55 *			...56 *			guard(pci_dev)(dev); // pci_dev_lock() invoked here57 *			...58 *		} // <- implied pci_dev_unlock() triggered here59 *	}60 *61 * Observe the lock is held for the remainder of the "if ()" block not62 * the remainder of "func()".63 *64 * Now, when a function uses both __free() and guard(), or multiple65 * instances of __free(), the LIFO order of variable definition order66 * matters. GCC documentation says:67 *68 * "When multiple variables in the same scope have cleanup attributes,69 * at exit from the scope their associated cleanup functions are run in70 * reverse order of definition (last defined, first cleanup)."71 *72 * When the unwind order matters it requires that variables be defined73 * mid-function scope rather than at the top of the file.  Take the74 * following example and notice the bug highlighted by "!!"::75 *76 *	LIST_HEAD(list);77 *	DEFINE_MUTEX(lock);78 *79 *	struct object {80 *	        struct list_head node;81 *	};82 *83 *	static struct object *alloc_add(void)84 *	{85 *	        struct object *obj;86 *87 *	        lockdep_assert_held(&lock);88 *	        obj = kzalloc(sizeof(*obj), GFP_KERNEL);89 *	        if (obj) {90 *	                LIST_HEAD_INIT(&obj->node);91 *	                list_add(obj->node, &list):92 *	        }93 *	        return obj;94 *	}95 *96 *	static void remove_free(struct object *obj)97 *	{98 *	        lockdep_assert_held(&lock);99 *	        list_del(&obj->node);100 *	        kfree(obj);101 *	}102 *103 *	DEFINE_FREE(remove_free, struct object *, if (_T) remove_free(_T))104 *	static int init(void)105 *	{106 *	        struct object *obj __free(remove_free) = NULL;107 *	        int err;108 *109 *	        guard(mutex)(&lock);110 *	        obj = alloc_add();111 *112 *	        if (!obj)113 *	                return -ENOMEM;114 *115 *	        err = other_init(obj);116 *	        if (err)117 *	                return err; // remove_free() called without the lock!!118 *119 *	        no_free_ptr(obj);120 *	        return 0;121 *	}122 *123 * That bug is fixed by changing init() to call guard() and define +124 * initialize @obj in this order::125 *126 *	guard(mutex)(&lock);127 *	struct object *obj __free(remove_free) = alloc_add();128 *129 * Given that the "__free(...) = NULL" pattern for variables defined at130 * the top of the function poses this potential interdependency problem131 * the recommendation is to always define and assign variables in one132 * statement and not group variable definitions at the top of the133 * function when __free() is used.134 *135 * Lastly, given that the benefit of cleanup helpers is removal of136 * "goto", and that the "goto" statement can jump between scopes, the137 * expectation is that usage of "goto" and cleanup helpers is never138 * mixed in the same function. I.e. for a given routine, convert all139 * resources that need a "goto" cleanup to scope-based cleanup, or140 * convert none of them.141 */142 143/*144 * DEFINE_FREE(name, type, free):145 *	simple helper macro that defines the required wrapper for a __free()146 *	based cleanup function. @free is an expression using '_T' to access the147 *	variable. @free should typically include a NULL test before calling a148 *	function, see the example below.149 *150 * __free(name):151 *	variable attribute to add a scoped based cleanup to the variable.152 *153 * no_free_ptr(var):154 *	like a non-atomic xchg(var, NULL), such that the cleanup function will155 *	be inhibited -- provided it sanely deals with a NULL value.156 *157 *	NOTE: this has __must_check semantics so that it is harder to accidentally158 *	leak the resource.159 *160 * return_ptr(p):161 *	returns p while inhibiting the __free().162 *163 * Ex.164 *165 * DEFINE_FREE(kfree, void *, if (_T) kfree(_T))166 *167 * void *alloc_obj(...)168 * {169 *	struct obj *p __free(kfree) = kmalloc(...);170 *	if (!p)171 *		return NULL;172 *173 *	if (!init_obj(p))174 *		return NULL;175 *176 *	return_ptr(p);177 * }178 *179 * NOTE: the DEFINE_FREE()'s @free expression includes a NULL test even though180 * kfree() is fine to be called with a NULL value. This is on purpose. This way181 * the compiler sees the end of our alloc_obj() function as:182 *183 *	tmp = p;184 *	p = NULL;185 *	if (p)186 *		kfree(p);187 *	return tmp;188 *189 * And through the magic of value-propagation and dead-code-elimination, it190 * eliminates the actual cleanup call and compiles into:191 *192 *	return p;193 *194 * Without the NULL test it turns into a mess and the compiler can't help us.195 */196 197#define DEFINE_FREE(_name, _type, _free) \198	static inline void __free_##_name(void *p) { _type _T = *(_type *)p; _free; }199 200#define __free(_name)	__cleanup(__free_##_name)201 202#define __get_and_null(p, nullvalue)   \203	({                                  \204		__auto_type __ptr = &(p);   \205		__auto_type __val = *__ptr; \206		*__ptr = nullvalue;         \207		__val;                      \208	})209 210static inline __must_check211const volatile void * __must_check_fn(const volatile void *val)212{ return val; }213 214#define no_free_ptr(p) \215	((typeof(p)) __must_check_fn(__get_and_null(p, NULL)))216 217#define return_ptr(p)	return no_free_ptr(p)218 219 220/*221 * DEFINE_CLASS(name, type, exit, init, init_args...):222 *	helper to define the destructor and constructor for a type.223 *	@exit is an expression using '_T' -- similar to FREE above.224 *	@init is an expression in @init_args resulting in @type225 *226 * EXTEND_CLASS(name, ext, init, init_args...):227 *	extends class @name to @name@ext with the new constructor228 *229 * CLASS(name, var)(args...):230 *	declare the variable @var as an instance of the named class231 *232 * Ex.233 *234 * DEFINE_CLASS(fdget, struct fd, fdput(_T), fdget(fd), int fd)235 *236 *	CLASS(fdget, f)(fd);237 *	if (!fd_file(f))238 *		return -EBADF;239 *240 *	// use 'f' without concern241 */242 243#define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...)		\244typedef _type class_##_name##_t;					\245static inline void class_##_name##_destructor(_type *p)			\246{ _type _T = *p; _exit; }						\247static inline _type class_##_name##_constructor(_init_args)		\248{ _type t = _init; return t; }249 250#define EXTEND_CLASS(_name, ext, _init, _init_args...)			\251typedef class_##_name##_t class_##_name##ext##_t;			\252static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\253{ class_##_name##_destructor(p); }					\254static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \255{ class_##_name##_t t = _init; return t; }256 257#define CLASS(_name, var)						\258	class_##_name##_t var __cleanup(class_##_name##_destructor) =	\259		class_##_name##_constructor260 261 262/*263 * DEFINE_GUARD(name, type, lock, unlock):264 *	trivial wrapper around DEFINE_CLASS() above specifically265 *	for locks.266 *267 * DEFINE_GUARD_COND(name, ext, condlock)268 *	wrapper around EXTEND_CLASS above to add conditional lock269 *	variants to a base class, eg. mutex_trylock() or270 *	mutex_lock_interruptible().271 *272 * guard(name):273 *	an anonymous instance of the (guard) class, not recommended for274 *	conditional locks.275 *276 * scoped_guard (name, args...) { }:277 *	similar to CLASS(name, scope)(args), except the variable (with the278 *	explicit name 'scope') is declard in a for-loop such that its scope is279 *	bound to the next (compound) statement.280 *281 *	for conditional locks the loop body is skipped when the lock is not282 *	acquired.283 *284 * scoped_cond_guard (name, fail, args...) { }:285 *      similar to scoped_guard(), except it does fail when the lock286 *      acquire fails.287 *288 */289 290#define DEFINE_GUARD(_name, _type, _lock, _unlock) \291	DEFINE_CLASS(_name, _type, if (_T) { _unlock; }, ({ _lock; _T; }), _type _T); \292	static inline void * class_##_name##_lock_ptr(class_##_name##_t *_T) \293	{ return *_T; }294 295#define DEFINE_GUARD_COND(_name, _ext, _condlock) \296	EXTEND_CLASS(_name, _ext, \297		     ({ void *_t = _T; if (_T && !(_condlock)) _t = NULL; _t; }), \298		     class_##_name##_t _T) \299	static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \300	{ return class_##_name##_lock_ptr(_T); }301 302#define guard(_name) \303	CLASS(_name, __UNIQUE_ID(guard))304 305#define __guard_ptr(_name) class_##_name##_lock_ptr306 307#define scoped_guard(_name, args...)					\308	for (CLASS(_name, scope)(args),					\309	     *done = NULL; __guard_ptr(_name)(&scope) && !done; done = (void *)1)310 311#define scoped_cond_guard(_name, _fail, args...) \312	for (CLASS(_name, scope)(args), \313	     *done = NULL; !done; done = (void *)1) \314		if (!__guard_ptr(_name)(&scope)) _fail; \315		else316 317/*318 * Additional helper macros for generating lock guards with types, either for319 * locks that don't have a native type (eg. RCU, preempt) or those that need a320 * 'fat' pointer (eg. spin_lock_irqsave).321 *322 * DEFINE_LOCK_GUARD_0(name, lock, unlock, ...)323 * DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...)324 * DEFINE_LOCK_GUARD_1_COND(name, ext, condlock)325 *326 * will result in the following type:327 *328 *   typedef struct {329 *	type *lock;		// 'type := void' for the _0 variant330 *	__VA_ARGS__;331 *   } class_##name##_t;332 *333 * As above, both _lock and _unlock are statements, except this time '_T' will334 * be a pointer to the above struct.335 */336 337#define __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, ...)		\338typedef struct {							\339	_type *lock;							\340	__VA_ARGS__;							\341} class_##_name##_t;							\342									\343static inline void class_##_name##_destructor(class_##_name##_t *_T)	\344{									\345	if (_T->lock) { _unlock; }					\346}									\347									\348static inline void *class_##_name##_lock_ptr(class_##_name##_t *_T)	\349{									\350	return _T->lock;						\351}352 353 354#define __DEFINE_LOCK_GUARD_1(_name, _type, _lock)			\355static inline class_##_name##_t class_##_name##_constructor(_type *l)	\356{									\357	class_##_name##_t _t = { .lock = l }, *_T = &_t;		\358	_lock;								\359	return _t;							\360}361 362#define __DEFINE_LOCK_GUARD_0(_name, _lock)				\363static inline class_##_name##_t class_##_name##_constructor(void)	\364{									\365	class_##_name##_t _t = { .lock = (void*)1 },			\366			 *_T __maybe_unused = &_t;			\367	_lock;								\368	return _t;							\369}370 371#define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...)		\372__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__)		\373__DEFINE_LOCK_GUARD_1(_name, _type, _lock)374 375#define DEFINE_LOCK_GUARD_0(_name, _lock, _unlock, ...)			\376__DEFINE_UNLOCK_GUARD(_name, void, _unlock, __VA_ARGS__)		\377__DEFINE_LOCK_GUARD_0(_name, _lock)378 379#define DEFINE_LOCK_GUARD_1_COND(_name, _ext, _condlock)		\380	EXTEND_CLASS(_name, _ext,					\381		     ({ class_##_name##_t _t = { .lock = l }, *_T = &_t;\382		        if (_T->lock && !(_condlock)) _T->lock = NULL;	\383			_t; }),						\384		     typeof_member(class_##_name##_t, lock) l)		\385	static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \386	{ return class_##_name##_lock_ptr(_T); }387 388 389#endif /* _LINUX_CLEANUP_H */390