vnet deletion panic

Marko Zec zec at fer.hr
Tue Feb 4 05:27:01 UTC 2014


On Mon, 3 Feb 2014 21:05:28 -0800
Vijay Singh <vijju.singh at gmail.com> wrote:

> Hi Marco, the code in rt_ifmsg() checks what seems like global state,
> so its not routing sockets in the vnet being destroyed.

Huh then we should V_irtualize that global state - maybe the attached
patch could help (only compile-tested, perhaps you could try it out)?

Marko


> rt_ifmsg(struct ifnet *ifp)
> {
>         struct if_msghdr *ifm;
>         struct mbuf *m;
>         struct rt_addrinfo info;
> 
>         if (route_cb.any_count == 0)
>                 return;
> 
> You are right, there is no ifp context in rt_dispatch(). So perhaps we
> should not call rt_ifmsg() from if_unroute() is (ifp == V_loif) since
> that would end up using the soon to be destroyed ifp in the mbuf.
> What do you think?
> 
> 
> On Mon, Feb 3, 2014 at 8:52 PM, Marko Zec <zec at fer.hr> wrote:
> 
> > On Mon, 3 Feb 2014 19:33:21 -0800
> > Vijay Singh <vijju.singh at gmail.com> wrote:
> >
> > > I'm running into a crash due on vnet deletion in the presence of
> > > routing sockets. The root cause seems to originate from():
> > >
> > > if_detach_internal() -> if_down(ifp) -> if_unroute() ->
> > > rt_ifmsg() -> rt_dispatch()
> > >
> > > In rt_dispatch() we have:
> > >
> > > #ifdef VIMAGE
> > >         if (V_loif)
> > >                 m->m_pkthdr.rcvif = V_loif;
> > > #endif
> > > netisr_queue(NETISR_ROUTE, m);
> > >
> > > Now since this would be processed async, and the ifp alove is the
> > > loopback of the vnet being deleted, we run into accessing a freed
> > > pointer (ifp) when netisr picks up the mbuf. So I am wondering
> > > how to fix this. I am thinking that we could do something like
> > > the following in rt_dispatch():
> > >
> > > #ifdef VIMAGE
> > >         if (V_loif) {
> > >             if ((ifp == V_loif) && !IS_DEFAULT_VNET(curvnet)) {
> > >                CURVNET_SET_QUIET(vnet0);
> > >                m->m_pkthdr.rcvif = V_loif;
> > >               CURVNET_RESTORE();
> > >             } else
> > >                 m->m_pkthdr.rcvif = V_loif;
> > >         }
> > > #endif
> > >
> > > So basically switch to the default vnet for the mbuf with the
> > > routing socket message. Thoughts?
> >
> > By design, the vnet teardown procedure should not commence before
> > the last socket attached to that vnet is closed, so I'm suspicious
> > whether the proposed approach could actually appease the panics
> > you're observing.  Furthermore, it would certainly cause bogus
> > routing messages to appear in vnet0 and possibly confuse routing
> > socket consumers running there.  Plus, in rt_dispatch() there's no
> > ifp context to check against V_loif at all, as you're proposing
> > your patch?
> >
> > Perhaps it could be possible to walk through all the netisr queues
> > just before V_loif gets destroyed, and prune all queued mbufs which
> > have m->m_pkthdr.rcvif pointing to V_loif?  Since the vnet teardown
> > procedure cannot be initiated before all (routing) sockets attached
> > to that vnet have been closed, after all other ifnets except V_loif
> > have also been destroyed it should not be possible for new mbufs to
> > be queued with rcvif pointing back to V_loif, so at least
> > conceptually that approach might work correctly.
> >
> > Marko
> >

-------------- next part --------------
A non-text attachment was scrubbed...
Name: v_route_cb.diff
Type: text/x-patch
Size: 2813 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-net/attachments/20140204/60e01994/attachment-0001.bin>


More information about the freebsd-net mailing list