tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: NetBSD 5.1 TCP performance issue (lots of ACK)



On Fri, Oct 28, 2011 at 09:21:08PM +0200, Manuel Bouyer wrote:
> On Fri, Oct 28, 2011 at 10:27:56AM -0500, David Young wrote:
> > > Here is an updated patch. The key point to avoid the receive errors is
> > > to do another BUS_DMASYNC after reading wrx_status, before reading the
> > > other values to avoid reading e.g. len before status gets updated.
> > > The errors were because of 0-len receive descriptors.
> > 
> > Good catch!  Question, though:
> > 
> > > Index: sys/dev/pci/if_wm.c
> > > ===================================================================
> > > RCS file: /cvsroot/src/sys/dev/pci/if_wm.c,v
> > > retrieving revision 1.162.4.15
> > > diff -u -p -u -r1.162.4.15 if_wm.c
> > > --- sys/dev/pci/if_wm.c   7 Mar 2011 04:14:19 -0000       1.162.4.15
> > > +++ sys/dev/pci/if_wm.c   28 Oct 2011 14:03:33 -0000
> > > @@ -2879,11 +2907,7 @@ wm_rxintr(struct wm_softc *sc)
> > >               device_xname(sc->sc_dev), i));
> > >  
> > >           WM_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
> > > -
> > >           status = sc->sc_rxdescs[i].wrx_status;
> > > -         errors = sc->sc_rxdescs[i].wrx_errors;
> > > -         len = le16toh(sc->sc_rxdescs[i].wrx_len);
> > > -         vlantag = sc->sc_rxdescs[i].wrx_special;
> > >  
> > >           if ((status & WRX_ST_DD) == 0) {
> > >                   /*
> > > @@ -2892,6 +2916,14 @@ wm_rxintr(struct wm_softc *sc)
> > >                   WM_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
> > >                   break;
> > >           }
> > 
> > Should
> > 
> > >                   WM_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
> > 
> > move above 
> > 
> > >           if ((status & WRX_ST_DD) == 0) {
> > 
> > ?
> 
> I don't think so: if WRX_ST_DD is not set, we won't read anything more frm
> this descriptor so there's no need to sync it again.

Currently, if WRX_ST_DD is not set, we sync the descriptor and
get out of the loop:

                        WM_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
                        break;

If WRX_ST_DD is set, however, we do read more from the descriptor.  That
is why I ask whether we should sync it again.

It is strange and possibly unnecessary to have two sync calls
back-to-back, for it would be:

                WM_CDRXSYNC(sc, i, BUS_DMASYNC_PREREAD);
                if ((status & WRX_ST_DD) == 0) {
                        break;
                }

                /*                                                              
                 * sync again, to make sure the values below have been read     
                 * after status.                                                
                 */                                                             
                WM_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);

Dave

-- 
David Young             OJC Technologies is now Pixo
dyoung%pixotech.com@localhost     Urbana, IL   (217) 344-0444 x24


Home | Main Index | Thread Index | Old Index