Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Feb 2025 20:48:07 GMT
From:      =?utf-8?Q?Jean-S=C3=A9bastien?= =?utf-8?Q?P=C3=A9dron?= <dumbbell@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 05dfaadde4ae - main - linuxkpi: Add `shrinker_alloc()` and `shrinker_free()`
Message-ID:  <202502192048.51JKm7Ts072124@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by dumbbell:

URL: https://cgit.FreeBSD.org/src/commit/?id=05dfaadde4ae0f5d823836d5d849e3ba5ebdbf17

commit 05dfaadde4ae0f5d823836d5d849e3ba5ebdbf17
Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2024-12-22 18:10:23 +0000
Commit:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2025-02-19 20:39:46 +0000

    linuxkpi: Add `shrinker_alloc()` and `shrinker_free()`
    
    They are used by the DRM drivers in Linux 6.7.
    
    Bump `FreeBSD_version` because external drivers that use `struct
    shrinker` will have to be recompiled.
    
    Reviewed by:    bz
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D48747
---
 .../linuxkpi/common/include/linux/shrinker.h       | 16 +++++++++++++
 sys/compat/linuxkpi/common/src/linux_shrinker.c    | 28 ++++++++++++++++++++++
 sys/sys/param.h                                    |  2 +-
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/shrinker.h b/sys/compat/linuxkpi/common/include/linux/shrinker.h
index 88cbca2dcf60..eb95dafb83ce 100644
--- a/sys/compat/linuxkpi/common/include/linux/shrinker.h
+++ b/sys/compat/linuxkpi/common/include/linux/shrinker.h
@@ -27,6 +27,8 @@
 #define	_LINUXKPI_LINUX_SHRINKER_H_
 
 #include <sys/queue.h>
+
+#include <linux/bitops.h>
 #include <linux/gfp.h>
 
 struct shrink_control {
@@ -39,6 +41,7 @@ struct shrinker {
 	unsigned long		(*count_objects)(struct shrinker *, struct shrink_control *);
 	unsigned long		(*scan_objects)(struct shrinker *, struct shrink_control *);
 	int			seeks;
+	unsigned int		flags;
 	void *			private_data;
 	long			batch;
 	TAILQ_ENTRY(shrinker)	next;
@@ -48,10 +51,23 @@ struct shrinker {
 
 #define	DEFAULT_SEEKS	2
 
+#define SHRINKER_REGISTERED	BIT(0)
+#define SHRINKER_ALLOCATED	BIT(1)
+
+struct shrinker *linuxkpi_shrinker_alloc(
+    unsigned int flags, const char *fmt, ...);
 int	linuxkpi_register_shrinker(struct shrinker *s);
 void	linuxkpi_unregister_shrinker(struct shrinker *s);
+void	linuxkpi_shrinker_free(struct shrinker *shrinker);
 void	linuxkpi_synchronize_shrinkers(void);
 
+#define	shrinker_alloc(flags, fmt, ...) \
+    linuxkpi_shrinker_alloc(flags, fmt __VA_OPT__(,) __VA_ARGS__)
+#define	shrinker_register(shrinker) \
+    linuxkpi_register_shrinker(shrinker)
+#define	shrinker_free(shrinker) \
+    linuxkpi_shrinker_free(shrinker)
+
 #if defined(LINUXKPI_VERSION) && LINUXKPI_VERSION >= 60000
 #define	register_shrinker(s, ...)	linuxkpi_register_shrinker(s)
 #else
diff --git a/sys/compat/linuxkpi/common/src/linux_shrinker.c b/sys/compat/linuxkpi/common/src/linux_shrinker.c
index 52a0472348d8..18200fa0bc01 100644
--- a/sys/compat/linuxkpi/common/src/linux_shrinker.c
+++ b/sys/compat/linuxkpi/common/src/linux_shrinker.c
@@ -32,10 +32,26 @@
 
 #include <linux/compat.h>
 #include <linux/shrinker.h>
+#include <linux/slab.h>
 
 TAILQ_HEAD(, shrinker) lkpi_shrinkers = TAILQ_HEAD_INITIALIZER(lkpi_shrinkers);
 static struct sx sx_shrinker;
 
+struct shrinker *
+linuxkpi_shrinker_alloc(unsigned int flags, const char *fmt, ...)
+{
+	struct shrinker *shrinker;
+
+	shrinker = kzalloc(sizeof(*shrinker), GFP_KERNEL);
+	if (shrinker == NULL)
+		return (NULL);
+
+	shrinker->flags = flags | SHRINKER_ALLOCATED;
+	shrinker->seeks = DEFAULT_SEEKS;
+
+	return (shrinker);
+}
+
 int
 linuxkpi_register_shrinker(struct shrinker *s)
 {
@@ -44,6 +60,7 @@ linuxkpi_register_shrinker(struct shrinker *s)
 	KASSERT(s->count_objects != NULL, ("NULL shrinker"));
 	KASSERT(s->scan_objects != NULL, ("NULL shrinker"));
 	sx_xlock(&sx_shrinker);
+	s->flags |= SHRINKER_REGISTERED;
 	TAILQ_INSERT_TAIL(&lkpi_shrinkers, s, next);
 	sx_xunlock(&sx_shrinker);
 	return (0);
@@ -55,9 +72,20 @@ linuxkpi_unregister_shrinker(struct shrinker *s)
 
 	sx_xlock(&sx_shrinker);
 	TAILQ_REMOVE(&lkpi_shrinkers, s, next);
+	s->flags &= ~SHRINKER_REGISTERED;
 	sx_xunlock(&sx_shrinker);
 }
 
+void
+linuxkpi_shrinker_free(struct shrinker *shrinker)
+{
+
+	if (shrinker->flags & SHRINKER_REGISTERED)
+		unregister_shrinker(shrinker);
+
+	kfree(shrinker);
+}
+
 void
 linuxkpi_synchronize_shrinkers(void)
 {
diff --git a/sys/sys/param.h b/sys/sys/param.h
index d3344c41562a..6645130e2614 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -73,7 +73,7 @@
  * cannot include sys/param.h and should only be updated here.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1500032
+#define __FreeBSD_version 1500033
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202502192048.51JKm7Ts072124>