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 <dumbb...@freebsd.org>
AuthorDate: 2024-12-22 18:10:23 +0000
Commit:     Jean-Sébastien Pédron <dumbb...@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,

Reply via email to