From owner-svn-src-head@FreeBSD.ORG Tue Apr 5 06:46:08 2011 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 51B90106564A; Tue, 5 Apr 2011 06:46:08 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3F6D08FC12; Tue, 5 Apr 2011 06:46:08 +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 p356k88R008409; Tue, 5 Apr 2011 06:46:08 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p356k8Oh008407; Tue, 5 Apr 2011 06:46:08 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201104050646.p356k8Oh008407@svn.freebsd.org> From: Adrian Chadd Date: Tue, 5 Apr 2011 06:46:08 +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: r220357 - head/sys/mips/atheros 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: Tue, 05 Apr 2011 06:46:08 -0000 Author: adrian Date: Tue Apr 5 06:46:07 2011 New Revision: 220357 URL: http://svn.freebsd.org/changeset/base/220357 Log: if_arge has had a strange bug that only appears during high traffic levels. TX would hang, RX wouldn't. A bit of digging showed the interface send queue was full, but IFF_DRV_OACTIVE was clear and the hardware TX queue was empty. It turns out that there wasn't a check to drain the interface send queue once hardware TX had completed, so if the interface send queue had filled up in the meantime, subsequent packets would be dropped by the higher layers and if_start (and thus arge_start()) would never be called. The fix is simple - call arge_start_locked() in the software interrupt handler after the hardware TX queue has been handled or a TX underrun occured. This way the interface send queue gets drained. Modified: head/sys/mips/atheros/if_arge.c Modified: head/sys/mips/atheros/if_arge.c ============================================================================== --- head/sys/mips/atheros/if_arge.c Tue Apr 5 06:33:35 2011 (r220356) +++ head/sys/mips/atheros/if_arge.c Tue Apr 5 06:46:07 2011 (r220357) @@ -1855,6 +1855,27 @@ arge_intr(void *arg) } /* + * If we've finished TXing and there's space for more packets + * to be queued for TX, do so. Otherwise we may end up in a + * situation where the interface send queue was filled + * whilst the hardware queue was full, then the hardware + * queue was drained by the interface send queue wasn't, + * and thus if_start() is never called to kick-start + * the send process (and all subsequent packets are simply + * discarded. + * + * XXX TODO: make sure that the hardware deals nicely + * with the possibility of the queue being enabled above + * after a TX underrun, then having the hardware queue added + * to below. + */ + if (status & (DMA_INTR_TX_PKT_SENT | DMA_INTR_TX_UNDERRUN) && + (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { + if (!IFQ_IS_EMPTY(&ifp->if_snd)) + arge_start_locked(ifp); + } + + /* * We handled all bits, clear status */ sc->arge_intr_status = 0;