From owner-svn-src-all@FreeBSD.ORG Sun Nov 22 19:44:11 2009 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 8B3A41065672; Sun, 22 Nov 2009 19:44:11 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7121A8FC1C; Sun, 22 Nov 2009 19:44:11 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAMJiBd8027752; Sun, 22 Nov 2009 19:44:11 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAMJiBkD027750; Sun, 22 Nov 2009 19:44:11 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <200911221944.nAMJiBkD027750@svn.freebsd.org> From: Pyun YongHyeon Date: Sun, 22 Nov 2009 19:44:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199666 - head/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: Sun, 22 Nov 2009 19:44:11 -0000 Author: yongari Date: Sun Nov 22 19:44:11 2009 New Revision: 199666 URL: http://svn.freebsd.org/changeset/base/199666 Log: Rearrange bge_start_locked to see we can send more frames by checking IFF_DRV_RUNNING and IFF_DRV_OACTIVE flags. Also if we have less than 16 free send BDs set IFF_DRV_OACTIVE and try it later. Previously bge(4) used to reserve 16 free send BDs after loading dma maps but hardware just need one reserved send BD. If prouder index has the same value of consumer index it means the Tx queue is empty. While I'm here check IFQ_DRV_IS_EMPTY first to save one lock operation. Modified: head/sys/dev/bge/if_bge.c Modified: head/sys/dev/bge/if_bge.c ============================================================================== --- head/sys/dev/bge/if_bge.c Sun Nov 22 19:17:32 2009 (r199665) +++ head/sys/dev/bge/if_bge.c Sun Nov 22 19:44:11 2009 (r199666) @@ -3683,11 +3683,8 @@ bge_encap(struct bge_softc *sc, struct m } else if (error != 0) return (error); - /* - * Sanity check: avoid coming within 16 descriptors - * of the end of the ring. - */ - if (nsegs > (BGE_TX_RING_CNT - sc->bge_txcnt - 16)) { + /* Check if we have enough free send BDs. */ + if (sc->bge_txcnt + nsegs >= BGE_TX_RING_CNT) { bus_dmamap_unload(sc->bge_cdata.bge_tx_mtag, map); return (ENOBUFS); } @@ -3752,18 +3749,25 @@ static void bge_start_locked(struct ifnet *ifp) { struct bge_softc *sc; - struct mbuf *m_head = NULL; + struct mbuf *m_head; uint32_t prodidx; - int count = 0; + int count; sc = ifp->if_softc; + BGE_LOCK_ASSERT(sc); - if (!sc->bge_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + if (!sc->bge_link || + (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) return; prodidx = sc->bge_tx_prodidx; - while(sc->bge_cdata.bge_tx_chain[prodidx] == NULL) { + for (count = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd);) { + if (sc->bge_txcnt > BGE_TX_RING_CNT - 16) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -3816,24 +3820,22 @@ bge_start_locked(struct ifnet *ifp) #endif } - if (count == 0) - /* No packets were dequeued. */ - return; - - bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag, - sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE); - /* Transmit. */ - bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); - /* 5700 b2 errata */ - if (sc->bge_chiprev == BGE_CHIPREV_5700_BX) + if (count > 0) { + bus_dmamap_sync(sc->bge_cdata.bge_tx_ring_tag, + sc->bge_cdata.bge_tx_ring_map, BUS_DMASYNC_PREWRITE); + /* Transmit. */ bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); + /* 5700 b2 errata */ + if (sc->bge_chiprev == BGE_CHIPREV_5700_BX) + bge_writembx(sc, BGE_MBX_TX_HOST_PROD0_LO, prodidx); - sc->bge_tx_prodidx = prodidx; + sc->bge_tx_prodidx = prodidx; - /* - * Set a timeout in case the chip goes out to lunch. - */ - sc->bge_timer = 5; + /* + * Set a timeout in case the chip goes out to lunch. + */ + sc->bge_timer = 5; + } } /*