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