On Wed, Jan 16, 2013 at 01:38:01PM +1100, Darren Tucker wrote:
> On Mon, Jan 14, 2013 at 10:10:55PM +1100, Darren Tucker wrote:
> > On my ALIX, it increase the IP routing throughput from 80Mbit/s to
> > 85Mbit/s while reducing the interrupt CPU usage from 99% to 80%.
>
> It turns out that due to an error on my part, most of this improvment
> was due to one of the test kernels being complied without POOL_DEBUG
> while the "baseline" one was. Sigh. I think there's still some gains
> to be had, though.
OK, here's another diff which does seem to help. It seems that there's
two different bits in the TX descriptor that control interrupts. Quoting
from the VT6105M spec:
TDES1 bit 23: "Interrupt Control. 0: No interrupt when Transmit OK, 1:
Interrupt when Transmit OK"
TDES3 bit 0: "Interrupt Control. 0: issue interrupt for this packet. 1:
no interrupt generated"
Why two bits with apparently similar functionality? Beats me, but only
the second actually seems to do anything on my VT6105M here. CPU usage
for routing 85 mbit/s drops CPU usage from about 75% to about 50%
(famous last words). Your milage may vary and so on.
Index: if_vr.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vr.c,v
retrieving revision 1.124
diff -u -p -r1.124 if_vr.c
--- if_vr.c 16 Jan 2013 06:15:50 -0000 1.124
+++ if_vr.c 17 Jan 2013 04:15:05 -0000
@@ -724,7 +724,7 @@ vr_list_tx_init(struct vr_softc *sc)
cd = &sc->vr_cdata;
ld = sc->vr_ldata;
- cd->vr_tx_cnt = 0;
+ cd->vr_tx_cnt = cd->vr_tx_pkts = 0;
for (i = 0; i < VR_TX_LIST_CNT; i++) {
cd->vr_tx_chain[i].vr_ptr = &ld->vr_tx_list[i];
@@ -1292,7 +1292,15 @@ vr_encap(struct vr_softc *sc, struct vr_
}
/* Set EOP on the last descriptor */
- f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG | VR_TXCTL_FINT);
+ f->vr_ctl |= htole32(VR_TXCTL_LASTFRAG);
+
+ /* set the disable-interrupt bit except on every Nth packet */
+ if (sc->vr_cdata.vr_tx_pkts++ % 16)
+ f->vr_next |= htole32(VR_TXNEXT_INTDISABLE);
+ else {
+ sc->vr_cdata.vr_tx_pkts = 0;
+ f->vr_ctl |= htole32(VR_TXCTL_FINT);
+ }
return (0);
}
@@ -1581,6 +1589,11 @@ vr_watchdog(struct ifnet *ifp)
struct vr_softc *sc;
sc = ifp->if_softc;
+
+ /* Reclaim first as we don't request an interrupt for every packet. */
+ vr_txeof(sc);
+ if (sc->vr_cdata.vr_tx_cnt == 0);
+ return;
ifp->if_oerrors++;
printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname);
Index: if_vrreg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_vrreg.h,v
retrieving revision 1.33
diff -u -p -r1.33 if_vrreg.h
--- if_vrreg.h 16 Jan 2013 05:25:57 -0000 1.33
+++ if_vrreg.h 17 Jan 2013 04:15:05 -0000
@@ -429,6 +429,9 @@ struct vr_desc {
#define VR_TXCTL_LASTFRAG 0x00400000
#define VR_TXCTL_FINT 0x00800000
+/* TDES3 aka vr_next */
+#define VR_TXNEXT_INTDISABLE 0x00000001
+
#define VR_MAXFRAGS 8
#define VR_RX_LIST_CNT 128
#define VR_TX_LIST_CNT 128
@@ -467,6 +470,7 @@ struct vr_chain_data {
struct vr_chain *vr_tx_cons;
struct vr_chain *vr_tx_prod;
int vr_tx_cnt;
+ int vr_tx_pkts;
};
struct vr_mii_frame {
--
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4 37C9 C982 80C7 8FF4 FA69
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.