Whamcloud - gitweb
LU-17392 build: compatibility updates for kernel 6.7 21/53621/17
authorShaun Tancheff <shaun.tancheff@hpe.com>
Thu, 29 Feb 2024 20:55:58 +0000 (03:55 +0700)
committerOleg Drokin <green@whamcloud.com>
Sat, 23 Mar 2024 15:45:58 +0000 (15:45 +0000)
Linux commit v6.6-rc4-53-gc42d50aefd17
  mm: shrinker: add infrastructure for dynamically allocating
      shrinker

Users of struct shrinker must dynamically allocate shrinker objects
to avoid run-time warnings.

Provide a wrapper for older kernels to alloc+register shinkers
and unregister+free.

Use get_group_info() and put_group_info() wrappers instead of
open coding the reference counting on group_info.usage

Signed-off-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Change-Id: Ie07bdb7fe3eb6060bd84f95f860f1b53d120a605
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53621
Tested-by: Maloo <maloo@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Jian Yu <yujian@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
lustre/autoconf/lustre-core.m4
lustre/include/lustre_compat.h
lustre/ldlm/ldlm_pool.c
lustre/obdclass/idmap.c
lustre/obdclass/lu_object.c
lustre/osc/osc_request.c
lustre/ptlrpc/sec_bulk.c

index 5912e83..5afeb19 100644 (file)
@@ -4363,6 +4363,29 @@ AC_DEFUN([LC_HAVE_INODE_GET_MTIME_SEC], [
 ]) # LC_HAVE_INODE_GET_MTIME_SEC
 
 #
+# LC_HAVE_SHRINKER_ALLOC
+#
+# Linux commit v6.6-rc4-53-gc42d50aefd17
+#   mm: shrinker: add infrastructure for dynamically allocating shrinker
+#
+AC_DEFUN([LC_SRC_HAVE_SHRINKER_ALLOC], [
+       LB2_LINUX_TEST_SRC([shrinker_alloc_exists], [
+               #include <linux/shrinker.h>
+       ],[
+               struct shrinker *shrink __attribute__ ((unused));
+
+               shrink = shrinker_alloc(0, "%s", "whoami");
+       ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_SHRINKER_ALLOC], [
+       LB2_MSG_LINUX_TEST_RESULT([if 'shrinker_alloc()' exists],
+       [shrinker_alloc_exists], [
+               AC_DEFINE(HAVE_SHRINKER_ALLOC, 1,
+                       ['shrinker_alloc()' exists])
+       ])
+]) # LC_HAVE_SHRINKER_ALLOC
+
+#
 # LC_PROG_LINUX
 #
 # Lustre linux kernel checks
@@ -4644,6 +4667,7 @@ AC_DEFUN([LC_PROG_LINUX_SRC], [
 
        # 6.7
        LC_SRC_HAVE_INODE_GET_MTIME_SEC
+       LC_SRC_HAVE_SHRINKER_ALLOC
 
        # kernel patch to extend integrity interface
        LC_SRC_BIO_INTEGRITY_PREP_FN
@@ -4947,6 +4971,7 @@ AC_DEFUN([LC_PROG_LINUX_RESULTS], [
 
        # 6.7
        LC_HAVE_INODE_GET_MTIME_SEC
+       LC_HAVE_SHRINKER_ALLOC
 
        # kernel patch to extend integrity interface
        LC_BIO_INTEGRITY_PREP_FN
index 8e36f76..002ad7a 100644 (file)
@@ -644,12 +644,85 @@ static inline bool is_root_inode(struct inode *inode)
 #define migrate_folio  migratepage
 #endif
 
-#ifdef HAVE_REGISTER_SHRINKER_FORMAT_NAMED
-#define register_shrinker(_s) register_shrinker((_s), "%ps", (_s))
-#elif !defined(HAVE_REGISTER_SHRINKER_RET)
-#define register_shrinker(_s) (register_shrinker(_s), 0)
+struct ll_shrinker_ops {
+#ifdef HAVE_SHRINKER_COUNT
+       unsigned long (*count_objects)(struct shrinker *,
+                                      struct shrink_control *sc);
+       unsigned long (*scan_objects)(struct shrinker *,
+                                     struct shrink_control *sc);
+#else
+       int (*shrink)(struct shrinker *, struct shrink_control *sc);
+#endif
+       int seeks;      /* seeks to recreate an obj */
+};
+
+#ifndef HAVE_SHRINKER_ALLOC
+static inline void shrinker_free(struct shrinker *shrinker)
+{
+       unregister_shrinker(shrinker);
+       OBD_FREE_PTR(shrinker);
+}
 #endif
 
+/* allocate and register a shrinker, return should be checked with IS_ERR() */
+static inline struct shrinker *
+ll_shrinker_create(struct ll_shrinker_ops *ops, unsigned int flags,
+                  const char *fmt, ...)
+{
+       struct shrinker *shrinker;
+       int rc = 0;
+
+#if defined(HAVE_REGISTER_SHRINKER_FORMAT_NAMED) || defined(HAVE_SHRINKER_ALLOC)
+       struct va_format vaf;
+       va_list args;
+#endif
+
+#ifdef HAVE_SHRINKER_ALLOC
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       shrinker = shrinker_alloc(flags, "%pV", &vaf);
+       va_end(args);
+#else
+       OBD_ALLOC_PTR(shrinker);
+#endif
+       if (!shrinker)
+               return ERR_PTR(-ENOMEM);
+
+#ifdef HAVE_SHRINKER_COUNT
+       shrinker->count_objects = ops->count_objects;
+       shrinker->scan_objects = ops->scan_objects;
+#else
+       shrinker->shrink = ops->shrink;
+#endif
+       shrinker->seeks = ops->seeks;
+
+#ifdef HAVE_SHRINKER_ALLOC
+       shrinker_register(shrinker);
+#else
+ #ifdef HAVE_REGISTER_SHRINKER_FORMAT_NAMED
+       va_start(args, fmt);
+       vaf.fmt = fmt;
+       vaf.va = &args;
+       rc = register_shrinker(shrinker, "%pV", &vaf);
+       va_end(args);
+ #elif defined(HAVE_REGISTER_SHRINKER_RET)
+       rc = register_shrinker(shrinker);
+ #else
+       register_shrinker(shrinker);
+ #endif
+#endif
+       if (rc) {
+#ifdef HAVE_SHRINKER_ALLOC
+               shrinker_free(shrinker);
+#else
+               OBD_FREE_PTR(shrinker);
+#endif
+               shrinker = ERR_PTR(rc);
+       }
+       return shrinker;
+}
+
 #ifndef fallthrough
 # if defined(__GNUC__) && __GNUC__ >= 7
 #  define fallthrough  __attribute__((fallthrough)) /* fallthrough */
index 2e1db64..89a164f 100644 (file)
@@ -1219,13 +1219,13 @@ static unsigned long ldlm_pools_cli_scan(struct shrinker *s,
                               sc->gfp_mask);
 }
 
-static struct shrinker ldlm_pools_srv_shrinker = {
+static struct ll_shrinker_ops ldlm_pools_srv_sh_ops = {
        .count_objects  = ldlm_pools_srv_count,
        .scan_objects   = ldlm_pools_srv_scan,
        .seeks          = DEFAULT_SEEKS,
 };
 
-static struct shrinker ldlm_pools_cli_shrinker = {
+static struct ll_shrinker_ops ldlm_pools_cli_sh_ops = {
        .count_objects  = ldlm_pools_cli_count,
        .scan_objects   = ldlm_pools_cli_scan,
        .seeks          = DEFAULT_SEEKS,
@@ -1266,12 +1266,12 @@ static int ldlm_pools_cli_shrink(struct shrinker *shrinker,
                                 sc->nr_to_scan, sc->gfp_mask);
 }
 
-static struct shrinker ldlm_pools_srv_shrinker = {
+static struct ll_shrinker_ops ldlm_pools_srv_sh_ops = {
        .shrink = ldlm_pools_srv_shrink,
        .seeks = DEFAULT_SEEKS,
 };
 
-static struct shrinker ldlm_pools_cli_shrinker = {
+static struct ll_shrinker_ops ldlm_pools_cli_sh_ops = {
        .shrink = ldlm_pools_cli_shrink,
        .seeks = DEFAULT_SEEKS,
 };
@@ -1449,43 +1449,49 @@ static void ldlm_pools_recalc_task(struct work_struct *ws)
 
 static bool ldlm_pools_init_done;
 
+static struct shrinker *ldlm_pools_srv_shrinker;
+static struct shrinker *ldlm_pools_cli_shrinker;
+
 int ldlm_pools_init(void)
 {
        time64_t delay;
        int rc;
 
+       ENTRY;
+
 #ifdef HAVE_SERVER_SUPPORT
        delay = min(LDLM_POOL_SRV_DEF_RECALC_PERIOD,
                    LDLM_POOL_CLI_DEF_RECALC_PERIOD);
 #else
        delay = LDLM_POOL_CLI_DEF_RECALC_PERIOD;
 #endif
+       ldlm_pools_srv_shrinker = ll_shrinker_create(&ldlm_pools_srv_sh_ops, 0,
+                                                    "ldlm_pools_server");
+       if (IS_ERR(ldlm_pools_srv_shrinker))
+               GOTO(out, rc = PTR_ERR(ldlm_pools_srv_shrinker));
 
-       rc = register_shrinker(&ldlm_pools_srv_shrinker);
-       if (rc)
-               goto out;
-
-       rc = register_shrinker(&ldlm_pools_cli_shrinker);
-       if (rc)
-               goto out_shrinker;
+       ldlm_pools_cli_shrinker = ll_shrinker_create(&ldlm_pools_cli_sh_ops, 0,
+                                                    "ldlm_pools_client");
+       if (IS_ERR(ldlm_pools_cli_shrinker))
+               GOTO(out_shrinker, rc = PTR_ERR(ldlm_pools_cli_shrinker));
 
        schedule_delayed_work(&ldlm_pools_recalc_work, delay);
        ldlm_pools_init_done = true;
-       return 0;
+       RETURN(0);
 
 out_shrinker:
-       unregister_shrinker(&ldlm_pools_cli_shrinker);
+       shrinker_free(ldlm_pools_srv_shrinker);
 out:
-       return rc;
+       RETURN(rc);
 }
 
 void ldlm_pools_fini(void)
 {
        if (ldlm_pools_init_done) {
-               unregister_shrinker(&ldlm_pools_srv_shrinker);
-               unregister_shrinker(&ldlm_pools_cli_shrinker);
-
                cancel_delayed_work_sync(&ldlm_pools_recalc_work);
+
+               shrinker_free(ldlm_pools_srv_shrinker);
+               shrinker_free(ldlm_pools_cli_shrinker);
        }
 
        ldlm_pools_init_done = false;
index b89a6d2..0a5b593 100644 (file)
@@ -151,10 +151,9 @@ int lustre_in_group_p(struct lu_ucred *mu, gid_t grp)
                if (!group_info)
                        return 0;
 
-               atomic_inc(&group_info->usage);
+               get_group_info(group_info);
                rc = lustre_groups_search(group_info, grp);
-               if (atomic_dec_and_test(&group_info->usage))
-                       groups_free(group_info);
+               put_group_info(group_info);
        }
        return rc;
 }
index 0d9fa5e..cd98acb 100644 (file)
@@ -2123,7 +2123,7 @@ static unsigned long lu_cache_shrink_scan(struct shrinker *sk,
 }
 
 #ifdef HAVE_SHRINKER_COUNT
-static struct shrinker lu_site_shrinker = {
+static struct ll_shrinker_ops lu_site_sh_ops = {
        .count_objects  = lu_cache_shrink_count,
        .scan_objects   = lu_cache_shrink_scan,
        .seeks          = DEFAULT_SEEKS,
@@ -2162,13 +2162,15 @@ static int lu_cache_shrink(struct shrinker *shrinker,
        return cached;
 }
 
-static struct shrinker lu_site_shrinker = {
+static struct ll_shrinker_ops lu_site_sh_ops = {
        .shrink  = lu_cache_shrink,
        .seeks   = DEFAULT_SEEKS,
 };
 
 #endif /* HAVE_SHRINKER_COUNT */
 
+static struct shrinker *lu_site_shrinker;
+
 /* Initialization of global lu_* data. */
 int lu_global_init(void)
 {
@@ -2203,9 +2205,11 @@ int lu_global_init(void)
         * inode, one for ea. Unfortunately setting this high value results in
         * lu_object/inode cache consuming all the memory.
         */
-       result = register_shrinker(&lu_site_shrinker);
-       if (result)
+       lu_site_shrinker = ll_shrinker_create(&lu_site_sh_ops, 0, "lu_site");
+       if (IS_ERR(lu_site_shrinker)) {
+               result = PTR_ERR(lu_site_shrinker);
                goto out_env;
+       }
 
        result = rhashtable_init(&lu_env_rhash, &lu_env_rhash_params);
 
@@ -2215,7 +2219,7 @@ int lu_global_init(void)
        return result;
 
 out_shrinker:
-       unregister_shrinker(&lu_site_shrinker);
+       shrinker_free(lu_site_shrinker);
 out_env:
        /* ordering here is explained in lu_global_fini() */
        lu_context_key_degister(&lu_global_key);
@@ -2230,7 +2234,7 @@ out_lu_ref:
 /* Dual to lu_global_init(). */
 void lu_global_fini(void)
 {
-       unregister_shrinker(&lu_site_shrinker);
+       shrinker_free(lu_site_shrinker);
 
        lu_context_key_degister(&lu_global_key);
 
index 6485093..edd4dcf 100644 (file)
@@ -3950,7 +3950,7 @@ DEFINE_SPINLOCK(osc_shrink_lock);
 bool osc_page_cache_shrink_enabled = true;
 
 #ifdef HAVE_SHRINKER_COUNT
-static struct shrinker osc_cache_shrinker = {
+static struct ll_shrinker_ops osc_cache_sh_ops = {
        .count_objects  = osc_cache_shrink_count,
        .scan_objects   = osc_cache_shrink_scan,
        .seeks          = DEFAULT_SEEKS,
@@ -3964,12 +3964,14 @@ static int osc_cache_shrink(struct shrinker *shrinker,
        return osc_cache_shrink_count(shrinker, sc);
 }
 
-static struct shrinker osc_cache_shrinker = {
+static struct ll_shrinker_ops osc_cache_sh_ops = {
        .shrink   = osc_cache_shrink,
        .seeks    = DEFAULT_SEEKS,
 };
 #endif
 
+static struct shrinker *osc_cache_shrinker;
+
 static int __init osc_init(void)
 {
        unsigned int reqpool_size;
@@ -3990,9 +3992,10 @@ static int __init osc_init(void)
        if (rc)
                RETURN(rc);
 
-       rc = register_shrinker(&osc_cache_shrinker);
-       if (rc)
-               GOTO(out_kmem, rc);
+       osc_cache_shrinker = ll_shrinker_create(&osc_cache_sh_ops, 0,
+                                               "osc_cache");
+       if (IS_ERR(osc_cache_shrinker))
+               GOTO(out_kmem, rc = PTR_ERR(osc_cache_shrinker));
 
        /* This is obviously too much memory, only prevent overflow here */
        if (osc_reqpool_mem_max >= 1 << 12 || osc_reqpool_mem_max == 0)
@@ -4035,7 +4038,7 @@ out_stop_grant:
 out_req_pool:
        ptlrpc_free_rq_pool(osc_rq_pool);
 out_shrinker:
-       unregister_shrinker(&osc_cache_shrinker);
+       shrinker_free(osc_cache_shrinker);
 out_kmem:
        lu_kmem_fini(osc_caches);
 
@@ -4047,7 +4050,7 @@ static void __exit osc_exit(void)
        class_unregister_type(LUSTRE_OSC_NAME);
        ptlrpc_free_rq_pool(osc_rq_pool);
        osc_stop_grant_work();
-       unregister_shrinker(&osc_cache_shrinker);
+       shrinker_free(osc_cache_shrinker);
        lu_kmem_fini(osc_caches);
 }
 
index bbf7374..9da60a9 100644 (file)
@@ -120,7 +120,8 @@ static struct ptlrpc_enc_page_pool {
        /*
         * memory shrinker
         */
-       struct shrinker pool_shrinker;
+       struct ll_shrinker_ops epp_shops;
+       struct shrinker *pool_shrinker;
        struct mutex add_pages_mutex;
 } **page_pools;
 
@@ -1014,16 +1015,17 @@ int sptlrpc_enc_pool_init(void)
                        GOTO(fail, rc = -ENOMEM);
                /* Pass pool number as part of pools_shrinker_seeks value */
 #ifdef HAVE_SHRINKER_COUNT
-               pool->pool_shrinker.count_objects = enc_pools_shrink_count;
-               pool->pool_shrinker.scan_objects = enc_pools_shrink_scan;
+               pool->epp_shops.count_objects = enc_pools_shrink_count;
+               pool->epp_shops.scan_objects = enc_pools_shrink_scan;
 #else
-               pool->pool_shrinker.shrink = enc_pools_shrink;
+               pool->epp_shops.shrink = enc_pools_shrink;
 #endif
-               pool->pool_shrinker.seeks = INDEX_TO_SEEKS(pool_index);
+               pool->epp_shops.seeks = INDEX_TO_SEEKS(pool_index);
 
-               rc = register_shrinker(&pool->pool_shrinker);
-               if (rc)
-                       GOTO(fail, rc);
+               pool->pool_shrinker = ll_shrinker_create(&pool->epp_shops, 0,
+                                                        "sptlrpc_enc_pool");
+               if (IS_ERR(pool->pool_shrinker))
+                       GOTO(fail, rc = PTR_ERR(pool->pool_shrinker));
 
                mutex_init(&pool->add_pages_mutex);
        }
@@ -1034,7 +1036,7 @@ fail:
        for (pool_index = 0; pool_index <= to_revert; pool_index++) {
                pool = page_pools[pool_index];
                if (pool) {
-                       if (pool->epp_pools) 
+                       if (pool->epp_pools)
                                enc_pools_free(pool_index);
                        OBD_FREE(pool, sizeof(**page_pools));
                }
@@ -1052,7 +1054,7 @@ void sptlrpc_enc_pool_fini(void)
 
        for (pool_index = 0; pool_index < POOLS_COUNT; pool_index++) {
                pool = page_pools[pool_index];
-               unregister_shrinker(&pool->pool_shrinker);
+               shrinker_free(pool->pool_shrinker);
                LASSERT(pool->epp_pools);
                LASSERT(pool->epp_total_pages == pool->epp_free_pages);