On Tue, Jul 5, 2016 at 10:59 AM, Cong Wang <xiyou.wangcong@xxxxxxxxx> wrote: > On Mon, Jul 4, 2016 at 7:50 PM, Matt Bennett > <Matt.Bennett@xxxxxxxxxxxxxxxxxxx> wrote: >> Using printk I have confirmed that ppp_pernet() is called from >> ppp_connect_channel() when the BUG occurs (i.e. pch->chan_net is NULL). >> >> This behavior appears to have been introduced in commit 1f461dc ("ppp: >> take reference on channels netns"). > > We have some race condition here, where a parallel ppp_unregister_channel() > could happen while we are in ppp_connect_channel(). > > We need some synchronization for them. I am not sure what is the right lock > here since ppp locking looks crazy. Matt, could you try if the attached patch helps? Thanks!
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 8dedafa..07f0e49 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2601,8 +2601,6 @@ ppp_unregister_channel(struct ppp_channel *chan) spin_lock_bh(&pn->all_channels_lock); list_del(&pch->list); spin_unlock_bh(&pn->all_channels_lock); - put_net(pch->chan_net); - pch->chan_net = NULL; pch->file.dead = 1; wake_up_interruptible(&pch->file.rwait); @@ -3136,6 +3134,11 @@ ppp_disconnect_channel(struct channel *pch) */ static void ppp_destroy_channel(struct channel *pch) { + if (pch->chan_net) { + put_net(pch->chan_net); + pch->chan_net = NULL; + } + atomic_dec(&channel_count); if (!pch->file.dead) {