Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Apr 2007 15:53:27 GMT
From:      Vladimir Ivanov<wawa@yandex-team.ru>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/111415: Serious bug in bce (and bfe?) ethernet driver
Message-ID:  <200704091553.l39FrRc2058443@www.freebsd.org>
Resent-Message-ID: <200704091600.l39G09vi076855@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         111415
>Category:       kern
>Synopsis:       Serious bug in bce (and bfe?) ethernet driver
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 09 16:00:08 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Vladimir Ivanov
>Release:        RELENG_6
>Organization:
Yandex LLC
>Environment:
FreeBSD bernoulli.yandex.net 6.2-STABLE FreeBSD 6.2-STABLE #26: Sat Apr  7 14:17:48 MSD 2007     root@bernoulli.yandex.net:/usr/obj/usr/src/sys/CORE-RTR-RELENG_6  i386

>Description:
We have reported serious bug with em driver
(http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/87418) one year and half ago.

The bug cause RX queue corruption and interface stuck.

Unfortunately some freebsd ethernet drivers reproduced this bug.
You can see same kind of bug in bce and ixgb and bfe(?). 

I've attached draft patch for bce driver (RELENG_6) to solve the problem.

We've started to test this patch revision one week before on twenty boxes. They seems to be Ok still.


>How-To-Repeat:

>Fix:


Patch attached with submission follows:

--- if_bce.c.orig	Fri Mar 16 00:58:25 2007
+++ if_bce.c	Thu Apr  5 02:57:39 2007
@@ -3943,6 +3943,8 @@ bce_rx_intr(struct bce_softc *sc)
 		unsigned int len;
 		u32 status;
 
+		m = NULL;
+
 		/* Convert the producer/consumer indices to an actual rx_bd index. */
 		sw_chain_cons = RX_CHAIN_IDX(sw_cons);
 		sw_chain_prod = RX_CHAIN_IDX(sw_prod);
@@ -4131,16 +4133,30 @@ bce_rx_intr(struct bce_softc *sc)
 			ifp->if_ipackets++;
 			DBPRINT(sc, BCE_VERBOSE_RECV, "%s(): Passing received frame up.\n",
 				__FUNCTION__);
-			BCE_UNLOCK(sc);
-			(*ifp->if_input)(ifp, m);
-			DBRUNIF(1, sc->rx_mbuf_alloc--);
-			BCE_LOCK(sc);
 
 bce_rx_int_next_rx:
 			sw_prod = NEXT_RX_BD(sw_prod);
 		}
 
 		sw_cons = NEXT_RX_BD(sw_cons);
+
+		if (m) {
+			sc->rx_cons = sw_cons;
+			sc->rx_prod = sw_prod;
+			sc->rx_prod_bseq = sw_prod_bseq;
+
+			BCE_UNLOCK(sc);
+			(*ifp->if_input)(ifp, m);
+			BCE_LOCK(sc);
+                        DBRUNIF(1, sc->rx_mbuf_alloc--);
+
+		        sw_cons = sc->rx_cons;
+      			sw_prod = sc->rx_prod;
+		        sw_prod_bseq = sc->rx_prod_bseq;
+			hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
+			if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
+				hw_cons++;
+		}
 
 		/* Refresh hw_cons to see if there's new work */
 		if (sw_cons == hw_cons) {

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200704091553.l39FrRc2058443>