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;