NetBSD Problem Report #31837
From www@netbsd.org Sun Oct 16 17:45:09 2005
Return-Path: <www@netbsd.org>
Received: by narn.netbsd.org (Postfix, from userid 31301)
id 4DCA563B900; Sun, 16 Oct 2005 17:45:09 +0000 (UTC)
Message-Id: <20051016174509.4DCA563B900@narn.netbsd.org>
Date: Sun, 16 Oct 2005 17:45:09 +0000 (UTC)
From: john32979@gmail.com
Reply-To: john32979@gmail.com
To: gnats-bugs@netbsd.org
Subject: sip driver receive buffer overrun diminishes the receive capabilities of the driver
X-Send-Pr-Version: www-1.0
>Number: 31837
>Category: kern
>Synopsis: sip driver receive buffer overrun diminishes the receive capabilities of the driver
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Oct 16 17:46:00 +0000 2005
>Originator: John Yau
>Release: NetBSD 2.0
>Organization:
>Environment:
>Description:
After a receive buffer overrun, the throughput of the sip interface halves. Setting the buffer ownership back to the sip card if the device is idle after detecting a buffer overrun seems to fix the problem.
>How-To-Repeat:
Trigger a receive buffer overrun by sending large amounts of data on a PC Engines WRAP board. After recovering from the buffer overrun, performance degrades severely.
>Fix:
Index: if_sip.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_sip.c,v
retrieving revision 1.87.2.1
diff -u -r1.87.2.1 if_sip.c
--- if_sip.c 28 May 2004 07:10:38 -0000 1.87.2.1
+++ if_sip.c 16 Oct 2005 17:38:54 -0000
@@ -1504,8 +1504,10 @@
{
struct sip_softc *sc = arg;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
- u_int32_t isr;
+ u_int32_t isr, cmdsts;
int handled = 0;
+ int i;
+ struct sip_rxsoft *rxs;
for (;;) {
/* Reading clears interrupt. */
@@ -1536,7 +1538,35 @@
if (isr & ISR_RXIDLE) {
printf("%s: receive ring overrun\n",
sc->sc_dev.dv_xname);
-
+ /* jyau
+ *
+ * Go through the receive descriptors and
+ * reset the ownership back to the card.
+ * We drop all the packets currently in the
+ * receive queue.
+ */
+ for (i = sc->sc_rxptr;; i = SIP_NEXTRX(i)) {
+ rxs = &sc->sc_rxsoft[i];
+ SIP_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ cmdsts = le32toh(sc->sc_rxdescs[i].sipd_cmdsts);
+ /*
+ * NOTE: OWN is set if owned by _consumer_. We're the
+ * consumer of the receive ring, so if the bit is clear,
+ * we have processed all of the packets.
+ */
+ if ((cmdsts & CMDSTS_OWN) == 0) {
+ /*
+ * We have processed all of the receive buffers.
+ */
+ break;
+ }
+ ifp->if_ierrors++;
+ SIP_INIT_RXDESC(sc, i);
+ bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
+ rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
+ printf("%s, Cleared rx desc %d\n",
+ sc->sc_dev.dv_xname, i);
+ }
/* Get the receive process going again. */
bus_space_write_4(sc->sc_st, sc->sc_sh,
SIP_RXDP, SIP_CDRXADDR(sc, sc->sc_rxptr));
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.