lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250616111436.665171-1-jemmywong512@gmail.com>
Date: Mon, 16 Jun 2025 19:14:36 +0800
From: Jemmy Wong <jemmywong512@...il.com>
To: Peter Zijlstra <peterz@...radead.org>,
	Thomas Gleixner <tglx@...utronix.de>,
	Dan Williams <dan.j.williams@...el.com>,
	Christian Brauner <brauner@...nel.org>,
	Jonathan Cameron <Jonathan.Cameron@...wei.com>,
	Al Viro <viro@...iv.linux.org.uk>,
	Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>,
	David Lechner <dlechner@...libre.com>,
	Przemek Kitszel <przemyslaw.kitszel@...el.com>,
	Jemmy Wong <jemmywong512@...il.com>,
	Ingo Molnar <mingo@...nel.org>,
	linux-kernel@...r.kernel.org
Subject: [PATCH v0] [RFC] cleanup: Unify DEFINE_LOCK_GUARD_0 and DEFINE_LOCK_GUARD_1

Hi,

This patch consolidates the DEFINE_LOCK_GUARD_0 and DEFINE_LOCK_GUARD_1
macros into a single, unified 'DEFINE_LOCK_GUARD' macro to provide
a consistent and simplified API for lock guard definitions.

API changes:
>From    DEFINE_LOCK_GUARD_0(name, lock, unlock, ...)
to      DEFINE_LOCK_GUARD(name, *void*, lock, unlock, ...)

>From    DEFINE_LOCK_GUARD_1(name, type, lock, unlock, ...)
to      DEFINE_LOCK_GUARD(name, type, lock, unlock, ...)

>From    CLASS(name, var)(args...)
to      CLASS(name, var, args...)

>From    guard(name)(args)
to      guard(name, args)

No change:
scoped_guard(name, args...)
scoped_cond_guard(name, fail, args...)

---

Deailted changes:

- DEFINE_CLASS(_name, _type, _exit, _init, _init_args...)
The void type for _init_args is not required when the constructor takes no arguments,
as an int argc is implicitly inserted as the first argument. (int argc, void) is an error.

This patch includes only the core changes.
Follow-up patches will be submitted once the approach is accepted.

Best,
Jemmy

---
 include/linux/cleanup.h | 50 +++++++++++++++++++++++++++++++----------
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h
index 7093e1d08af0..2a4c3a96d37b 100644
--- a/include/linux/cleanup.h
+++ b/include/linux/cleanup.h
@@ -2,6 +2,7 @@
 #ifndef _LINUX_CLEANUP_H
 #define _LINUX_CLEANUP_H

+#include <linux/stdarg.h>
 #include <linux/compiler.h>

 /**
@@ -259,24 +260,28 @@ const volatile void * __must_check_fn(const volatile void *val)
  *	// use 'f' without concern
  */

+#define __ARGC(_9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...)		N
+#define ARGC(...) __ARGC(9, ##__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
 #define DEFINE_CLASS(_name, _type, _exit, _init, _init_args...)		\
 typedef _type class_##_name##_t;					\
 static inline void class_##_name##_destructor(_type *p)			\
 { _type _T = *p; _exit; }						\
-static inline _type class_##_name##_constructor(_init_args)		\
+static inline _type class_##_name##_constructor(int argc, ##_init_args)	\
 { _type t = _init; return t; }

 #define EXTEND_CLASS(_name, ext, _init, _init_args...)			\
 typedef class_##_name##_t class_##_name##ext##_t;			\
 static inline void class_##_name##ext##_destructor(class_##_name##_t *p)\
 { class_##_name##_destructor(p); }					\
-static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \
+static inline class_##_name##_t class_##_name##ext##_constructor(int argc, ##_init_args) \
 { class_##_name##_t t = _init; return t; }

-#define CLASS(_name, var)						\
+#define __CLASS(_name, var, argc, args...)						\
 	class_##_name##_t var __cleanup(class_##_name##_destructor) =	\
-		class_##_name##_constructor
+		class_##_name##_constructor(argc, ##args)

+#define CLASS(_name, var, args...) __CLASS(_name, var, ARGC(args), ##args)

 /*
  * DEFINE_GUARD(name, type, lock, unlock):
@@ -334,8 +339,8 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
 	static inline void * class_##_name##_ext##_lock_ptr(class_##_name##_t *_T) \
 	{ return class_##_name##_lock_ptr(_T); }

-#define guard(_name) \
-	CLASS(_name, __UNIQUE_ID(guard))
+#define guard(_name, args...) \
+	__CLASS(_name, __UNIQUE_ID(guard), ARGC(args), ##args)

 #define __guard_ptr(_name) class_##_name##_lock_ptr
 #define __is_cond_ptr(_name) class_##_name##_is_conditional
@@ -349,8 +354,8 @@ static __maybe_unused const bool class_##_name##_is_conditional = _is_cond
  * It is needed because the other part - "__guard_ptr(_name)(&scope)" - is too
  * hard to deduce (even if could be proven true for unconditional locks).
  */
-#define __scoped_guard(_name, _label, args...)				\
-	for (CLASS(_name, scope)(args);					\
+#define __scoped_guard(_name, _label, argc, args...)			\
+	for (__CLASS(_name, scope, argc, ##args);			\
 	     __guard_ptr(_name)(&scope) || !__is_cond_ptr(_name);	\
 	     ({ goto _label; }))					\
 		if (0) {						\
@@ -359,10 +364,10 @@ _label:									\
 		} else

 #define scoped_guard(_name, args...)	\
-	__scoped_guard(_name, __UNIQUE_ID(label), args)
+	__scoped_guard(_name, __UNIQUE_ID(label), ARGC(args), ##args)

-#define __scoped_cond_guard(_name, _fail, _label, args...)		\
-	for (CLASS(_name, scope)(args); true; ({ goto _label; }))	\
+#define __scoped_cond_guard(_name, _fail, _label, argc, args...)	\
+	for (__CLASS(_name, scope, argc, ##args); true; ({ goto _label; }))	\
 		if (!__guard_ptr(_name)(&scope)) {			\
 			BUILD_BUG_ON(!__is_cond_ptr(_name));		\
 			_fail;						\
@@ -371,7 +376,7 @@ _label:									\
 		} else

 #define scoped_cond_guard(_name, _fail, args...)	\
-	__scoped_cond_guard(_name, _fail, __UNIQUE_ID(label), args)
+	__scoped_cond_guard(_name, _fail, __UNIQUE_ID(label), ARGC(args), ##args)

 /*
  * Additional helper macros for generating lock guards with types, either for
@@ -423,6 +428,27 @@ static inline class_##_name##_t class_##_name##_constructor(void)	\
 	return _t;							\
 }

+#define __DEFINE_LOCK_GUARD(_name, _type, _lock)			\
+	static inline class_##_name##_t class_##_name##_constructor_x(void *l) { \
+		class_##_name##_t _t = { .lock = (_type *)l },		\
+		*_T __maybe_unused = &_t;				\
+		_lock;							\
+		return _t;						\
+	}								\
+	static inline class_##_name##_t class_##_name##_constructor(int argc, ...) { \
+		BUILD_BUG_ON(argc > 1);					\
+		va_list args;  						\
+		va_start(args, argc);                              	\
+		void *arg = argc ? va_arg(args, _type *) : (void *)8;	\
+		va_end(args);                                       	\
+		return class_##_name##_constructor_x(arg);		\
+	}
+
+#define DEFINE_LOCK_GUARD(_name, _type, _lock, _unlock, ...)		\
+	__DEFINE_CLASS_IS_CONDITIONAL(_name, false);			\
+	__DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__)	\
+	__DEFINE_LOCK_GUARD(_name, _type, _lock)
+
 #define DEFINE_LOCK_GUARD_1(_name, _type, _lock, _unlock, ...)		\
 __DEFINE_CLASS_IS_CONDITIONAL(_name, false);				\
 __DEFINE_UNLOCK_GUARD(_name, _type, _unlock, __VA_ARGS__)		\
--
2.43.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ