The next commit in this series will add yet another code site decrementing a struct parallel_data's refcount and invoking dealloction as appropriate. With that, it's due to provide proper helper functions for managing parallel_datas' refcounts and to convert the existing open-coded refcount manipulation sites. Implement padata_put_pd() as well as a padata_put_pd_many() for batched releases as needed in padata_serial_worker(). For symmetry reasons, also provide a padata_put_get(), even though its implementation is fairly trivial. Convert the exisiting open-coded parallel_data ->refcnt manipulation code sites to these new helpers. Signed-off-by: Nicolai Stange <nstange@xxxxxxx> --- kernel/padata.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/kernel/padata.c b/kernel/padata.c index e5819bb8bd1d..3bd1e23f089b 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -45,6 +45,10 @@ struct padata_mt_job_state { }; static void padata_free_pd(struct parallel_data *pd); +static inline void padata_get_pd(struct parallel_data *pd); +static void padata_put_pd_many(struct parallel_data *pd, int cnt); +static inline void padata_put_pd(struct parallel_data *pd); + static void __init padata_mt_helper(struct work_struct *work); static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index) @@ -198,7 +202,7 @@ int padata_do_parallel(struct padata_shell *ps, if ((pinst->flags & PADATA_RESET)) goto out; - refcount_inc(&pd->refcnt); + padata_get_pd(pd); padata->pd = pd; padata->cb_cpu = *cb_cpu; @@ -370,8 +374,7 @@ static void padata_serial_worker(struct work_struct *serial_work) } local_bh_enable(); - if (refcount_sub_and_test(cnt, &pd->refcnt)) - padata_free_pd(pd); + padata_put_pd_many(pd, cnt); } /** @@ -608,6 +611,22 @@ static void padata_free_pd(struct parallel_data *pd) kfree(pd); } +static inline void padata_get_pd(struct parallel_data *pd) +{ + refcount_inc(&pd->refcnt); +} + +static void padata_put_pd_many(struct parallel_data *pd, int cnt) +{ + if (refcount_sub_and_test(cnt, &pd->refcnt)) + padata_free_pd(pd); +} + +static inline void padata_put_pd(struct parallel_data *pd) +{ + padata_put_pd_many(pd, 1); +} + static void __padata_start(struct padata_instance *pinst) { pinst->flags |= PADATA_INIT; @@ -654,8 +673,7 @@ static int padata_replace(struct padata_instance *pinst) synchronize_rcu(); list_for_each_entry_continue_reverse(ps, &pinst->pslist, list) - if (refcount_dec_and_test(&ps->opd->refcnt)) - padata_free_pd(ps->opd); + padata_put_pd(ps->opd); pinst->flags &= ~PADATA_RESET; -- 2.37.3