On Tue, Jul 16, 2019 at 09:23:45PM +0800, Herbert Xu wrote: > On Tue, Jul 16, 2019 at 09:09:28PM +0800, Herbert Xu wrote: > > > > Hmm, it doesn't work because the refcnt is attached to the old > > pd. That shouldn't be a problem though as we could simply ignore > > the refcnt in padata_flush_queue. > > This should fix it: > > ---8<--- > The function padata_do_serial uses parallel_data without obeying > the RCU rules around its life-cycle. This means that a concurrent > padata_replace call can result in a crash. > > This patch fixes it by using RCU just as we do in padata_do_parallel. RCU alone won't help because if some object is queued for async crypto, we left the RCU protected aera. I think padata_do_serial needs to do RCU and should free 'parallel_data' if the flag PADATA_RESET is set and the refcount goes to zero. padata_replace should do the same then. > > As the refcnt may now span two parallel_data structures, this patch > moves it to padata_instance instead. FWIW the refcnt is used to > limit the number of outstanding requests (albeit a soft limit as > we don't do a proper atomic inc and test). > > Fixes: 16295bec6398 ("padata: Generic parallelization/...") > Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> > > diff --git a/include/linux/padata.h b/include/linux/padata.h ... > index 5d13d25da2c8..ce51555cb86c 100644 > @@ -367,7 +367,7 @@ void padata_do_serial(struct padata_priv *padata) > struct parallel_data *pd; > int reorder_via_wq = 0; > > - pd = padata->pd; > + pd = rcu_dereference_bh(padata->inst->pd); Why not just pd = rcu_dereference_bh(padata->pd);