Subject: Re: packet capturing
To: Darren Reed <darrenr@mail.netbsd.org>
From: Jonathan Stone <jonathan@DSG.Stanford.EDU>
List: tech-kern
Date: 01/22/2004 11:34:08
In message <Pine.NEB.4.58.0401211743110.18750@mail.netbsd.org>
Darren Reed writes:
>And does NetBSD, by default, ship with polling drivers or irq based ?
Yesterday just committed a hook to the bge driver which supports
changing the receive-interrupt thresholds.
The following code uses that hook to set one of six interrupt
thresh-hold levels. At the highest level, the interrupt deferral
is already lower than 2KHz polling for typical traffic.
Note this is copyrighted (c) 2003-2004 by Jonathan Stone. I still
need to work out some copyright issues before committing the code below.
In the short term, I will paste in (temporary) sysctl knobs, to allow
setting the values for all bge devices in a given kernel. If someone
wants to invent a better, driver-independent framework for turning the
interrupt-rate knob up, down, or just-fine: go for it.
/*
* Tunable thresholds for rx-side interrupt mitigation. The values
* below were measured to give 1 interrupt in N packets, where N is
* max_bds.
*
* These values were obtained by empirical trial-and-error on a bcm5700.
* They appear to work reasonably well on a 5704. If the larger values
* are used on Altima chip variants (or 5705), they are likely to
* overflow internal chip registers and wrap to lower effective values.
* Caveat emptor.
*/
struct bge_load_rx_thresh {
int rx_ticks;
int rx_max_bds;
} bge_rxthreshes[] = {
{ 32, 2 },
{ 50, 4 },
{ 100 , 8 },
{ 192 , 16 },
{ 416 , 32 },
{ 598 , 46 }
};
#define NBGE_RX_THRESH (sizeof(bge_rxthreshes) / sizeof(bge_rxthreshes[0]))
/*
....
*/
void bge_set_rxthresh(struct ifnet *ifp, int lvl);
/*
...
*/
void
bge_set_rxthresh(struct ifnet *ifp, int lvl)
{
struct bge_softc *sc = ifp->if_softc;
int s;
/* For now, just save the new Rx-intr thresholds and
* record that a threshold update is pending.
* Updating the hardware registers here (even at splhigh())
* is observed to occasionaly cause glitches where Rx-interrupts
* are not honoured for up to 10 seconds. Jonathan, 2003-04-05
*/
sc->bge_rx_coal_ticks = bge_rxthreshes[lvl].rx_ticks;
sc->bge_rx_max_coal_bds = bge_rxthreshes[lvl].rx_max_bds;
s = splnet();
sc->bge_pending_rxintr_change = 1;
splx(s);
return;
}