From owner-svn-src-head@FreeBSD.ORG Thu Apr 16 11:38:07 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67327106566C; Thu, 16 Apr 2009 11:38:07 +0000 (UTC) (envelope-from raj@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3B4A38FC08; Thu, 16 Apr 2009 11:38:07 +0000 (UTC) (envelope-from raj@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n3GBc7CW079181; Thu, 16 Apr 2009 11:38:07 GMT (envelope-from raj@svn.freebsd.org) Received: (from raj@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3GBc7v9079180; Thu, 16 Apr 2009 11:38:07 GMT (envelope-from raj@svn.freebsd.org) Message-Id: <200904161138.n3GBc7v9079180@svn.freebsd.org> From: Rafal Jaworowski Date: Thu, 16 Apr 2009 11:38:07 +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: r191142 - head/sys/dev/mge X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Apr 2009 11:38:07 -0000 Author: raj Date: Thu Apr 16 11:38:06 2009 New Revision: 191142 URL: http://svn.freebsd.org/changeset/base/191142 Log: mge(4): fix two bugs, which were leading to crash/hang under very heavy network load. 1. Leave the RX interrupt routine if there is no mbuf available. 2. Properly initialize and track tx_desc_used_count counter so as not to leak mbuf while traversing used descriptors. Obtained from: Semihalf Modified: head/sys/dev/mge/if_mge.c Modified: head/sys/dev/mge/if_mge.c ============================================================================== --- head/sys/dev/mge/if_mge.c Thu Apr 16 11:21:52 2009 (r191141) +++ head/sys/dev/mge/if_mge.c Thu Apr 16 11:38:06 2009 (r191142) @@ -642,6 +642,7 @@ mge_attach(device_t dev) sc->tx_desc_curr = 0; sc->rx_desc_curr = 0; sc->tx_desc_used_idx = 0; + sc->tx_desc_used_count = 0; /* Configure defaults for interrupts coalescing */ sc->rx_ic_time = 768; @@ -899,6 +900,7 @@ mge_init_locked(void *arg) sc->tx_desc_curr = 0; sc->rx_desc_curr = 0; sc->tx_desc_used_idx = 0; + sc->tx_desc_used_count = 0; /* Enable RX descriptors */ for (i = 0; i < MGE_RX_DESC_NUM; i++) { @@ -1022,7 +1024,7 @@ mge_intr_rx_locked(struct mge_softc *sc, MGE_RECEIVE_LOCK_ASSERT(sc); - while(count != 0) { + while (count != 0) { dw = &sc->mge_rx_desc[sc->rx_desc_curr]; bus_dmamap_sync(sc->mge_desc_dtag, dw->desc_dmap, BUS_DMASYNC_POSTREAD); @@ -1033,7 +1035,6 @@ mge_intr_rx_locked(struct mge_softc *sc, if ((status & MGE_DMA_OWNED) != 0) break; - sc->rx_desc_curr = (++sc->rx_desc_curr % MGE_RX_DESC_NUM); if (dw->mge_desc->byte_count && ~(status & MGE_ERR_SUMMARY)) { @@ -1044,6 +1045,10 @@ mge_intr_rx_locked(struct mge_softc *sc, dw->mge_desc->byte_count - ETHER_CRC_LEN, 0, ifp, NULL); + if (mb == NULL) + /* Give up if no mbufs */ + break; + mb->m_len -= 2; mb->m_pkthdr.len -= 2; mb->m_data += 2; @@ -1058,6 +1063,7 @@ mge_intr_rx_locked(struct mge_softc *sc, dw->mge_desc->byte_count = 0; dw->mge_desc->cmd_status = MGE_RX_ENABLE_INT | MGE_DMA_OWNED; + sc->rx_desc_curr = (++sc->rx_desc_curr % MGE_RX_DESC_NUM); bus_dmamap_sync(sc->mge_desc_dtag, dw->desc_dmap, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1514,7 +1520,8 @@ mge_stop(struct mge_softc *sc) MGE_WRITE(sc, MGE_RX_QUEUE_CMD, MGE_DISABLE_RXQ_ALL); /* Remove pending data from TX queue */ - while (sc->tx_desc_used_idx < sc->tx_desc_curr) { + while (sc->tx_desc_used_idx != sc->tx_desc_curr && + sc->tx_desc_used_count) { /* Get the descriptor */ dw = &sc->mge_tx_desc[sc->tx_desc_used_idx]; desc = dw->mge_desc; @@ -1529,6 +1536,7 @@ mge_stop(struct mge_softc *sc) sc->tx_desc_used_idx = (++sc->tx_desc_used_idx) % MGE_TX_DESC_NUM; + sc->tx_desc_used_count--; bus_dmamap_sync(sc->mge_tx_dtag, dw->buffer_dmap, BUS_DMASYNC_POSTWRITE);