Date: Tue, 1 Jan 2008 10:19:37 +1100 (EST) From: Peter Jeremy <peterjeremy@optushome.com.au> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/119205: [patch] Collect various stats regarding dc(4) interrupts Message-ID: <200712312319.lBVNJbDw062120@turion.vk2pj.dyndns.org> Resent-Message-ID: <200712312320.lBVNK18p019619@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712312319.lBVNJbDw062120>