kern/119205: [patch] Collect various stats regarding dc(4) interrupts

Peter Jeremy peterjeremy at optushome.com.au
Mon Dec 31 15:20:02 PST 2007


>Number:         119205
>Category:       kern
>Synopsis:       [patch] Collect various stats regarding dc(4) interrupts
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 31 23:20:01 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator:     Peter Jeremy
>Release:        FreeBSD 6.3-PRERELEASE amd64
>Organization:
n/a
>Environment:
System: FreeBSD turion.vk2pj.dyndns.org 6.3-PRERELEASE FreeBSD 6.3-PRERELEASE #31: Wed Dec 26 09:23:54 EST 2007 root at turion.vk2pj.dyndns.org:/usr/obj/usr/src/sys/turion amd64

>Description:
	I wrote the attached patch some time ago to try and identify
	the breakdown of dc(4) interrupts as part of some investigations
	into the performance of a dc NIC that I was using.  It adds a new
	"hw.dc" sysctl tree and reports total interrupts, interrupt
	categories (abnormal, bus_err, normal, rx_nobuf, rx_ok,
	rx_watchdogtimeout, tx_idle, tx_nobuf, tx_ok, tx_underrun) and
	receiver resync events.  Note that this patch accumulates totals
	for all dc(4) devices, not per-device.

	The new sysctl nodes are:
hw.dc.abnormal	Abnormal interrupts
hw.dc.bus_err	"Bus error" interrupts
hw.dc.ints	Total interrupts
hw.dc.normal	"normal" interrupts
hw.dc.resync1	Resync needed following normal receive interrupt
hw.dc.resync2	Resync needed following watchdog timeout or no buffers
hw.dc.rx_nobuf	No receive buffers
hw.dc.rx_ok	Normal receive interrupt
hw.dc.rx_watdogtimeo  Watchdog timeout on receive
hw.dc.tx_idle	Transmitter idle
hw.dc.tx_nobuf	No transmit buffers
hw.dc.tx_ok	Normal transmit interrupt.
hw.dc.tx_underrun Transmit underrun

	It's possible they may be of use to someone else.  

>How-To-Repeat:
	code inspection
>Fix:
	See attached patches for RELENG_6 and -current/RELENG_7.  Note that
	the latter patch compiles cleanly but has not been tested.

--- dc.releng6.patch begins here ---
Index: sys/pci/if_dc.c
===================================================================
RCS file: /usr/ncvs/src/sys/pci/Attic/if_dc.c,v
retrieving revision 1.160.2.13
diff -u -r1.160.2.13 if_dc.c
--- sys/pci/if_dc.c	15 Sep 2007 10:00:51 -0000	1.160.2.13
+++ sys/pci/if_dc.c	25 Dec 2007 20:42:18 -0000
@@ -342,6 +342,47 @@
     "do not m_devget() in dc driver");
 #endif
 
+SYSCTL_NODE(_hw, OID_AUTO, dc, CTLFLAG_RD, 0, "if_dc parameters");
+
+static int dc_ints;
+SYSCTL_INT(_hw_dc, OID_AUTO, ints, CTLFLAG_RW, &dc_ints, 0, "");
+
+static int dc_isr_abnormal;
+SYSCTL_INT(_hw_dc, OID_AUTO, abnormal, CTLFLAG_RW, &dc_isr_abnormal, 0, "");
+
+static int dc_isr_bus_err;
+SYSCTL_INT(_hw_dc, OID_AUTO, bus_err, CTLFLAG_RW, &dc_isr_bus_err, 0, "");
+
+static int dc_isr_normal;
+SYSCTL_INT(_hw_dc, OID_AUTO, normal, CTLFLAG_RW, &dc_isr_normal, 0, "");
+
+static int dc_isr_rx_nobuf;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_nobuf, CTLFLAG_RW, &dc_isr_rx_nobuf, 0, "");
+
+static int dc_isr_rx_ok;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_ok, CTLFLAG_RW, &dc_isr_rx_ok, 0, "");
+
+static int dc_isr_rx_watdogtimeo;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_watdogtimeo, CTLFLAG_RW, &dc_isr_rx_watdogtimeo, 0, "");
+
+static int dc_isr_tx_idle;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_idle, CTLFLAG_RW, &dc_isr_tx_idle, 0, "");
+
+static int dc_isr_tx_nobuf;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_nobuf, CTLFLAG_RW, &dc_isr_tx_nobuf, 0, "");
+
+static int dc_isr_tx_ok;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_ok, CTLFLAG_RW, &dc_isr_tx_ok, 0, "");
+
+static int dc_isr_tx_underrun;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_underrun, CTLFLAG_RW, &dc_isr_tx_underrun, 0, "");
+
+static int dc_rx_resync1;
+SYSCTL_INT(_hw_dc, OID_AUTO, resync1, CTLFLAG_RW, &dc_rx_resync1, 0, "");
+
+static int dc_rx_resync2;
+SYSCTL_INT(_hw_dc, OID_AUTO, resync2, CTLFLAG_RW, &dc_rx_resync2, 0, "");
+
 DRIVER_MODULE(dc, cardbus, dc_driver, dc_devclass, 0, 0);
 DRIVER_MODULE(dc, pci, dc_driver, dc_devclass, 0, 0);
 DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0);
@@ -3097,26 +3138,43 @@
 	/* Disable interrupts. */
 	CSR_WRITE_4(sc, DC_IMR, 0x00000000);
 
+	dc_ints++;
+
 	while (((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) &&
 	    status != 0xFFFFFFFF &&
 	    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 
 		CSR_WRITE_4(sc, DC_ISR, status);
 
+		if (status & DC_ISR_ABNORMAL)
+			dc_isr_abnormal++;
+		if (status & DC_ISR_NORMAL)
+			dc_isr_normal++;
+
 		if (status & DC_ISR_RX_OK) {
 			int		curpkts;
+
+			dc_isr_rx_ok++;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
-				while (dc_rx_resync(sc))
+				while (dc_rx_resync(sc)) {
+					dc_rx_resync1++;
 					dc_rxeof(sc);
+				}
 			}
 		}
 
-		if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF))
+	 	if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF)) {
+		 	if (status & DC_ISR_TX_OK)
+				dc_isr_tx_ok++;
+		 	if (status & DC_ISR_TX_NOBUF)
+				dc_isr_tx_nobuf++;
 			dc_txeof(sc);
+		}
 
 		if (status & DC_ISR_TX_IDLE) {
+			dc_isr_tx_idle++;
 			dc_txeof(sc);
 			if (sc->dc_cdata.dc_tx_cnt) {
 				DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
@@ -3124,21 +3182,30 @@
 			}
 		}
 
-		if (status & DC_ISR_TX_UNDERRUN)
+		if (status & DC_ISR_TX_UNDERRUN) {
+			dc_isr_tx_underrun++;
 			dc_tx_underrun(sc);
+		}
 
 		if ((status & DC_ISR_RX_WATDOGTIMEO)
 		    || (status & DC_ISR_RX_NOBUF)) {
 			int		curpkts;
+			if (status & DC_ISR_RX_WATDOGTIMEO)
+				dc_isr_rx_watdogtimeo++;
+			if (status & DC_ISR_RX_NOBUF)
+				dc_isr_rx_nobuf++;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
-				while (dc_rx_resync(sc))
+				while (dc_rx_resync(sc)) {
+					dc_rx_resync2++;
 					dc_rxeof(sc);
+				}
 			}
 		}
 
 		if (status & DC_ISR_BUS_ERR) {
+			dc_isr_bus_err++;
 			dc_reset(sc);
 			dc_init_locked(sc);
 		}
--- dc.releng6.patch ends here ---

--- dc.current.patch begins here ---
Index: sys/dev/dc/if_dc.c
===================================================================
RCS file: /usr/ncvs/src/sys/dev/dc/if_dc.c,v
retrieving revision 1.193
diff -u -r1.193 if_dc.c
--- sys/dev/dc/if_dc.c	22 Nov 2007 02:44:58 -0000	1.193
+++ sys/dev/dc/if_dc.c	23 Nov 2007 16:07:17 -0000
@@ -104,6 +104,7 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h>
+#include <sys/sysctl.h>
 
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -333,6 +334,47 @@
 
 static devclass_t dc_devclass;
 
+SYSCTL_NODE(_hw, OID_AUTO, dc, CTLFLAG_RD, 0, "if_dc parameters");
+
+static int dc_ints;
+SYSCTL_INT(_hw_dc, OID_AUTO, ints, CTLFLAG_RW, &dc_ints, 0, "");
+
+static int dc_isr_abnormal;
+SYSCTL_INT(_hw_dc, OID_AUTO, abnormal, CTLFLAG_RW, &dc_isr_abnormal, 0, "");
+
+static int dc_isr_bus_err;
+SYSCTL_INT(_hw_dc, OID_AUTO, bus_err, CTLFLAG_RW, &dc_isr_bus_err, 0, "");
+
+static int dc_isr_normal;
+SYSCTL_INT(_hw_dc, OID_AUTO, normal, CTLFLAG_RW, &dc_isr_normal, 0, "");
+
+static int dc_isr_rx_nobuf;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_nobuf, CTLFLAG_RW, &dc_isr_rx_nobuf, 0, "");
+
+static int dc_isr_rx_ok;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_ok, CTLFLAG_RW, &dc_isr_rx_ok, 0, "");
+
+static int dc_isr_rx_watdogtimeo;
+SYSCTL_INT(_hw_dc, OID_AUTO, rx_watdogtimeo, CTLFLAG_RW, &dc_isr_rx_watdogtimeo, 0, "");
+
+static int dc_isr_tx_idle;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_idle, CTLFLAG_RW, &dc_isr_tx_idle, 0, "");
+
+static int dc_isr_tx_nobuf;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_nobuf, CTLFLAG_RW, &dc_isr_tx_nobuf, 0, "");
+
+static int dc_isr_tx_ok;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_ok, CTLFLAG_RW, &dc_isr_tx_ok, 0, "");
+
+static int dc_isr_tx_underrun;
+SYSCTL_INT(_hw_dc, OID_AUTO, tx_underrun, CTLFLAG_RW, &dc_isr_tx_underrun, 0, "");
+
+static int dc_rx_resync1;
+SYSCTL_INT(_hw_dc, OID_AUTO, resync1, CTLFLAG_RW, &dc_rx_resync1, 0, "");
+
+static int dc_rx_resync2;
+SYSCTL_INT(_hw_dc, OID_AUTO, resync2, CTLFLAG_RW, &dc_rx_resync2, 0, "");
+
 DRIVER_MODULE(dc, cardbus, dc_driver, dc_devclass, 0, 0);
 DRIVER_MODULE(dc, pci, dc_driver, dc_devclass, 0, 0);
 DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0);
@@ -3065,26 +3107,43 @@
 	/* Disable interrupts. */
 	CSR_WRITE_4(sc, DC_IMR, 0x00000000);
 
+	dc_ints++;
+
 	while (((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) &&
 	    status != 0xFFFFFFFF &&
 	    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 
 		CSR_WRITE_4(sc, DC_ISR, status);
 
+		if (status & DC_ISR_ABNORMAL)
+			dc_isr_abnormal++;
+		if (status & DC_ISR_NORMAL)
+			dc_isr_normal++;
+
 		if (status & DC_ISR_RX_OK) {
 			int		curpkts;
+
+			dc_isr_rx_ok++;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
-				while (dc_rx_resync(sc))
+				while (dc_rx_resync(sc)) {
+					dc_rx_resync1++;
 					dc_rxeof(sc);
+				}
 			}
 		}
 
-		if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF))
+	 	if (status & (DC_ISR_TX_OK | DC_ISR_TX_NOBUF)) {
+		 	if (status & DC_ISR_TX_OK)
+				dc_isr_tx_ok++;
+		 	if (status & DC_ISR_TX_NOBUF)
+				dc_isr_tx_nobuf++;
 			dc_txeof(sc);
+		}
 
 		if (status & DC_ISR_TX_IDLE) {
+			dc_isr_tx_idle++;
 			dc_txeof(sc);
 			if (sc->dc_cdata.dc_tx_cnt) {
 				DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
@@ -3092,21 +3151,30 @@
 			}
 		}
 
-		if (status & DC_ISR_TX_UNDERRUN)
+		if (status & DC_ISR_TX_UNDERRUN) {
+			dc_isr_tx_underrun++;
 			dc_tx_underrun(sc);
+		}
 
 		if ((status & DC_ISR_RX_WATDOGTIMEO)
 		    || (status & DC_ISR_RX_NOBUF)) {
 			int		curpkts;
+			if (status & DC_ISR_RX_WATDOGTIMEO)
+				dc_isr_rx_watdogtimeo++;
+			if (status & DC_ISR_RX_NOBUF)
+				dc_isr_rx_nobuf++;
 			curpkts = ifp->if_ipackets;
 			dc_rxeof(sc);
 			if (curpkts == ifp->if_ipackets) {
-				while (dc_rx_resync(sc))
+				while (dc_rx_resync(sc)) {
+					dc_rx_resync2++;
 					dc_rxeof(sc);
+				}
 			}
 		}
 
 		if (status & DC_ISR_BUS_ERR) {
+			dc_isr_bus_err++;
 			dc_reset(sc);
 			dc_init_locked(sc);
 		}
--- dc.current.patch ends here ---


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


More information about the freebsd-bugs mailing list