Here are patches to three of the Gigabit ethernet drivers to
implement soft interrupt coelescing. I have included patches
for the dc, ti, and vr drivers... the ti driver is by far the
cleanest.
I don't use Bill Paul's Tigon III driver, so I haven't
included patche for it (the patches should be obvious,
anyway, from these).
This does in software what the firmware interrupt coelescing
that Bill Paul put in the Tigon II and Tigon III drivers
does, namely, process more packets per interrupt than would
otherwise be processed, and thus reduce interrupt overhead.
The interrupt overhead is reduced by 33% on a full loaded
system (for a Tigon III, this means 960 megabits a second),
so most of you don't have the equipment necessary to test
this.
Note that it is only incremental, unless you also do the
stack processing at interrupt time, but since it is a net
positive (reduces a Tigon III from 12,000 to 8,000 interrupts
a second for 960 megabits a second), it's worthwhile.
This is based on ideas in the Jeff Mogul (DEC Western Research
Labs) paper from 1995:
http://www.research.digital.com/wrl/techreports/abstracts/95.8.html
http://ftp.digital.com/%7emogul/usenix96.ps
Kris: Commit this... K PLZ THX.
-- Terry
Index: if_dc.c
===================================================================
RCS file: /home/cvs/clickarray/FreeBSD/sys.releng4/pci/if_dc.c,v
retrieving revision 1.1.1.2
diff -r1.1.1.2 if_dc.c
196,197c196,197
< static void dc_rxeof __P((struct dc_softc *));
< static void dc_txeof __P((struct dc_softc *));
---
> static int dc_rxeof __P((struct dc_softc *));
> static int dc_txeof __P((struct dc_softc *));
2305c2305
< static void dc_rxeof(sc)
---
> static int dc_rxeof(sc)
2313a2314
> int cnt = 0;
2358c2359
< return;
---
> return(cnt);
2381a2383
> cnt++;
2392c2394
< static void dc_txeof(sc)
---
> static int dc_txeof(sc)
2397a2400
> int cnt = 0;
2455c2458
< return;
---
> return(cnt);
2468a2472
> cnt++;
2475c2479
< return;
---
> return(cnt);
2614a2619
> int cnt = 0;
2632a2638
> again:
2640c2646
< dc_rxeof(sc);
---
> cnt += dc_rxeof(sc);
2643c2649
< dc_rxeof(sc);
---
> cnt += dc_rxeof(sc);
2648c2654
< dc_txeof(sc);
---
> cnt += dc_txeof(sc);
2651c2657
< dc_txeof(sc);
---
> cnt += dc_txeof(sc);
2665c2671
< dc_rxeof(sc);
---
> cnt += dc_rxeof(sc);
2668c2674
< dc_rxeof(sc);
---
> cnt += dc_rxeof(sc);
2675a2682,2686
> }
>
> if (cnt) { /* XXX limit repeats? */
> cnt = 0;
> goto again;
Index: if_ti.c
===================================================================
RCS file: /home/cvs/clickarray/FreeBSD/sys.releng4/pci/if_ti.c,v
retrieving revision 1.4
diff -r1.4 if_ti.c
162,163c162,163
< static void ti_txeof __P((struct ti_softc *));
< static void ti_rxeof __P((struct ti_softc *));
---
> static int ti_txeof __P((struct ti_softc *));
> static int ti_rxeof __P((struct ti_softc *));
1818c1818
< static void ti_rxeof(sc)
---
> static int ti_rxeof(sc)
1822a1823
> int cnt = 0;
1906a1908
> cnt++;
1931c1933
< return;
---
> return(cnt);
1934c1936
< static void ti_txeof(sc)
---
> static int ti_txeof(sc)
1938a1941
> int cnt = 0;
1974a1978
> cnt++;
1980c1984
< return;
---
> return(cnt);
2003,2007c2007,2009
< /* Check RX return ring producer/consumer */
< ti_rxeof(sc);
<
< /* Check TX ring producer/consumer */
< ti_txeof(sc);
---
> /* Check RX, TX return ring producer/consumer */
> while(ti_rxeof(sc) || ti_txeof(sc))
> continue; /* XXX limit repeats? */
Index: if_vr.c
===================================================================
RCS file: /home/cvs/clickarray/FreeBSD/sys.releng4/pci/if_vr.c,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 if_vr.c
133,135c133,135
< static void vr_rxeof __P((struct vr_softc *));
< static void vr_rxeoc __P((struct vr_softc *));
< static void vr_txeof __P((struct vr_softc *));
---
> static int vr_rxeof __P((struct vr_softc *));
> static int vr_rxeoc __P((struct vr_softc *));
> static int vr_txeof __P((struct vr_softc *));
956c956
< static void vr_rxeof(sc)
---
> static int vr_rxeof(sc)
964a965
> int cnt = 0;
1042a1044,1045
>
> cnt++;
1045c1048
< return;
---
> return(cnt);
1048c1051
< void vr_rxeoc(sc)
---
> int vr_rxeoc(sc)
1050a1054
> int cnt;
1052c1056
< vr_rxeof(sc);
---
> cnt = vr_rxeof(sc);
1058c1062
< return;
---
> return(cnt);
1066c1070
< static void vr_txeof(sc)
---
> static int vr_txeof(sc)
1070a1075
> int cnt = 0;
1167a1173
> int cnt = 0;
1180a1187
> again:
1191c1198
< vr_rxeof(sc);
---
> cnt += vr_rxeof(sc);
1197c1204
< vr_rxeoc(sc);
---
> cnt += vr_rxeoc(sc);
1201c1208
< vr_txeof(sc);
---
> cnt += vr_txeof(sc);
1207c1214
< vr_txeof(sc);
---
> cnt += vr_txeof(sc);
1217a1225,1229
> }
>
> if (cnt) { /* XXX limit repeats? */
> cnt = 0;
> goto again;