if_sk patch to get more info from people with problems

John-Mark Gurney gurney_j at resnet.uoregon.edu
Tue Nov 2 11:08:54 PST 2004


Peter Edwards wrote this message on Tue, Nov 02, 2004 at 17:56 +0000:
> A (very) quick look at the source reveals that buffers are allocated
> via  sk_rxeof()->sk_newbuf()->sk_jalloc() in the interrupt receive
> function, with the softc lock held in sk_rxeof().
> 
> They're freed by the mbuf system via a call to sk_jfree(), but that
> doesn't hold the SK_LOCK. Is this possibly the source of the
> corruption problems? What am I missing?
> This compiles, anyway :-)

Well, try the attached patch (it also includes my changes from a previous
diff) that will see what happens...  Make sure you have your kernel
compiled with WITNESS and INVARIANTS...  If you hit one of these
asserts, make sure you post the back trace...

Thanks for the testing..

-- 
  John-Mark Gurney				Voice: +1 415 225 5579

     "All that I will do, has been done, All that I have, has not."
-------------- next part --------------
Index: if_sk.c
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_sk.c,v
retrieving revision 1.87
diff -u -r1.87 if_sk.c
--- if_sk.c	1 Nov 2004 17:21:04 -0000	1.87
+++ if_sk.c	2 Nov 2004 19:05:29 -0000
@@ -1076,6 +1076,8 @@
 {
 	struct sk_jpool_entry   *entry;
 	
+	SK_IF_LOCK_ASSERT(sc_if);
+
 	entry = SLIST_FIRST(&sc_if->sk_jfree_listhead);
 	
 	if (entry == NULL) {
@@ -1108,6 +1110,8 @@
 	if (sc_if == NULL)
 		panic("sk_jfree: didn't get softc pointer!");
 
+	SK_IF_LOCK_ASSERT(sc_if);
+
 	/* calculate the slot this buffer belongs to */
 	i = ((vm_offset_t)buf
 	     - (vm_offset_t)sc_if->sk_cdata.sk_jumbo_buf) / SK_JLEN;
@@ -1845,11 +1849,13 @@
 	}
 
 	/* Transmit */
-	sc_if->sk_cdata.sk_tx_prod = idx;
-	CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
+	if (idx != sc_if->sk_cdata.sk_tx_prod) {
+		sc_if->sk_cdata.sk_tx_prod = idx;
+		CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
 
-	/* Set a timeout in case the chip goes out to lunch. */
-	ifp->if_timer = 5;
+		/* Set a timeout in case the chip goes out to lunch. */
+		ifp->if_timer = 5;
+	}
 	SK_IF_UNLOCK(sc_if);
 
 	return;
@@ -1989,13 +1995,15 @@
 		}
 		sc_if->sk_cdata.sk_tx_cnt--;
 		SK_INC(idx, SK_TX_RING_CNT);
-		ifp->if_timer = 0;
 	}
 
-	sc_if->sk_cdata.sk_tx_cons = idx;
-
-	if (cur_tx != NULL)
+	if (sc_if->sk_cdata.sk_tx_cnt == 0) {
+		ifp->if_timer = 0;
 		ifp->if_flags &= ~IFF_OACTIVE;
+	} else /* nudge chip to keep tx ring moving */
+		CSR_WRITE_4(sc, sc_if->sk_tx_bmu, SK_TXBMU_TX_START);
+
+	sc_if->sk_cdata.sk_tx_cons = idx;
 
 	return;
 }
Index: if_skreg.h
===================================================================
RCS file: /home/ncvs/src/sys/pci/if_skreg.h,v
retrieving revision 1.22
diff -u -r1.22 if_skreg.h
--- if_skreg.h	20 Aug 2004 06:22:04 -0000	1.22
+++ if_skreg.h	2 Nov 2004 19:05:29 -0000
@@ -1441,6 +1441,7 @@
 #define	SK_LOCK_ASSERT(_sc)	mtx_assert(&(_sc)->sk_mtx, MA_OWNED)
 #define	SK_IF_LOCK(_sc)		SK_LOCK((_sc)->sk_softc)
 #define	SK_IF_UNLOCK(_sc)	SK_UNLOCK((_sc)->sk_softc)
+#define	SK_IF_LOCK_ASSERT(_sc)	SK_LOCK_ASSERT((_sc)->sk_softc)
 
 /* Softc for each logical interface */
 struct sk_if_softc {


More information about the freebsd-amd64 mailing list