From owner-svn-src-all@FreeBSD.ORG Tue Jun 29 08:06:21 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C9F7B1065673; Tue, 29 Jun 2010 08:06:21 +0000 (UTC) (envelope-from anders@FreeBSD.org) Received: from fupp.net (totem.fix.no [80.91.36.20]) by mx1.freebsd.org (Postfix) with ESMTP id 1B3568FC08; Tue, 29 Jun 2010 08:06:20 +0000 (UTC) Received: from localhost (totem.fix.no [80.91.36.20]) by fupp.net (Postfix) with ESMTP id 376A747B16; Tue, 29 Jun 2010 09:48:32 +0200 (CEST) Received: from fupp.net ([80.91.36.20]) by localhost (totem.fix.no [80.91.36.20]) (amavisd-new, port 10024) with LMTP id oDDW71m9f73e; Tue, 29 Jun 2010 09:48:31 +0200 (CEST) Received: by fupp.net (Postfix, from userid 1000) id D630147B15; Tue, 29 Jun 2010 09:48:31 +0200 (CEST) Date: Tue, 29 Jun 2010 09:48:31 +0200 From: Anders Nordby To: Pyun YongHyeon Message-ID: <20100629074831.GA75332@fupp.net> References: <201006101804.o5AI4PEX024259@svn.freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: <201006101804.o5AI4PEX024259@svn.freebsd.org> User-Agent: Mutt/1.4.2.3i X-PGP-Key: http://anders.fix.no/pgp/ X-PGP-Key-FingerPrint: 1E0F C53C D8DF 6A8F EAAD 19C5 D12A BC9F 0083 5956 Cc: marcel@FreeBSD.org, jdc@parodius.com, svn-src-stable@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, svn-src-stable-7@freebsd.org Subject: Re: svn commit: r208995 - stable/7/sys/dev/bge X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 Jun 2010 08:06:22 -0000 Hi! Is it possible to get this fix into FreeBSD 7.3-RELEASE? Without this fix I have serious issues with my bge NICs: - packet loss around 10%. - transferrate (scp) is 10% of expected, 2 MB/sec instead of 20 when testing. - get "Corrupted MAC on input" while synchronizing large directories using rsync over SSH. It seems we also discussed this matter on -fs, where I had issues on a ZFS+NFS file server. After updating to a newer 8.1 install (which has the fix) the problem went away. If this can not make it into 7.3, I and other people using 7.x have to manually patch this or follow RELENG_7 which not everyone wants to. The bge driver is such a common server driver, I think this should be rolled back into affected releases. Regards, Anders. On Thu, Jun 10, 2010 at 06:04:25PM +0000, Pyun YongHyeon wrote: > Author: yongari > Date: Thu Jun 10 18:04:25 2010 > New Revision: 208995 > URL: http://svn.freebsd.org/changeset/base/208995 > > Log: > MFC r208862: > Fix a bug introduced in r199011. When bge(4) reuses loaded RX > buffers it should also reinitialize RX descriptors otherwise some > stale data could be passed to controller. This could end up with > mbuf double free or unexpected NULL pointer dereference in upper > stack. To fix the issue, save loaded buffer's length and > reinitialize RX descriptors with the saved value whenever bge(4) > reuses the loaded RX buffers. > While I'm here, increase the number of RX buffers to 512 from 256. > This simplifies RX buffer handling as well as giving more RX > buffers. Controller supports just fixed number of RX buffers > (i.e. 512) and bge(4) used to rely on hope that our CPU is fast > enough to keep up with the controller. With this change, bge(4) > will use 1MB for RX buffers but I don't think it would cause > problems in these days. > > Reported by: marcel > Tested by: marcel > > Modified: > stable/7/sys/dev/bge/if_bge.c > stable/7/sys/dev/bge/if_bgereg.h > Directory Properties: > stable/7/sys/ (props changed) > stable/7/sys/cddl/contrib/opensolaris/ (props changed) > stable/7/sys/contrib/dev/acpica/ (props changed) > stable/7/sys/contrib/pf/ (props changed) > > Modified: stable/7/sys/dev/bge/if_bge.c > ============================================================================== > --- stable/7/sys/dev/bge/if_bge.c Thu Jun 10 17:59:47 2010 (r208994) > +++ stable/7/sys/dev/bge/if_bge.c Thu Jun 10 18:04:25 2010 (r208995) > @@ -400,6 +400,8 @@ static void bge_setpromisc(struct bge_so > static void bge_setmulti(struct bge_softc *); > static void bge_setvlan(struct bge_softc *); > > +static __inline void bge_rxreuse_std(struct bge_softc *, int); > +static __inline void bge_rxreuse_jumbo(struct bge_softc *, int); > static int bge_newbuf_std(struct bge_softc *, int); > static int bge_newbuf_jumbo(struct bge_softc *, int); > static int bge_init_rx_ring_std(struct bge_softc *); > @@ -949,6 +951,7 @@ bge_newbuf_std(struct bge_softc *sc, int > sc->bge_cdata.bge_rx_std_dmamap[i] = sc->bge_cdata.bge_rx_std_sparemap; > sc->bge_cdata.bge_rx_std_sparemap = map; > sc->bge_cdata.bge_rx_std_chain[i] = m; > + sc->bge_cdata.bge_rx_std_seglen[i] = segs[0].ds_len; > r = &sc->bge_ldata.bge_rx_std_ring[sc->bge_std]; > r->bge_addr.bge_addr_lo = BGE_ADDR_LO(segs[0].ds_addr); > r->bge_addr.bge_addr_hi = BGE_ADDR_HI(segs[0].ds_addr); > @@ -1006,6 +1009,11 @@ bge_newbuf_jumbo(struct bge_softc *sc, i > sc->bge_cdata.bge_rx_jumbo_sparemap; > sc->bge_cdata.bge_rx_jumbo_sparemap = map; > sc->bge_cdata.bge_rx_jumbo_chain[i] = m; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][0] = 0; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][1] = 0; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][2] = 0; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][3] = 0; > + > /* > * Fill in the extended RX buffer descriptor. > */ > @@ -1018,18 +1026,22 @@ bge_newbuf_jumbo(struct bge_softc *sc, i > r->bge_addr3.bge_addr_lo = BGE_ADDR_LO(segs[3].ds_addr); > r->bge_addr3.bge_addr_hi = BGE_ADDR_HI(segs[3].ds_addr); > r->bge_len3 = segs[3].ds_len; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][3] = segs[3].ds_len; > case 3: > r->bge_addr2.bge_addr_lo = BGE_ADDR_LO(segs[2].ds_addr); > r->bge_addr2.bge_addr_hi = BGE_ADDR_HI(segs[2].ds_addr); > r->bge_len2 = segs[2].ds_len; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][2] = segs[2].ds_len; > case 2: > r->bge_addr1.bge_addr_lo = BGE_ADDR_LO(segs[1].ds_addr); > r->bge_addr1.bge_addr_hi = BGE_ADDR_HI(segs[1].ds_addr); > r->bge_len1 = segs[1].ds_len; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][1] = segs[1].ds_len; > case 1: > r->bge_addr0.bge_addr_lo = BGE_ADDR_LO(segs[0].ds_addr); > r->bge_addr0.bge_addr_hi = BGE_ADDR_HI(segs[0].ds_addr); > r->bge_len0 = segs[0].ds_len; > + sc->bge_cdata.bge_rx_jumbo_seglen[i][0] = segs[0].ds_len; > break; > default: > panic("%s: %d segments\n", __func__, nsegs); > @@ -1041,12 +1053,6 @@ bge_newbuf_jumbo(struct bge_softc *sc, i > return (0); > } > > -/* > - * The standard receive ring has 512 entries in it. At 2K per mbuf cluster, > - * that's 1MB or memory, which is a lot. For now, we fill only the first > - * 256 ring entries and hope that our CPU is fast enough to keep up with > - * the NIC. > - */ > static int > bge_init_rx_ring_std(struct bge_softc *sc) > { > @@ -1054,7 +1060,7 @@ bge_init_rx_ring_std(struct bge_softc *s > > bzero(sc->bge_ldata.bge_rx_std_ring, BGE_STD_RX_RING_SZ); > sc->bge_std = 0; > - for (i = 0; i < BGE_SSLOTS; i++) { > + for (i = 0; i < BGE_STD_RX_RING_CNT; i++) { > if ((error = bge_newbuf_std(sc, i)) != 0) > return (error); > BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); > @@ -1063,8 +1069,8 @@ bge_init_rx_ring_std(struct bge_softc *s > bus_dmamap_sync(sc->bge_cdata.bge_rx_std_ring_tag, > sc->bge_cdata.bge_rx_std_ring_map, BUS_DMASYNC_PREWRITE); > > - sc->bge_std = i - 1; > - bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, sc->bge_std); > + sc->bge_std = 0; > + bge_writembx(sc, BGE_MBX_RX_STD_PROD_LO, BGE_STD_RX_RING_CNT - 1); > > return (0); > } > @@ -1106,14 +1112,14 @@ bge_init_rx_ring_jumbo(struct bge_softc > bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, > sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_PREWRITE); > > - sc->bge_jumbo = i - 1; > + sc->bge_jumbo = 0; > > rcb = &sc->bge_ldata.bge_info.bge_jumbo_rx_rcb; > rcb->bge_maxlen_flags = BGE_RCB_MAXLEN_FLAGS(0, > BGE_RCB_FLAG_USE_EXT_RX_BD); > CSR_WRITE_4(sc, BGE_RX_JUMBO_RCB_MAXLEN_FLAGS, rcb->bge_maxlen_flags); > > - bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, sc->bge_jumbo); > + bge_writembx(sc, BGE_MBX_RX_JUMBO_PROD_LO, BGE_JUMBO_RX_RING_CNT - 1); > > return (0); > } > @@ -3299,6 +3305,33 @@ bge_reset(struct bge_softc *sc) > return(0); > } > > +static __inline void > +bge_rxreuse_std(struct bge_softc *sc, int i) > +{ > + struct bge_rx_bd *r; > + > + r = &sc->bge_ldata.bge_rx_std_ring[sc->bge_std]; > + r->bge_flags = BGE_RXBDFLAG_END; > + r->bge_len = sc->bge_cdata.bge_rx_std_seglen[i]; > + r->bge_idx = i; > + BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); > +} > + > +static __inline void > +bge_rxreuse_jumbo(struct bge_softc *sc, int i) > +{ > + struct bge_extrx_bd *r; > + > + r = &sc->bge_ldata.bge_rx_jumbo_ring[sc->bge_jumbo]; > + r->bge_flags = BGE_RXBDFLAG_JUMBO_RING | BGE_RXBDFLAG_END; > + r->bge_len0 = sc->bge_cdata.bge_rx_jumbo_seglen[i][0]; > + r->bge_len1 = sc->bge_cdata.bge_rx_jumbo_seglen[i][1]; > + r->bge_len2 = sc->bge_cdata.bge_rx_jumbo_seglen[i][2]; > + r->bge_len3 = sc->bge_cdata.bge_rx_jumbo_seglen[i][3]; > + r->bge_idx = i; > + BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); > +} > + > /* > * Frame reception handling. This is called if there's a frame > * on the receive return list. > @@ -3362,24 +3395,24 @@ bge_rxeof(struct bge_softc *sc, uint16_t > jumbocnt++; > m = sc->bge_cdata.bge_rx_jumbo_chain[rxidx]; > if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { > - BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); > + bge_rxreuse_jumbo(sc, rxidx); > continue; > } > if (bge_newbuf_jumbo(sc, rxidx) != 0) { > - BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); > + bge_rxreuse_jumbo(sc, rxidx); > ifp->if_iqdrops++; > continue; > } > BGE_INC(sc->bge_jumbo, BGE_JUMBO_RX_RING_CNT); > } else { > stdcnt++; > + m = sc->bge_cdata.bge_rx_std_chain[rxidx]; > if (cur_rx->bge_flags & BGE_RXBDFLAG_ERROR) { > - BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); > + bge_rxreuse_std(sc, rxidx); > continue; > } > - m = sc->bge_cdata.bge_rx_std_chain[rxidx]; > if (bge_newbuf_std(sc, rxidx) != 0) { > - BGE_INC(sc->bge_std, BGE_STD_RX_RING_CNT); > + bge_rxreuse_std(sc, rxidx); > ifp->if_iqdrops++; > continue; > } > > Modified: stable/7/sys/dev/bge/if_bgereg.h > ============================================================================== > --- stable/7/sys/dev/bge/if_bgereg.h Thu Jun 10 17:59:47 2010 (r208994) > +++ stable/7/sys/dev/bge/if_bgereg.h Thu Jun 10 18:04:25 2010 (r208995) > @@ -2561,6 +2561,8 @@ struct bge_chain_data { > struct mbuf *bge_tx_chain[BGE_TX_RING_CNT]; > struct mbuf *bge_rx_std_chain[BGE_STD_RX_RING_CNT]; > struct mbuf *bge_rx_jumbo_chain[BGE_JUMBO_RX_RING_CNT]; > + int bge_rx_std_seglen[BGE_STD_RX_RING_CNT]; > + int bge_rx_jumbo_seglen[BGE_JUMBO_RX_RING_CNT][4]; > }; > > struct bge_dmamap_arg { > _______________________________________________ > svn-src-stable-7@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/svn-src-stable-7 > To unsubscribe, send any mail to "svn-src-stable-7-unsubscribe@freebsd.org" -- Anders.