Message ID | 20230727080502.77895-41-zhengqi.arch@bytedance.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | use refcount+RCU method to implement lockless slab shrink | expand |
On 2023/7/27 16:04, Qi Zheng wrote: > In preparation for implementing lockless slab shrink, use new APIs to > dynamically allocate the xfs-qm shrinker, so that it can be freed > asynchronously using kfree_rcu(). Then it doesn't need to wait for RCU > read-side critical section when releasing the struct xfs_quotainfo. > > Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com> > Reviewed-by: Muchun Song <songmuchun@bytedance.com> > --- > fs/xfs/xfs_qm.c | 26 +++++++++++++------------- > fs/xfs/xfs_qm.h | 2 +- > 2 files changed, 14 insertions(+), 14 deletions(-) > > diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c > index 6abcc34fafd8..032f0a208bd2 100644 > --- a/fs/xfs/xfs_qm.c > +++ b/fs/xfs/xfs_qm.c > @@ -504,8 +504,7 @@ xfs_qm_shrink_scan( > struct shrinker *shrink, > struct shrink_control *sc) > { > - struct xfs_quotainfo *qi = container_of(shrink, > - struct xfs_quotainfo, qi_shrinker); > + struct xfs_quotainfo *qi = shrink->private_data; > struct xfs_qm_isolate isol; > unsigned long freed; > int error; > @@ -539,8 +538,7 @@ xfs_qm_shrink_count( > struct shrinker *shrink, > struct shrink_control *sc) > { > - struct xfs_quotainfo *qi = container_of(shrink, > - struct xfs_quotainfo, qi_shrinker); > + struct xfs_quotainfo *qi = shrink->private_data; > > return list_lru_shrink_count(&qi->qi_lru, sc); > } > @@ -680,16 +678,18 @@ xfs_qm_init_quotainfo( > if (XFS_IS_PQUOTA_ON(mp)) > xfs_qm_set_defquota(mp, XFS_DQTYPE_PROJ, qinf); > > - qinf->qi_shrinker.count_objects = xfs_qm_shrink_count; > - qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan; > - qinf->qi_shrinker.seeks = DEFAULT_SEEKS; > - qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; > - > - error = register_shrinker(&qinf->qi_shrinker, "xfs-qm:%s", > - mp->m_super->s_id); > - if (error) > + qinf->qi_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE, "xfs-qm:%s", > + mp->m_super->s_id); > + if (!qinf->qi_shrinker) Here should set error to -ENOMEM, will fix. > goto out_free_inos; > > + qinf->qi_shrinker->count_objects = xfs_qm_shrink_count; > + qinf->qi_shrinker->scan_objects = xfs_qm_shrink_scan; > + qinf->qi_shrinker->seeks = DEFAULT_SEEKS; > + qinf->qi_shrinker->private_data = qinf; > + > + shrinker_register(qinf->qi_shrinker); > + > return 0; > > out_free_inos: > @@ -718,7 +718,7 @@ xfs_qm_destroy_quotainfo( > qi = mp->m_quotainfo; > ASSERT(qi != NULL); > > - unregister_shrinker(&qi->qi_shrinker); > + shrinker_free(qi->qi_shrinker); > list_lru_destroy(&qi->qi_lru); > xfs_qm_destroy_quotainos(qi); > mutex_destroy(&qi->qi_tree_lock); > diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h > index 9683f0457d19..d5c9fc4ba591 100644 > --- a/fs/xfs/xfs_qm.h > +++ b/fs/xfs/xfs_qm.h > @@ -63,7 +63,7 @@ struct xfs_quotainfo { > struct xfs_def_quota qi_usr_default; > struct xfs_def_quota qi_grp_default; > struct xfs_def_quota qi_prj_default; > - struct shrinker qi_shrinker; > + struct shrinker *qi_shrinker; > > /* Minimum and maximum quota expiration timestamp values. */ > time64_t qi_expiry_min;
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 6abcc34fafd8..032f0a208bd2 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -504,8 +504,7 @@ xfs_qm_shrink_scan( struct shrinker *shrink, struct shrink_control *sc) { - struct xfs_quotainfo *qi = container_of(shrink, - struct xfs_quotainfo, qi_shrinker); + struct xfs_quotainfo *qi = shrink->private_data; struct xfs_qm_isolate isol; unsigned long freed; int error; @@ -539,8 +538,7 @@ xfs_qm_shrink_count( struct shrinker *shrink, struct shrink_control *sc) { - struct xfs_quotainfo *qi = container_of(shrink, - struct xfs_quotainfo, qi_shrinker); + struct xfs_quotainfo *qi = shrink->private_data; return list_lru_shrink_count(&qi->qi_lru, sc); } @@ -680,16 +678,18 @@ xfs_qm_init_quotainfo( if (XFS_IS_PQUOTA_ON(mp)) xfs_qm_set_defquota(mp, XFS_DQTYPE_PROJ, qinf); - qinf->qi_shrinker.count_objects = xfs_qm_shrink_count; - qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan; - qinf->qi_shrinker.seeks = DEFAULT_SEEKS; - qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; - - error = register_shrinker(&qinf->qi_shrinker, "xfs-qm:%s", - mp->m_super->s_id); - if (error) + qinf->qi_shrinker = shrinker_alloc(SHRINKER_NUMA_AWARE, "xfs-qm:%s", + mp->m_super->s_id); + if (!qinf->qi_shrinker) goto out_free_inos; + qinf->qi_shrinker->count_objects = xfs_qm_shrink_count; + qinf->qi_shrinker->scan_objects = xfs_qm_shrink_scan; + qinf->qi_shrinker->seeks = DEFAULT_SEEKS; + qinf->qi_shrinker->private_data = qinf; + + shrinker_register(qinf->qi_shrinker); + return 0; out_free_inos: @@ -718,7 +718,7 @@ xfs_qm_destroy_quotainfo( qi = mp->m_quotainfo; ASSERT(qi != NULL); - unregister_shrinker(&qi->qi_shrinker); + shrinker_free(qi->qi_shrinker); list_lru_destroy(&qi->qi_lru); xfs_qm_destroy_quotainos(qi); mutex_destroy(&qi->qi_tree_lock); diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 9683f0457d19..d5c9fc4ba591 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h @@ -63,7 +63,7 @@ struct xfs_quotainfo { struct xfs_def_quota qi_usr_default; struct xfs_def_quota qi_grp_default; struct xfs_def_quota qi_prj_default; - struct shrinker qi_shrinker; + struct shrinker *qi_shrinker; /* Minimum and maximum quota expiration timestamp values. */ time64_t qi_expiry_min;