On Mon, Jun 12, 2023 at 11:07:16AM +0200, Peter Zijlstra wrote: > --- /dev/null > +++ b/include/linux/cleanup.h > @@ -0,0 +1,167 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __LINUX_GUARDS_H > +#define __LINUX_GUARDS_H > + > +#include <linux/compiler.h> > + > +/* > + * DEFINE_FREE(name, type, free): > + * simple helper macro that defines the required wrapper for a __free() > + * based cleanup function. @free is an expression using '_T' to access > + * the variable. > + * > + * __free(name): > + * variable attribute to add a scoped based cleanup to the variable. > + * no_free_ptr(var): like a non-atomic xchg(var, NULL), such that the cleanup function will be inhibited -- provided it sanely deals with a NULL value. > + * return_ptr(p): > + * returns p while inhibiting the __free(). > + * > + * Ex. > + * > + * DEFINE_FREE(kfree, void *, if (_T) kfree(_T)) > + * > + * struct obj *p = kmalloc(...); That should obviously have been: struct obj *p __free(kfree) = kmalloc(...); > + * if (!p) > + * return NULL; > + * > + * if (!init_obj(p)) > + * return NULL; > + * > + * return_ptr(p); > + */ > + > +#define DEFINE_FREE(name, type, free) \ > + static inline void __free_##name(void *p) { type _T = *(type *)p; free; } > + > +#define __free(name) __cleanup(__free_##name) > + > +#define no_free_ptr(p) \ > + ({ __auto_type __ptr = (p); (p) = NULL; __ptr; }) > + > +#define return_ptr(p) return no_free_ptr(p)