________________________________________ 发件人: Paul E. McKenney <paul...@kernel.org> 发送时间: 2020年12月31日 0:19 收件人: Zhang, Qiang 抄送: a...@linux-foundation.org; manf...@colorfullife.com; gustavo...@kernel.org; linux-kernel@vger.kernel.org 主题: Re: [PATCH] ipc/sem.c: Convert kfree_rcu() to call_rcu() in freeary function
On Wed, Dec 30, 2020 at 08:00:38PM +0800, qiang.zh...@windriver.com wrote: > From: Zqiang <qiang.zh...@windriver.com> > > Due to freeary function is called with spinlock be held, > the synchronize_rcu function may be called in kfree_rcu > function, the schedule may be happen in spinlock critical > region, need to replace kfree_rcu() with call_rcu(). > >Except that the call to kfree_rcu() below has two arguments, and >thus >provides a link for queuing the callback. It will never directly invoke >synchronize_rcu(). It is only the single-argument variant of >kfree_rcu() >that might invoke synchronize_rcu(). Sorry. It was my mistake, please ignore this patch. Thanks Qiang >Or are you seeing lockdep or might-sleep failures with the current >code? >If so, please post the relevant portions of the console output. > > Thanx, Paul > > Fixes: 693a8b6eecce ("ipc,rcu: Convert call_rcu(free_un) to kfree_rcu()") > Signed-off-by: Zqiang <qiang.zh...@windriver.com> > --- > ipc/sem.c | 9 ++++++++- > 1 file changed, 8 insertions(+), 1 deletion(-) > > diff --git a/ipc/sem.c b/ipc/sem.c > index f6c30a85dadf..12c3184347d9 100644 > --- a/ipc/sem.c > +++ b/ipc/sem.c > @@ -1132,6 +1132,13 @@ static int count_semcnt(struct sem_array *sma, ushort > semnum, > return semcnt; > } > > +static void free_un(struct rcu_head *head) > +{ > + struct sem_undo *un = container_of(head, struct sem_undo, rcu); > + > + kfree(un); > +} > + > /* Free a semaphore set. freeary() is called with sem_ids.rwsem locked > * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem > * remains locked on exit. > @@ -1152,7 +1159,7 @@ static void freeary(struct ipc_namespace *ns, struct > kern_ipc_perm *ipcp) > un->semid = -1; > list_del_rcu(&un->list_proc); > spin_unlock(&un->ulp->lock); > - kfree_rcu(un, rcu); > + call_rcu(&un->rcu, free_un); > } > > /* Wake up all pending processes and let them fail with EIDRM. */ > -- > 2.17.1 >