Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 19 Jul 2014 16:16:28 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Adrian Chadd <adrian@freebsd.org>
Cc:        hiren panchasara <hiren.panchasara@gmail.com>, "freebsd-net@freebsd.org" <net@freebsd.org>
Subject:   Re: UDP sendto() returning ENOBUFS - "No buffer space available"
Message-ID:  <20140719152125.A874@besplex.bde.org>
In-Reply-To: <CAJ-Vmonunb=WqcyJ%2BhJNDknj%2BzjMQVOWWk%2Bu=MqhXkJkcm_DFQ@mail.gmail.com>
References:  <CALCpEUE7OtbXjVTk2C8%2BV7fjOKutuNq04BTo0SN42YEgX81k-Q@mail.gmail.com> <CAJ-VmokEiZMpdfNjs%2B-C9pmRcjOOjjNGTvM88muh940sr7SmPw@mail.gmail.com> <CALCpEUE-vebmaGSK5aGM%2B3q5YqzXkn1P=St7R8G_ztmHmgUBBA@mail.gmail.com> <20140719053318.I15959@besplex.bde.org> <CAJ-Vmonunb=WqcyJ%2BhJNDknj%2BzjMQVOWWk%2Bu=MqhXkJkcm_DFQ@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 18 Jul 2014, Adrian Chadd wrote:

> On 18 July 2014 13:40, Bruce Evans <brde@optusnet.com.au> wrote:
>> On Fri, 18 Jul 2014, hiren panchasara wrote:
>>
>>> On Wed, Jul 16, 2014 at 11:00 AM, Adrian Chadd <adrian@freebsd.org> wrote:
>>>>
>>>> Hi!
>>>>
>>>> So the UDP transmit path is udp_usrreqs->pru_send() == udp_send() ->
>>>> udp_output() -> ip_output()
>>>>
>>>> udp_output() does do a M_PREPEND() which can return ENOBUFS. ip_output
>>>> can also return ENOBUFS.
>>>>
>>>> it doesn't look like the socket code (eg sosend_dgram()) is doing any
>>>> buffering - it's just copying the frame and stuffing it up to the
>>>> driver. No queuing involved before the NIC.
>>>
>>> Right. Thanks for confirming.
>>
>> Most buffering should be in ifq above the NIC.  For UDP, I think
>> udp_output() puts buffers on the ifq and calls the driver for every
>> one, but the driver shouldn't do anything for most calls.  The
>> driver can't possibly do anything if its ring buffer is full, and
>> shouldn't do anything if it is nearly full.  Buffers accumulate in
>> the ifq until the driver gets around to them or the queue fills up.
>> Most ENOBUFS errors are for when it fills up.  It can very easily
>> fill up, especially since it is too small in most configurations.
>> Just loop calling sendto().  This will fill the ifq almost
>> instantly unless the hardware is faster than the software.
>
> For if_transmit() drivers, there's no ifp queue. The queuing is being
> done in the driver.
>
> For drivers with if_transmit(), they may end up doing direct DMA ring
> dispatch or they may have a buf_ring in front of it.There's no ifq
> anymore. It upsets the ALTQ people too.

Ah, a new source of bugs.  Most drivers don't use this yet.  Most still
use ifq with the bogus size of (tx_ring_size - 1):

Ones converted to the indirect API:
% dev/bge/if_bge.c:	if_setsendqlen(ifp, BGE_TX_RING_CNT - 1);
% dev/bxe/bxe.c:    if_setsendqlen(ifp, sc->tx_ring_size);

bxe is one of the few without the silly subtraction of 1.

% dev/e1000/if_em.c:	if_setsendqlen(ifp, adapter->num_tx_desc - 1);
% dev/e1000/if_lem.c:	if_setsendqlen(ifp, adapter->num_tx_desc - 1);
% dev/fxp/if_fxp.c:	if_setsendqlen(ifp, FXP_NTXCB - 1);
% dev/nfe/if_nfe.c:	if_setsendqlen(ifp, NFE_TX_RING_COUNT - 1);

Ones not converted:
% dev/ae/if_ae.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/ae/if_ae.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);

The double setting is related to ALTQ.  I grepped for maxlen to find both.
I might have missed alternative spellings.

ifqmaxlen is usually 50, so all drivers using it have very little buffering.
Even if their tx ring is tiny, this 50 is too small above 1 or 10 Mbps.

% dev/age/if_age.c:	ifp->if_snd.ifq_drv_maxlen = AGE_TX_RING_CNT - 1;
% dev/age/if_age.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/alc/if_alc.c:	ifp->if_snd.ifq_drv_maxlen = ALC_TX_RING_CNT - 1;
% dev/alc/if_alc.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/ale/if_ale.c:	ifp->if_snd.ifq_drv_maxlen = ALE_TX_RING_CNT - 1;
% dev/ale/if_ale.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/an/if_an.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/an/if_an.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/asmc/asmc.c:	uint8_t maxlen;
% dev/asmc/asmc.c:		maxlen = type[0];

Grepping for maxlen unfortunately found related things.  I deleted most
after this.

% dev/ath/if_ath.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ath/if_ath.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/bce/if_bce.c:	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD_ALLOC;
% dev/bce/if_bce.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/bfe/if_bfe.c:	ifp->if_snd.ifq_drv_maxlen = BFE_TX_QLEN;
% dev/bm/if_bm.c:	ifp->if_snd.ifq_drv_maxlen = BM_MAX_TX_PACKETS;
% dev/bwi/if_bwi.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/bwi/if_bwi.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/bwn/if_bwn.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/bwn/if_bwn.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/cadence/if_cgem.c:	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
% dev/cas/if_cas.c:	ifp->if_snd.ifq_drv_maxlen = CAS_TXQUEUELEN;
% dev/ce/if_ce.c:		d->queue.ifq_maxlen	= ifqmaxlen;
% dev/ce/if_ce.c:		d->hi_queue.ifq_maxlen	= ifqmaxlen;
% dev/ce/if_ce.c:		d->rqueue.ifq_maxlen	= ifqmaxlen;
% dev/ce/if_ce.c:		d->rqueue.ifq_maxlen	= ifqmaxlen;

Seems silly to have many tiny queues, especially when their length is
nominal and can be changed by tunables if not sysctls so that it is
not actually tiny.  But good for latency.

% dev/cm/smc90cx6.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/cp/if_cp.c:		d->queue.ifq_maxlen = ifqmaxlen;
% dev/cp/if_cp.c:		d->hi_queue.ifq_maxlen = ifqmaxlen;
% dev/cp/if_cp.c:		d->queue.ifq_maxlen	= NRBUF;
% dev/cs/if_cs.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ctau/if_ct.c:		d->queue.ifq_maxlen = ifqmaxlen;
% dev/ctau/if_ct.c:		d->hi_queue.ifq_maxlen = ifqmaxlen;
% dev/ctau/if_ct.c:		d->queue.ifq_maxlen	= NBUF;
% dev/cx/if_cx.c:		d->lo_queue.ifq_maxlen = ifqmaxlen;
% dev/cx/if_cx.c:		d->hi_queue.ifq_maxlen = ifqmaxlen;
% dev/cx/if_cx.c:		d->queue.ifq_maxlen	= 2;

Not that's a tiny queue which can't be broken by changing the sysctl.

% dev/dc/if_dc.c:	ifp->if_snd.ifq_drv_maxlen = DC_TX_LIST_CNT - 1;
% dev/de/if_de.c:    IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/de/if_de.c:    ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/e1000/if_igb.c:	ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 1;
% dev/ed/if_ed.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ed/if_ed.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/ep/if_ep.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ep/if_ep.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/et/if_et.c:	ifp->if_snd.ifq_drv_maxlen = ET_TX_NDESC - 1;
% dev/ex/if_ex.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/fatm/if_fatm.c:	ifp->if_snd.ifq_maxlen = 512;
% dev/fe/if_fe.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ffec/if_ffec.c:	ifp->if_snd.ifq_drv_maxlen = TX_DESC_COUNT - 1;
% dev/firewire/if_fwe.c:	ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
% dev/firewire/if_fwip.c:	ifp->if_snd.ifq_maxlen = TX_MAX_QUEUE;
% dev/gem/if_gem.c:	ifp->if_snd.ifq_drv_maxlen = GEM_TXQUEUELEN;
% dev/hme/if_hme.c:	ifp->if_snd.ifq_drv_maxlen = HME_NTXQ;
% dev/i40e/if_i40e.c:	ifp->if_snd.ifq_maxlen = que->num_desc - 2;
% dev/ie/if_ie.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/if_ndis/if_ndis.c:	ifp->if_snd.ifq_drv_maxlen = 25;
% dev/iicbus/if_ic.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/ipw/if_ipw.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ipw/if_ipw.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/iwi/if_iwi.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/iwi/if_iwi.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/iwn/if_iwn.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/iwn/if_iwn.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/ixgb/if_ixgb.c:	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 1;
% dev/ixgbe/ixgbe.c:	ifp->if_snd.ifq_drv_maxlen = adapter->num_tx_desc - 2;
% dev/ixgbe/ixv.c:	ifp->if_snd.ifq_maxlen = adapter->num_tx_desc - 2;
% dev/jme/if_jme.c:	ifp->if_snd.ifq_drv_maxlen = JME_TX_RING_CNT - 1;
% dev/jme/if_jme.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/le/lance.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/le/lance.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/lge/if_lge.c:	ifp->if_snd.ifq_maxlen = LGE_TX_LIST_CNT - 1;
% dev/malo/if_malo.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/malo/if_malo.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/mge/if_mge.c:	ifp->if_snd.ifq_drv_maxlen = MGE_TX_DESC_NUM - 1;
% dev/mge/if_mge.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/msk/if_msk.c:	ifp->if_snd.ifq_drv_maxlen = MSK_TX_RING_CNT - 1;
% dev/mwl/if_mwl.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/mwl/if_mwl.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/mxge/if_mxge.c:	sc->ifp->if_snd.ifq_drv_maxlen = sc->ifp->if_snd.ifq_maxlen;
% dev/my/if_my.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/my/if_my.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/nge/if_nge.c:	ifp->if_snd.ifq_drv_maxlen = NGE_TX_RING_CNT - 1;
% dev/nge/if_nge.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/nxge/if_nxge.c:	ifnetp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/oce/oce_if.c:	sc->ifp->if_snd.ifq_drv_maxlen = OCE_MAX_TX_DESC - 1;
% dev/oce/oce_if.c:	IFQ_SET_MAXLEN(&sc->ifp->if_snd, sc->ifp->if_snd.ifq_drv_maxlen);
% dev/patm/if_patm.c:	sc->scd0->q.ifq_maxlen = PATM_DLFT_MAXQ;
% dev/patm/if_patm.c:	scd->q.ifq_maxlen = PATM_TX_IFQLEN;
% dev/pcn/if_pcn.c:	ifp->if_snd.ifq_maxlen = PCN_TX_LIST_CNT - 1;
% dev/pdq/pdq_ifsubr.c:    ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/ppbus/if_plip.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;

ifqmaxlen = 50 is actually right for plip, but only if someone doesn't
bump it up using the sysctl.

% dev/qlxgb/qla_os.c:	IFQ_SET_MAXLEN(&ifp->if_snd, qla_get_ifq_snd_maxlen(ha));
% dev/qlxgb/qla_os.c:	ifp->if_snd.ifq_drv_maxlen = qla_get_ifq_snd_maxlen(ha);
% dev/qlxgbe/ql_os.c:	IFQ_SET_MAXLEN(&ifp->if_snd, qla_get_ifq_snd_maxlen(ha));
% dev/qlxgbe/ql_os.c:	ifp->if_snd.ifq_drv_maxlen = qla_get_ifq_snd_maxlen(ha);
% dev/qlxge/qls_os.c:	IFQ_SET_MAXLEN(&ifp->if_snd, qls_get_ifq_snd_maxlen(ha));
% dev/qlxge/qls_os.c:	ifp->if_snd.ifq_drv_maxlen = qls_get_ifq_snd_maxlen(ha);
% dev/ral/rt2560.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ral/rt2560.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/ral/rt2661.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ral/rt2661.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/ral/rt2860.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ral/rt2860.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/re/if_re.c:	ifp->if_snd.ifq_drv_maxlen = RL_IFQ_MAXLEN;
% dev/rt/if_rt.c:	ifp->if_snd.ifq_drv_maxlen = RT_TX_QLEN;
% dev/sbni/if_sbni.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/sf/if_sf.c:	ifp->if_snd.ifq_drv_maxlen = SF_TX_DLIST_CNT - 1;
% dev/sfxge/sfxge.c:	ifp->if_snd.ifq_drv_maxlen = SFXGE_NDESCS - 1;
% dev/sge/if_sge.c:	ifp->if_snd.ifq_drv_maxlen = SGE_TX_RING_CNT - 1;
% dev/sge/if_sge.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/sis/if_sis.c:	ifp->if_snd.ifq_drv_maxlen = SIS_TX_LIST_CNT - 1;
% dev/sk/if_sk.c:	ifp->if_snd.ifq_drv_maxlen = SK_TX_RING_CNT - 1;
% dev/smc/if_smc.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/sn/if_sn.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/sn/if_sn.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/snc/dp83932.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/ste/if_ste.c:	ifp->if_snd.ifq_drv_maxlen = STE_TX_LIST_CNT - 1;
% dev/stge/if_stge.c:	ifp->if_snd.ifq_drv_maxlen = STGE_TX_RING_CNT - 1;
% dev/stge/if_stge.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/ti/if_ti.c:	ifp->if_snd.ifq_drv_maxlen = TI_TX_RING_CNT - 1;
% dev/ti/if_ti.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/tl/if_tl.c:	ifp->if_snd.ifq_maxlen = TL_TX_LIST_CNT - 1;
% dev/tsec/if_tsec.c:	ifp->if_snd.ifq_drv_maxlen = TSEC_TX_NUM_DESC - 1;
% dev/txp/if_txp.c:	ifp->if_snd.ifq_drv_maxlen = TX_ENTRIES - 1;
% dev/txp/if_txp.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/usb/usb_dev.c:	f->free_q.ifq_maxlen = nbuf;
% dev/usb/usb_dev.c:	f->used_q.ifq_maxlen = nbuf;
% dev/vge/if_vge.c:	ifp->if_snd.ifq_drv_maxlen = VGE_TX_DESC_CNT - 1;
% dev/vr/if_vr.c:	ifp->if_snd.ifq_maxlen = VR_TX_RING_CNT - 1;
% dev/vte/if_vte.c:	ifp->if_snd.ifq_drv_maxlen = VTE_TX_RING_CNT - 1;
% dev/vte/if_vte.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/vx/if_vx.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/vxge/vxge.c:	ifp->if_snd.ifq_drv_maxlen = max(vdev->config.ifq_maxlen, ifqmaxlen);
% dev/vxge/vxge.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
% dev/wb/if_wb.c:	ifp->if_snd.ifq_maxlen = WB_TX_LIST_CNT - 1;
% dev/wi/if_wi.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/wi/if_wi.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/wl/if_wl.c:    ifp->if_snd.ifq_maxlen = ifqmaxlen;
% dev/wpi/if_wpi.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/wpi/if_wpi.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/wtap/if_wtap.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% dev/wtap/if_wtap.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% dev/xe/if_xe.c:	IFQ_SET_MAXLEN(&scp->ifp->if_snd, ifqmaxlen);
% dev/xl/if_xl.c:	ifp->if_snd.ifq_drv_maxlen = XL_TX_LIST_CNT - 1;

There are so many drivers that just removing the silly subtraction of 1
or the excessive use of the global ifqmaxlen in them is a daunting task.
You would have to check that the silly subtraction isn't actually needed.
Changing ifqmaxlen is easier.  It is supposed to be variable and not
closely related to devices, so its not your fault if changing to another
value (not so directly connected to ifqmaxlen) breaks the driver.

I have only worked on bge and sk much.  This required intricate
device-dependent changes to implement watermark stuff in the tx rings.
The hardware doesn't really support watermark stuff but it is possible
to emulate it.

% net/if.c:SYSCTL_INT(_net_link, OID_AUTO, ifqmaxlen, CTLFLAG_RDTUN,
% net/if.c:    &ifqmaxlen, 0, "max send queue size");
% net/if.c:int	ifqmaxlen = IFQ_MAXLEN;
% net/if_atmsubr.c:	ifp->if_snd.ifq_maxlen = 50;	/* dummy */

No reason to spell 50 as 50 instead of as ifqmaxlen?  A random default
works especially well when it is not used.

% net/if_disc.c:	ifp->if_snd.ifq_maxlen = 20;

Tiny queues may be even worse for synthetic devices than for real ones.
The real ones tend to have large enough tx rings except under load,
and the load is limited by the link speed.  But for synthetic ones
there might not be any more buffering, and the only speed limits are
in software.  When the queue fills up, the application has the same
problem of restarting as soon as possible without busy-waiting as for
hardware devices.

% net/if_edsc.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_enc.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_epair.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_epair.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_epair.c:		epair_nh.nh_qlimit = 42 * ifqmaxlen; /* 42 shall be the number. */

It is a better too-small number than 50.

% net/if_faith.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_gif.c:	GIF2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_gre.c:	GRE2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_loop.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_mib.c:		ifmd.ifmd_snd_maxlen = ifp->if_snd.ifq_maxlen;
% net/if_mib.c:		ifp->if_snd.ifq_maxlen = ifmd.ifmd_snd_maxlen;
% net/if_spppsubr.c: 	ifp->if_snd.ifq_maxlen = 32;
% net/if_spppsubr.c: 	sp->pp_fastq.ifq_maxlen = 32;
% net/if_spppsubr.c: 	sp->pp_cpq.ifq_maxlen = 20;
% net/if_stf.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% net/if_tap.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% net/if_tun.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% net/if_tun.c:	ifp->if_snd.ifq_drv_maxlen = 0;
% netgraph/ng_device.c:	IFQ_SET_MAXLEN(&priv->readq, ifqmaxlen);
% netgraph/ng_eiface.c:	ifp->if_snd.ifq_maxlen = ifqmaxlen;
% netgraph/ng_iface.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% netgraph/ng_iface.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;
% netgraph/ng_source.c:	sc->snd_queue.ifq_maxlen = 2048;	/* XXX not checked */
% netgraph/ng_tty.c:	IFQ_SET_MAXLEN(&sc->outq, ifqmaxlen);

End of synthetic devices.

% pci/if_rl.c:	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
% pci/if_rl.c:	ifp->if_snd.ifq_drv_maxlen = ifqmaxlen;

if_transmit is relatively rarely used:

% dev/ath/if_ath.c:	ifp->if_transmit = ath_transmit;
% dev/cxgb/cxgb_main.c:	ifp->if_transmit = cxgb_transmit;
% dev/cxgbe/t4_main.c:	ifp->if_transmit = cxgbe_transmit;
% dev/cxgbe/t4_netmap.c:	ifp->if_transmit = cxgbe_nm_transmit;
% dev/cxgbe/t4_tracer.c:	ifp->if_transmit = tracer_transmit;
% dev/e1000/if_igb.c:	ifp->if_transmit = igb_mq_start;
% dev/i40e/if_i40e.c:	ifp->if_transmit = i40e_mq_start;
% dev/ixgbe/ixgbe.c:	ifp->if_transmit = ixgbe_mq_start;
% dev/ixgbe/ixv.c:	ifp->if_transmit = ixv_mq_start;
% dev/mxge/if_mxge.c:	ifp->if_transmit = mxge_transmit;
% dev/netmap/netmap_freebsd.c:		na->if_transmit = ifp->if_transmit;
% dev/netmap/netmap_freebsd.c:		ifp->if_transmit = netmap_transmit;
% dev/netmap/netmap_freebsd.c:		ifp->if_transmit = na->if_transmit;
% dev/oce/oce_if.c:	sc->ifp->if_transmit = oce_multiq_start;
% dev/sfxge/sfxge.c:	ifp->if_transmit = sfxge_if_transmit;
% dev/sfxge/sfxge_tx.c:sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m)
% dev/vxge/vxge.c:	ifp->if_transmit = vxge_mq_send;
% dev/wtap/if_wtap.c:wtap_if_transmit(struct ifnet *ifp, struct mbuf *m)
% dev/wtap/if_wtap.c:	sc->if_transmit = ifp->if_transmit;
% dev/wtap/if_wtap.c:	ifp->if_transmit = wtap_if_transmit;

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140719152125.A874>