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;
}