git: 7710a16e9847 - stable/15 - linuxkpi: Define `DEFINE_CLASS()` and `CLASS()`

From: Vladimir Kondratyev <wulf_at_FreeBSD.org>
Date: Tue, 22 Sep 2026 15:48:50 UTC
The branch stable/15 has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=7710a16e9847149882fd87769540d669592d4278

commit 7710a16e9847149882fd87769540d669592d4278
Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2026-06-12 17:56:35 +0000
Commit:     Vladimir Kondratyev <wulf@FreeBSD.org>
CommitDate: 2026-09-22 15:47:03 +0000

    linuxkpi: Define `DEFINE_CLASS()` and `CLASS()`
    
    `DEFINE_CLASS()` is in fact named `LINUXKPI_DEFINE_CLASS()` because it
    conflicts with `DEFINE_CLASS()` defined in <sys/kobj.h>.
    
    This macro defines a type and a pair of constructor/destructor
    functions.
    
    They are to be used by `CLASS()`: this one declares a variable,
    initialise it with the constructor and set the `__cleanup()` attribute
    to call the destructor once the variable goes out of scope.
    
    The DRM drivers generic code started to use `CLASS()` in Linux 6.13. It
    requires the `fd` class to be defined in <linux/file.h>.
    
    Reviewed by:    bz
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D57583
    
    (cherry picked from commit f2a2e02ae54b836d1e23648756a050406f65111e)
---
 sys/compat/linuxkpi/common/include/linux/cleanup.h | 26 ++++++++++++++++++++++
 sys/compat/linuxkpi/common/include/linux/file.h    |  2 ++
 2 files changed, 28 insertions(+)

diff --git a/sys/compat/linuxkpi/common/include/linux/cleanup.h b/sys/compat/linuxkpi/common/include/linux/cleanup.h
index fb21a81f121b..815cdc37a956 100644
--- a/sys/compat/linuxkpi/common/include/linux/cleanup.h
+++ b/sys/compat/linuxkpi/common/include/linux/cleanup.h
@@ -20,6 +20,32 @@
     CLEANUP_NAME(_n, _t) _x __cleanup(CLEANUP_NAME(_n, _destroy)) =	\
 	CLEANUP_NAME(_n, _create)
 
+/*
+ * On Linux, the following macro is called `DEFINE_CLASS()`. However it
+ * conflicts with FreeBSD's macro defined in <sys/kobj.h>.
+ *
+ * Note: "_T" are special as they are exposed into common code for
+ * statements.  Extra care should be taken when changing the code.
+ */
+#define	LINUXKPI_DEFINE_CLASS(_name, _type, _exit, _init, _init_args...)\
+    typedef _type class_##_name##_t;					\
+									\
+    static inline _type class_##_name##_constructor(_init_args)		\
+    {									\
+	_type v = _init;						\
+	return (v);							\
+    }									\
+									\
+    static inline void class_##_name##_destructor(_type *p)		\
+    {									\
+	_type _T = *p;							\
+	_exit;								\
+    }
+
+#define	CLASS(_name, _var)						\
+    class_##_name##_t _var __cleanup(class_##_name##_destructor) =	\
+	class_##_name##_constructor
+
 /*
  * Note: "_T" are special as they are exposed into common code for
  * statements.  Extra care should be taken when changing the code.
diff --git a/sys/compat/linuxkpi/common/include/linux/file.h b/sys/compat/linuxkpi/common/include/linux/file.h
index 4d8f8fba7fab..8a589bd2021b 100644
--- a/sys/compat/linuxkpi/common/include/linux/file.h
+++ b/sys/compat/linuxkpi/common/include/linux/file.h
@@ -184,6 +184,8 @@ static inline struct fd fdget(unsigned int fd)
 	return (struct fd){f};
 }
 
+LINUXKPI_DEFINE_CLASS(fd, struct fd, fdput(_T), fdget(fd), int fd)
+
 #define	fd_file(fd)	((fd).linux_file)
 
 #define	file		linux_file