On 2010/05/26 11:46, Claudio Jeker wrote:
> On Wed, May 26, 2010 at 10:06:54AM +0100, Stuart Henderson wrote:
> > On 2010/05/21 23:54, Chris Bayly wrote:
> > > Okay, I believe I've finally simplified this down to something 
> > > manageable, 
> > > and hopefully a heck of alot more repeatable.
> > > 
> > > I have a second Alix 3D3 board running -current as of the 19th.
> > > 
> > > I can make it start leaking mbufs with the following setup.
> > > 
> > > - Completely bone stock OpenBSD install.
> > > - At install time setup one interface (vr0) as dhcp
> > > - After install, issue the following commands:
> > > 
> > > ifconfig vr1 up # Note: no cable connected on vr1
> > > ifconfig bridge0 add vr0
> > > ifconfig bridge0 add vr1
> > > ifconfig bridge0 up
> > > 
> > > netstat -m # will now show an increasing number of mbuf 2048 byte clusters
> > >            # being used
> > 
> > in vr_start() [if_vr.c:1228] we have this
> > 
> >     if (ifp->if_flags & IFF_OACTIVE || sc->vr_link == 0)
> >             return;
> > 
> > the sc->vr_link check was added to prevent watchdog timeouts,
> > but because these frames aren't transmitted we have a leak.
> > 
> > not sure if this is the best way, but it seems to do the trick:
> > 
> > Index: if_vr.c
> > ===================================================================
> > RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
> > retrieving revision 1.105
> > diff -u -p -r1.105 if_vr.c
> > --- if_vr.c 19 May 2010 15:27:35 -0000      1.105
> > +++ if_vr.c 26 May 2010 09:05:51 -0000
> > @@ -1225,7 +1225,7 @@ vr_start(struct ifnet *ifp)
> >  
> >     sc = ifp->if_softc;
> >  
> > -   if (ifp->if_flags & IFF_OACTIVE || sc->vr_link == 0)
> > +   if (ifp->if_flags & IFF_OACTIVE)
> >             return;
> >  
> >     cur_tx = sc->vr_cdata.vr_tx_prod;
> > @@ -1233,6 +1233,11 @@ vr_start(struct ifnet *ifp)
> >             IFQ_DEQUEUE(&ifp->if_snd, m_head);
> >             if (m_head == NULL)
> >                     break;
> > +           /* transmitting without link results in watchdog timeouts */
> > +           if (sc->vr_link == 0) {
> > +                   m_freem(m_head);
> > +                   return;
> > +           }
> >  
> >             /* Pack the data into the descriptor. */
> >             if (vr_encap(sc, cur_tx, m_head)) {
> > 
> 
> Hmm. The IFQ should have a limit and when reaching that packets will be
> dropped. So after 256 packets no more packets should leak.
> Unless something is calling IF_ENQUEUE() without checking IF_QFULL() first.
> Ugh, the these ifq makros are stupid.

With vr+bridge, the leak seems to be unlimited, certainly more than
256.

If you send packets some other way (I use ping6 ff02::1%vr0) then the
leak is clamped.

> Still I think the current behaviour is strange and your diff makes more
> sense. Any idea why vr(4) is using IFQ_DEQUEUE() + IF_PREPEND instead of
> doing the IFQ_POLL(), IFQ_DEQUEUE() dance?

No ideas...

[Added chris@ to cc's.]

Reply via email to