staging/lustre: convert to new shrinker API
cover staging/lustre: convert to new shrinker API
Hi Andrew,
Following patches convert Lustre to new shrinker scan/count API. They are rebased on top of latest staging-next and can replace the current Lustre shrinker patches in linux-next/akpm. Please help to queue them.
Resend after fixing up sender email address. Greg complained about it so I guess I shouldn't let you complain as well...
So here are the resent ones.
Thanks,
Tao
Peng Tao (4):
staging/lustre/ldlm: convert to shrinkers to count/scan API staging/lustre/obdclass: convert lu_object shrinker to count/scan API staging/lustre/ptlrpc: convert to new shrinker API staging/lustre/libcfs: cleanup linux-mem.h
.../lustre/include/linux/libcfs/linux/linux-mem.h | 38 ----- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 148 +++++++++++--------- drivers/staging/lustre/lustre/obdclass/lu_object.c | 98 +++++++------ drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 76 +++++----- 4 files changed, 173 insertions(+), 187 deletions(-)
Signature · 1 line
1.7.9.5
PATCH 1/4 staging/lustre/ldlm: convert to shrinkers to count/scan API
convert ldlm shrinker to new count/scan API.
--- drivers/staging/lustre/lustre/ldlm/ldlm_pool.c | 148 +++++++++++++----------- 1 file changed, 79 insertions(+), 69 deletions(-)
drivers/staging/lustre/lustre/ldlm/ldlm_pool.c +79 -69
@@ -524,7 +524,7 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl, int nr, unsigned int gfp_mask) {struct ldlm_namespace *ns; -int canceled =0 , unused; +int unused; ns =ldlm_pl2ns (pl);
@@ -543,14 +543,10 @@ static int ldlm_cli_pool_shrink(struct ldlm_pool *pl, unused = ns->ns_nr_unused;spin_unlock (&ns->ns_lock); -if (nr) { - canceled =ldlm_cancel_lru (ns, nr,LCF_ASYNC , -LDLM_CANCEL_SHRINK ); - } -/* -* Return the number of potentially reclaimable locks. -*/ -return ((unused - canceled) /100 ) * sysctl_vfs_cache_pressure; +if (nr ==0 ) +return (unused /100 ) * sysctl_vfs_cache_pressure; +else +return ldlm_cancel_lru (ns, nr,LCF_ASYNC ,LDLM_CANCEL_SHRINK ); }struct ldlm_pool_ops ldlm_srv_pool_ops = {
@@ -604,9 +600,10 @@ int ldlm_pool_recalc(struct ldlm_pool *pl)return recalc_interval_sec; } -/** +/* * Pool shrink wrapper. Will call either client or server pool recalc callback -* depending what pool \a pl is used. +* depending what pool pl is used. When nr == 0, just return the number of +* freeable locks. Otherwise, return the number of canceled locks. */ int ldlm_pool_shrink (struct ldlm_pool *pl,int nr,unsigned int gfp_mask)
@@ -1025,29 +1022,24 @@ static int ldlm_pool_granted(struct ldlm_pool *pl) }static struct ptlrpc_thread *ldlm_pools_thread; -static struct shrinker *ldlm_pools_srv_shrinker; -static struct shrinker *ldlm_pools_cli_shrinker;static struct completion ldlm_pools_comp;/* -* Cancel \a nr locks from all namespaces (if possible). Returns number of -* cached locks after shrink is finished. All namespaces are asked to -* cancel approximately equal amount of locks to keep balancing. +* count locks from all namespaces (if possible). Returns number of +* cached locks. */ -static int ldlm_pools_shrink (ldlm_side_t client,int nr, -unsigned int gfp_mask) +static unsigned long ldlm_pools_count (ldlm_side_t client,unsigned int gfp_mask) { -int total =0 , cached =0 , nr_ns; +int total =0 , nr_ns;struct ldlm_namespace *ns;struct ldlm_namespace *ns_old =NULL ;/* loop detection */ void *cookie; -if (client ==LDLM_NAMESPACE_CLIENT && nr !=0 && - !(gfp_mask & __GFP_FS)) -return -1 ; +if (client ==LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS)) +return 0 ; -CDEBUG (D_DLMTRACE ,"Request to shrink %d %s locks from all pools\n" , - nr, client ==LDLM_NAMESPACE_CLIENT ?"client" :"server" ); +CDEBUG (D_DLMTRACE ,"Request to count %s locks from all pools\n" , + client ==LDLM_NAMESPACE_CLIENT ?"client" :"server" ); cookie =cl_env_reenter ();
@@ -1055,8 +1047,7 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,* Find out how many resources we may release. */ for (nr_ns =ldlm_namespace_nr_read (client); - nr_ns >0 ; nr_ns--) - { + nr_ns >0 ; nr_ns--) {mutex_lock (ldlm_namespace_lock (client));if (list_empty (ldlm_namespace_list (client))) {mutex_unlock (ldlm_namespace_lock (client));
@@ -1086,17 +1077,27 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,ldlm_namespace_put (ns); } -if (nr ==0 || total ==0 ) { -cl_env_reexit (cookie); -return total; - } +cl_env_reexit (cookie); +return total; +} + +static unsigned long ldlm_pools_scan (ldlm_side_t client,int nr,unsigned int gfp_mask) +{ +unsigned long freed =0 ; +int tmp, nr_ns; +struct ldlm_namespace *ns; +void *cookie; + +if (client ==LDLM_NAMESPACE_CLIENT && !(gfp_mask & __GFP_FS)) +return -1 ; + + cookie =cl_env_reenter ();/* -* Shrink at least ldlm_namespace_nr(client) namespaces. +* Shrink at least ldlm_namespace_nr_read(client) namespaces. */ -for (nr_ns =ldlm_namespace_nr_read (client) - nr_ns; - nr_ns >0 ; nr_ns--) - { +for (tmp = nr_ns =ldlm_namespace_nr_read (client); + tmp >0 ; tmp--) {int cancel, nr_locks;/*
@@ -1105,12 +1106,6 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,mutex_lock (ldlm_namespace_lock (client));if (list_empty (ldlm_namespace_list (client))) {mutex_unlock (ldlm_namespace_lock (client)); -/* -* If list is empty, we can't return any @cached > 0, -* that probably would cause needless shrinker -* call. -*/ - cached =0 ;break ; } ns =ldlm_namespace_first_locked (client);
@@ -1119,29 +1114,42 @@ static int ldlm_pools_shrink(ldlm_side_t client, int nr,mutex_unlock (ldlm_namespace_lock (client)); nr_locks =ldlm_pool_granted (&ns->ns_pool); - cancel =1 + nr_locks * nr / total; -ldlm_pool_shrink (&ns->ns_pool, cancel, gfp_mask); - cached +=ldlm_pool_granted (&ns->ns_pool); +/* +* We use to shrink propotionally but with new shrinker API, +* we lost the total number of freeable locks. +*/ + cancel =1 +min_t (int, nr_locks, nr / nr_ns); + freed +=ldlm_pool_shrink (&ns->ns_pool, cancel, gfp_mask);ldlm_namespace_put (ns); }cl_env_reexit (cookie); -/* we only decrease the SLV in server pools shrinker, return -1 to -* kernel to avoid needless loop. LU-1128 */ -return (client ==LDLM_NAMESPACE_SERVER ) ?-1 : cached; +/* +* we only decrease the SLV in server pools shrinker, return +* SHRINK_STOP to kernel to avoid needless loop. LU-1128 +*/ +return (client ==LDLM_NAMESPACE_SERVER ) ?SHRINK_STOP : freed; +} + +static unsigned long ldlm_pools_srv_count (struct shrinker *s,struct shrink_control *sc) +{ +return ldlm_pools_count (LDLM_NAMESPACE_SERVER , sc->gfp_mask); } -static int ldlm_pools_srv_shrink (SHRINKER_ARGS (sc ,nr_to_scan ,gfp_mask )) +static unsigned long ldlm_pools_srv_scan (struct shrinker *s,struct shrink_control *sc) { -return ldlm_pools_shrink (LDLM_NAMESPACE_SERVER , -shrink_param (sc, nr_to_scan), -shrink_param (sc, gfp_mask)); +return ldlm_pools_scan (LDLM_NAMESPACE_SERVER , sc->nr_to_scan, + sc->gfp_mask); } -static int ldlm_pools_cli_shrink (SHRINKER_ARGS (sc ,nr_to_scan ,gfp_mask )) +static unsigned long ldlm_pools_cli_count (struct shrinker *s,struct shrink_control *sc) { -return ldlm_pools_shrink (LDLM_NAMESPACE_CLIENT , -shrink_param (sc, nr_to_scan), -shrink_param (sc, gfp_mask)); +return ldlm_pools_count (LDLM_NAMESPACE_CLIENT , sc->gfp_mask); +} + +static unsigned long ldlm_pools_cli_scan (struct shrinker *s,struct shrink_control *sc) +{ +return ldlm_pools_scan (LDLM_NAMESPACE_CLIENT , sc->nr_to_scan, + sc->gfp_mask); }int ldlm_pools_recalc (ldlm_side_t client)
@@ -1224,7 +1232,7 @@ int ldlm_pools_recalc(ldlm_side_t client) }/* -* Recalc at least ldlm_namespace_nr(client) namespaces. +* Recalc at least ldlm_namespace_nr_read(client) namespaces. */ for (nr =ldlm_namespace_nr_read (client); nr >0 ; nr--) {int skip;
@@ -1397,6 +1405,18 @@ static void ldlm_pools_thread_stop(void)EXIT ; } +static struct shrinker ldlm_pools_srv_shrinker = { + .count_objects = ldlm_pools_srv_count, + .scan_objects = ldlm_pools_srv_scan, + .seeks =DEFAULT_SEEKS , +}; + +static struct shrinker ldlm_pools_cli_shrinker = { + .count_objects = ldlm_pools_cli_count, + .scan_objects = ldlm_pools_cli_scan, + .seeks =DEFAULT_SEEKS , +}; +int ldlm_pools_init (void ) {int rc;
@@ -1404,12 +1424,8 @@ int ldlm_pools_init(void) rc =ldlm_pools_thread_start ();if (rc ==0 ) { - ldlm_pools_srv_shrinker = -set_shrinker (DEFAULT_SEEKS , - ldlm_pools_srv_shrink); - ldlm_pools_cli_shrinker = -set_shrinker (DEFAULT_SEEKS , - ldlm_pools_cli_shrink); +register_shrinker (&ldlm_pools_srv_shrinker); +register_shrinker (&ldlm_pools_cli_shrinker); }RETURN (rc); }
@@ -1417,14 +1433,8 @@ EXPORT_SYMBOL(ldlm_pools_init);void ldlm_pools_fini (void ) { -if (ldlm_pools_srv_shrinker !=NULL ) { -remove_shrinker (ldlm_pools_srv_shrinker); - ldlm_pools_srv_shrinker =NULL ; - } -if (ldlm_pools_cli_shrinker !=NULL ) { -remove_shrinker (ldlm_pools_cli_shrinker); - ldlm_pools_cli_shrinker =NULL ; - } +unregister_shrinker (&ldlm_pools_srv_shrinker); +unregister_shrinker (&ldlm_pools_cli_shrinker);ldlm_pools_thread_stop (); }EXPORT_SYMBOL (ldlm_pools_fini);
Signature · 1 line
1.7.9.5
PATCH 2/4 staging/lustre/obdclass: convert lu_object shrinker to count/scan API
In reply to Peng Taoconvert lu_object shrinker to new count/scan API.
--- drivers/staging/lustre/lustre/obdclass/lu_object.c | 98 +++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-)
drivers/staging/lustre/lustre/obdclass/lu_object.c +52 -46
@@ -1780,7 +1780,6 @@ int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, }EXPORT_SYMBOL (lu_env_refill_by_tags); -static struct shrinker *lu_site_shrinker =NULL ; typedef struct lu_site_stats{ unsigned lss_populated;
@@ -1836,61 +1835,68 @@ static void lu_site_stats_get(cfs_hash_t *hs,* objects without taking the lu_sites_guard lock, but this is not * possible in the current implementation. */ -static int lu_cache_shrink (SHRINKER_ARGS (sc ,nr_to_scan ,gfp_mask )) +static unsigned long lu_cache_shrink_count (struct shrinker *sk, +struct shrink_control *sc) {lu_site_stats_t stats;struct lu_site *s;struct lu_site *tmp; -int cached =0 ; -int remain =shrink_param (sc, nr_to_scan); -LIST_HEAD (splice); - -if (!(shrink_param (sc, gfp_mask) & __GFP_FS)) { -if (remain !=0 ) -return -1 ; -else -/* We must not take the lu_sites_guard lock when -* __GFP_FS is *not* set because of the deadlock -* possibility detailed above. Additionally, -* since we cannot determine the number of -* objects in the cache without taking this -* lock, we're in a particularly tough spot. As -* a result, we'll just lie and say our cache is -* empty. This _should_ be ok, as we can't -* reclaim objects when __GFP_FS is *not* set -* anyways. -*/ -return 0 ; - } +unsigned long cached =0 ; -CDEBUG (D_INODE ,"Shrink %d objects\n" , remain); +if (!(sc->gfp_mask & __GFP_FS)) +return 0 ;mutex_lock (&lu_sites_guard);list_for_each_entry_safe (s, tmp, &lu_sites, ls_linkage) { -if (shrink_param (sc, nr_to_scan) !=0 ) { - remain =lu_site_purge (&lu_shrink_env, s, remain); -/* -* Move just shrunk site to the tail of site list to -* assure shrinking fairness. -*/ -list_move_tail (&s->ls_linkage, &splice); - } -memset (&stats,0 ,sizeof (stats));lu_site_stats_get (s->ls_obj_hash, &stats,0 ); cached += stats.lss_total - stats.lss_busy; -if (shrink_param (sc, nr_to_scan) && remain <=0 ) -break ; } -list_splice (&splice, lu_sites.prev);mutex_unlock (&lu_sites_guard); cached = (cached /100 ) * sysctl_vfs_cache_pressure; -if (shrink_param (sc, nr_to_scan) ==0 ) -CDEBUG (D_INODE ,"%d objects cached\n" , cached); +CDEBUG (D_INODE ,"%ld objects cached\n" , cached);return cached; } +static unsigned long lu_cache_shrink_scan (struct shrinker *sk, +struct shrink_control *sc) +{ +struct lu_site *s; +struct lu_site *tmp; +unsigned long remain = sc->nr_to_scan, freed =0 ; +LIST_HEAD (splice); + +if (!(sc->gfp_mask & __GFP_FS)) +/* We must not take the lu_sites_guard lock when +* __GFP_FS is *not* set because of the deadlock +* possibility detailed above. Additionally, +* since we cannot determine the number of +* objects in the cache without taking this +* lock, we're in a particularly tough spot. As +* a result, we'll just lie and say our cache is +* empty. This _should_ be ok, as we can't +* reclaim objects when __GFP_FS is *not* set +* anyways. +*/ +return SHRINK_STOP ; + +mutex_lock (&lu_sites_guard); +list_for_each_entry_safe (s, tmp, &lu_sites, ls_linkage) { + freed =lu_site_purge (&lu_shrink_env, s, remain); + remain -= freed; +/* +* Move just shrunk site to the tail of site list to +* assure shrinking fairness. +*/ +list_move_tail (&s->ls_linkage, &splice); + } +list_splice (&splice, lu_sites.prev); +mutex_unlock (&lu_sites_guard); + +return sc->nr_to_scan - remain; +} +/* * Debugging stuff. */
@@ -1914,6 +1920,12 @@ int lu_printk_printer(const struct lu_env *env,return 0 ; } +static struct shrinker lu_site_shrinker = { + .count_objects = lu_cache_shrink_count, + .scan_objects = lu_cache_shrink_scan, + .seeks =DEFAULT_SEEKS , +}; +/** * Initialization of global lu_* data. */
@@ -1948,9 +1960,7 @@ int lu_global_init(void)* inode, one for ea. Unfortunately setting this high value results in * lu_object/inode cache consuming all the memory. */ - lu_site_shrinker =set_shrinker (DEFAULT_SEEKS , lu_cache_shrink); -if (lu_site_shrinker ==NULL ) -return -ENOMEM ; +register_shrinker (&lu_site_shrinker);return result; }
@@ -1960,11 +1970,7 @@ int lu_global_init(void)*/ void lu_global_fini (void ) { -if (lu_site_shrinker !=NULL ) { -remove_shrinker (lu_site_shrinker); - lu_site_shrinker =NULL ; - } - +unregister_shrinker (&lu_site_shrinker);lu_context_key_degister (&lu_global_key);/*
Signature · 1 line
1.7.9.5
PATCH 3/4 staging/lustre/ptlrpc: convert to new shrinker API
In reply to Peng TaoConvert sptlrpc encode pool shrinker to use scan/count API.
--- drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c | 76 +++++++++++++---------- 1 file changed, 42 insertions(+), 34 deletions(-)
drivers/staging/lustre/lustre/ptlrpc/sec_bulk.c +42 -34
@@ -121,13 +121,6 @@ static struct ptlrpc_enc_page_pool { } page_pools;/* -* memory shrinker -*/ -const int pools_shrinker_seeks =DEFAULT_SEEKS ; -static struct shrinker *pools_shrinker =NULL ; - - -/* * /proc/fs/lustre/sptlrpc/encrypt_page_pools */ int sptlrpc_proc_enc_pool_seq_show (struct seq_file *m,void *v)
@@ -226,30 +219,46 @@ static void enc_pools_release_free_pages(long npages) }/* -* could be called frequently for query (@nr_to_scan == 0). * we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. */ -static int enc_pools_shrink (SHRINKER_ARGS (sc ,nr_to_scan ,gfp_mask )) +static unsigned long enc_pools_shrink_count (struct shrinker *s, +struct shrink_control *sc) { -if (unlikely (shrink_param (sc, nr_to_scan) !=0 )) { +/* +* if no pool access for a long time, we consider it's fully idle. +* a little race here is fine. +*/ +if (unlikely (cfs_time_current_sec () - page_pools.epp_last_access > +CACHE_QUIESCENT_PERIOD )) {spin_lock (&page_pools.epp_lock); - shrink_param(sc, nr_to_scan) = min_t(unsigned long, -shrink_param (sc, nr_to_scan), - page_pools.epp_free_pages - -PTLRPC_MAX_BRW_PAGES ); -if (shrink_param (sc, nr_to_scan) >0 ) { -enc_pools_release_free_pages (shrink_param (sc, - nr_to_scan)); -CDEBUG (D_SEC ,"released %ld pages, %ld left\n" , - (long )shrink_param (sc, nr_to_scan), - page_pools.epp_free_pages); - - page_pools.epp_st_shrinks++; - page_pools.epp_last_shrink =cfs_time_current_sec (); - } + page_pools.epp_idle_idx =IDLE_IDX_MAX ;spin_unlock (&page_pools.epp_lock); } +LASSERT (page_pools.epp_idle_idx <=IDLE_IDX_MAX ); +return max ((int )page_pools.epp_free_pages -PTLRPC_MAX_BRW_PAGES ,0 ) * + (IDLE_IDX_MAX - page_pools.epp_idle_idx) /IDLE_IDX_MAX ; +} + +/* +* we try to keep at least PTLRPC_MAX_BRW_PAGES pages in the pool. +*/ +static unsigned long enc_pools_shrink_scan (struct shrinker *s, +struct shrink_control *sc) +{ +spin_lock (&page_pools.epp_lock); + sc->nr_to_scan = min_t(unsigned long, sc->nr_to_scan, + page_pools.epp_free_pages -PTLRPC_MAX_BRW_PAGES ); +if (sc->nr_to_scan >0 ) { +enc_pools_release_free_pages (sc->nr_to_scan); +CDEBUG (D_SEC ,"released %ld pages, %ld left\n" , + (long )sc->nr_to_scan, page_pools.epp_free_pages); + + page_pools.epp_st_shrinks++; + page_pools.epp_last_shrink =cfs_time_current_sec (); + } +spin_unlock (&page_pools.epp_lock); +/* * if no pool access for a long time, we consider it's fully idle. * a little race here is fine.
@@ -262,8 +271,7 @@ static int enc_pools_shrink(SHRINKER_ARGS(sc, nr_to_scan, gfp_mask)) }LASSERT (page_pools.epp_idle_idx <=IDLE_IDX_MAX ); -return max ((int )page_pools.epp_free_pages -PTLRPC_MAX_BRW_PAGES ,0 ) * - (IDLE_IDX_MAX - page_pools.epp_idle_idx) /IDLE_IDX_MAX ; +return sc->nr_to_scan; } static inline
@@ -699,6 +707,12 @@ static inline void enc_pools_free(void) sizeof(*page_pools.epp_pools)); } +static struct shrinker pools_shrinker = { + .count_objects = enc_pools_shrink_count, + .scan_objects = enc_pools_shrink_scan, + .seeks =DEFAULT_SEEKS , +}; +int sptlrpc_enc_pool_init (void ) {/*
@@ -736,12 +750,7 @@ int sptlrpc_enc_pool_init(void)if (page_pools.epp_pools ==NULL )return -ENOMEM ; - pools_shrinker =set_shrinker (pools_shrinker_seeks, - enc_pools_shrink); -if (pools_shrinker ==NULL ) { -enc_pools_free (); -return -ENOMEM ; - } +register_shrinker (&pools_shrinker);return 0 ; }
@@ -750,11 +759,10 @@ void sptlrpc_enc_pool_fini(void) {unsigned long cleaned, npools; -LASSERT (pools_shrinker);LASSERT (page_pools.epp_pools);LASSERT (page_pools.epp_total_pages == page_pools.epp_free_pages); -remove_shrinker (pools_shrinker); +unregister_shrinker (&pools_shrinker); npools =npages_to_npools (page_pools.epp_total_pages); cleaned =enc_pools_cleanup (page_pools.epp_pools, npools);
Signature · 1 line
1.7.9.5
PATCH 4/4 staging/lustre/libcfs: cleanup linux-mem.h
In reply to Peng Taoremove shrinker related wrappers.
--- .../lustre/include/linux/libcfs/linux/linux-mem.h | 38 -------------------- 1 file changed, 38 deletions(-)
drivers/staging/lustre/include/linux/libcfs/linux/linux-mem.h +0 -38
@@ -79,42 +79,4 @@ do { __oldfs = get_fs(); set_fs(get_ds());} while(0)#define MMSPACE_CLOSE set_fs(__oldfs) -/* -* Shrinker -*/ - -# define SHRINKER_ARGS (sc, nr_to_scan, gfp_mask) \ - struct shrinker *shrinker, \ - struct shrink_control *sc -# define shrink_param (sc, var) ((sc)->var) - -typedef int (*shrinker_t )(SHRINKER_ARGS (sc ,nr_to_scan ,gfp_mask )); - -static inline -struct shrinker *set_shrinker (int seek,shrinker_t func) -{ -struct shrinker *s; - - s =kmalloc (sizeof (*s),GFP_KERNEL ); -if (s ==NULL ) -return (NULL ); - - s->shrink = func; - s->seeks = seek; - -register_shrinker (s); - -return s; -} - -static inline -void remove_shrinker (struct shrinker *shrinker) -{ -if (shrinker ==NULL ) -return ; - -unregister_shrinker (shrinker); -kfree (shrinker); -} -#endif /* __LINUX_CFS_MEM_H__ */
Signature · 1 line
1.7.9.5