Re: [PATCH v3 03/57] locking: Introduce __cleanup() based infrastructure

From: Peter Zijlstra
Date: Tue Jun 13 2023 - 06:55:49 EST


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)