From: Shaun Tancheff Date: Fri, 8 Mar 2024 01:18:58 +0000 (-0800) Subject: LU-17392 build: compatibility updates for kernel 6.7 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=3f72e836dc6c5fe3bd850146120eb08b4797ac3d;p=fs%2Flustre-release.git LU-17392 build: compatibility updates for kernel 6.7 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 Lustre-change: https://review.whamcloud.com/53621 Lustre-commit: TBD (from 7e8165620e1943189d63ce4770c7722fa309a58e) Signed-off-by: Shaun Tancheff Change-Id: Ie07bdb7fe3eb6060bd84f95f860f1b53d120a605 Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/54323 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 49f8617..c080cb0 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -4038,6 +4038,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 + ],[ + struct shrinker *shrink __attribute__ ((unused)); + + shrink = shrinker_alloc(0, "%s", "whoami"); + ],[-Werror]) +]) +AC_DEFUN([LC_HAVE_SHRINKER_ALLOC], [ + AC_MSG_CHECKING([if 'shrinker_alloc()' exists]) + LB2_LINUX_TEST_RESULT([shrinker_alloc_exists], [ + AC_DEFINE(HAVE_SHRINKER_ALLOC, 1, + ['shrinker_alloc()' exists]) + ]) +]) # LC_HAVE_SHRINKER_ALLOC + +# # LC_PROG_LINUX # # Lustre linux kernel checks @@ -4288,6 +4311,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 @@ -4565,6 +4589,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 diff --git a/lustre/include/lustre_compat.h b/lustre/include/lustre_compat.h index ea2d655..b97d37b 100644 --- a/lustre/include/lustre_compat.h +++ b/lustre/include/lustre_compat.h @@ -557,12 +557,85 @@ static inline int ll_vfs_removexattr(struct dentry *dentry, 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 */ diff --git a/lustre/ldlm/ldlm_pool.c b/lustre/ldlm/ldlm_pool.c index 2b85ce2..50d8e27 100644 --- a/lustre/ldlm/ldlm_pool.c +++ b/lustre/ldlm/ldlm_pool.c @@ -1221,13 +1221,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, @@ -1268,12 +1268,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, }; @@ -1451,43 +1451,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; diff --git a/lustre/obdclass/idmap.c b/lustre/obdclass/idmap.c index 9db5497..1c9af54 100644 --- a/lustre/obdclass/idmap.c +++ b/lustre/obdclass/idmap.c @@ -173,10 +173,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; } diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index ec39ef4..e564bb8 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -2193,7 +2193,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, @@ -2232,13 +2232,14 @@ 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; /* * Debugging stuff. @@ -2324,9 +2325,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); @@ -2336,7 +2339,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); @@ -2353,7 +2356,7 @@ out_lu_ref: */ void lu_global_fini(void) { - unregister_shrinker(&lu_site_shrinker); + shrinker_free(lu_site_shrinker); lu_context_key_degister(&lu_global_key); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index de32a89..af3504a 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -4052,7 +4052,7 @@ LIST_HEAD(osc_shrink_list); DEFINE_SPINLOCK(osc_shrink_lock); #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, @@ -4066,12 +4066,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; @@ -4088,9 +4090,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) @@ -4133,7 +4136,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); @@ -4145,7 +4148,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); } diff --git a/lustre/ptlrpc/sec_bulk.c b/lustre/ptlrpc/sec_bulk.c index 2e9bdb1..9ab117e 100644 --- a/lustre/ptlrpc/sec_bulk.c +++ b/lustre/ptlrpc/sec_bulk.c @@ -127,7 +127,8 @@ static struct ptlrpc_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; @@ -1055,16 +1056,18 @@ int sptlrpc_pool_init(void) if (pool->ppp_ptr_pages == NULL) GOTO(fail, rc = -ENOMEM); #ifdef HAVE_SHRINKER_COUNT - pool->pool_shrinker.count_objects = pool_shrink_count; - pool->pool_shrinker.scan_objects = pool_shrink_scan; + pool->epp_shops.count_objects = pool_shrink_count; + pool->epp_shops.scan_objects = pool_shrink_scan; #else - pool->pool_shrinker.shrink = pool_shrink; + pool->epp_shops.shrink = pool_shrink; #endif - pool->pool_shrinker.seeks = ORDER_TO_SEEKS(pool_order); + pool->epp_shops.seeks = ORDER_TO_SEEKS(pool_order); /* Pass pool number as part of pool_shrinker_seeks value */ - 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); } @@ -1074,8 +1077,8 @@ fail: for (pool_order = 0; pool_order <= to_revert; pool_order++) { pool = page_pools[pool_order]; if (pool) { - unregister_shrinker(&pool->pool_shrinker); - if (pool->ppp_ptr_pages) + shrinker_free(pool->pool_shrinker); + if (pool->ppp_ptr_pages) pool_ptrs_free(pool); OBD_FREE(pool, sizeof(**page_pools)); } @@ -1093,7 +1096,7 @@ void sptlrpc_pool_fini(void) for (pool_order = 0; pool_order < POOLS_COUNT; pool_order++) { pool = page_pools[pool_order]; - unregister_shrinker(&pool->pool_shrinker); + shrinker_free(pool->pool_shrinker); LASSERT(pool->ppp_ptr_pages); LASSERT(pool->ppp_total_pages == pool->ppp_free_pages);