xref: /freebsd/sys/net/netisr.c (revision f0796cd26c51af84618836d41f9e37a310323c6e)
11cafed39SJonathan Lemon /*-
21cafed39SJonathan Lemon  * Copyright (c) 2001,2002,2003 Jonathan Lemon <jlemon@FreeBSD.org>
3e3b6e33cSJake Burkholder  * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
4e3b6e33cSJake Burkholder  * All rights reserved.
5e3b6e33cSJake Burkholder  *
6e3b6e33cSJake Burkholder  * Redistribution and use in source and binary forms, with or without
7e3b6e33cSJake Burkholder  * modification, are permitted provided that the following conditions
8e3b6e33cSJake Burkholder  * are met:
9e3b6e33cSJake Burkholder  * 1. Redistributions of source code must retain the above copyright
101cafed39SJonathan Lemon  *    notice, this list of conditions and the following disclaimer.
11e3b6e33cSJake Burkholder  * 2. Redistributions in binary form must reproduce the above copyright
12e3b6e33cSJake Burkholder  *    notice, this list of conditions and the following disclaimer in the
13e3b6e33cSJake Burkholder  *    documentation and/or other materials provided with the distribution.
14e3b6e33cSJake Burkholder  *
151cafed39SJonathan Lemon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
161cafed39SJonathan Lemon  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171cafed39SJonathan Lemon  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181cafed39SJonathan Lemon  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191cafed39SJonathan Lemon  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201cafed39SJonathan Lemon  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211cafed39SJonathan Lemon  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221cafed39SJonathan Lemon  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231cafed39SJonathan Lemon  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241cafed39SJonathan Lemon  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251cafed39SJonathan Lemon  * SUCH DAMAGE.
26e3b6e33cSJake Burkholder  *
27e3b6e33cSJake Burkholder  * $FreeBSD$
28e3b6e33cSJake Burkholder  */
29e3b6e33cSJake Burkholder 
30f0796cd2SGleb Smirnoff #include "opt_device_polling.h"
311d8cd39eSRobert Watson #include "opt_net.h"
321d8cd39eSRobert Watson 
33e3b6e33cSJake Burkholder #include <sys/param.h>
34e3b6e33cSJake Burkholder #include <sys/bus.h>
351cafed39SJonathan Lemon #include <sys/rtprio.h>
361cafed39SJonathan Lemon #include <sys/systm.h>
37e3b6e33cSJake Burkholder #include <sys/interrupt.h>
38e3b6e33cSJake Burkholder #include <sys/kernel.h>
391cafed39SJonathan Lemon #include <sys/kthread.h>
401cafed39SJonathan Lemon #include <sys/lock.h>
411cafed39SJonathan Lemon #include <sys/malloc.h>
421cafed39SJonathan Lemon #include <sys/proc.h>
431cafed39SJonathan Lemon #include <sys/random.h>
441cafed39SJonathan Lemon #include <sys/resourcevar.h>
451cafed39SJonathan Lemon #include <sys/sysctl.h>
461cafed39SJonathan Lemon #include <sys/unistd.h>
471cafed39SJonathan Lemon #include <machine/atomic.h>
481cafed39SJonathan Lemon #include <machine/cpu.h>
491cafed39SJonathan Lemon #include <machine/stdarg.h>
50e3b6e33cSJake Burkholder 
511cafed39SJonathan Lemon #include <sys/mbuf.h>
521cafed39SJonathan Lemon #include <sys/socket.h>
531cafed39SJonathan Lemon 
541cafed39SJonathan Lemon #include <net/if.h>
551cafed39SJonathan Lemon #include <net/if_types.h>
561cafed39SJonathan Lemon #include <net/if_var.h>
57e3b6e33cSJake Burkholder #include <net/netisr.h>
58e3b6e33cSJake Burkholder 
59d3be1471SSam Leffler /*
6008f85b08SRobert Watson  * debug_mpsafenet controls network subsystem-wide use of the Giant lock,
611d8cd39eSRobert Watson  * from system calls down to interrupt handlers.  It can be changed only via
621d8cd39eSRobert Watson  * a tunable at boot, not at run-time, due to the complexity of unwinding.
631d8cd39eSRobert Watson  * The compiled default is set via a kernel option; right now, the default
641d8cd39eSRobert Watson  * unless otherwise specified is to run the network stack without Giant.
65d3be1471SSam Leffler  */
661d8cd39eSRobert Watson #ifdef NET_WITH_GIANT
67d3be1471SSam Leffler int	debug_mpsafenet = 0;
681d8cd39eSRobert Watson #else
691d8cd39eSRobert Watson int	debug_mpsafenet = 1;
701d8cd39eSRobert Watson #endif
711d8cd39eSRobert Watson int	debug_mpsafenet_toolatetotwiddle = 0;
721d8cd39eSRobert Watson 
73d3be1471SSam Leffler TUNABLE_INT("debug.mpsafenet", &debug_mpsafenet);
74d3be1471SSam Leffler SYSCTL_INT(_debug, OID_AUTO, mpsafenet, CTLFLAG_RD, &debug_mpsafenet, 0,
75d3be1471SSam Leffler     "Enable/disable MPSAFE network support");
76d3be1471SSam Leffler 
771cafed39SJonathan Lemon volatile unsigned int	netisr;	/* scheduling bits for network */
78e3b6e33cSJake Burkholder 
791cafed39SJonathan Lemon struct netisr {
801cafed39SJonathan Lemon 	netisr_t	*ni_handler;
811cafed39SJonathan Lemon 	struct ifqueue	*ni_queue;
827902224cSSam Leffler 	int		ni_flags;
831cafed39SJonathan Lemon } netisrs[32];
841cafed39SJonathan Lemon 
851cafed39SJonathan Lemon static void *net_ih;
86e3b6e33cSJake Burkholder 
871d8cd39eSRobert Watson /*
88ccaae37aSRobert Watson  * Not all network code is currently capable of running MPSAFE; however,
891d8cd39eSRobert Watson  * most of it is.  Since those sections that are not are generally optional
901d8cd39eSRobert Watson  * components not shipped with default kernels, we provide a basic way to
911d8cd39eSRobert Watson  * determine whether MPSAFE operation is permitted: based on a default of
921d8cd39eSRobert Watson  * yes, we permit non-MPSAFE components to use a registration call to
931d8cd39eSRobert Watson  * identify that they require Giant.  If the system is early in the boot
941d8cd39eSRobert Watson  * process still, then we change the debug_mpsafenet setting to choose a
951d8cd39eSRobert Watson  * non-MPSAFE execution mode (degraded).  If it's too late for that (since
961d8cd39eSRobert Watson  * the setting cannot be changed at run time), we generate a console warning
971d8cd39eSRobert Watson  * that the configuration may be unsafe.
981d8cd39eSRobert Watson  */
991d8cd39eSRobert Watson static int mpsafe_warn_count;
1001d8cd39eSRobert Watson 
1011d8cd39eSRobert Watson /*
1021d8cd39eSRobert Watson  * Function call implementing registration of a non-MPSAFE network component.
1031d8cd39eSRobert Watson  */
1041d8cd39eSRobert Watson void
1051d8cd39eSRobert Watson net_warn_not_mpsafe(const char *component)
1061d8cd39eSRobert Watson {
1071d8cd39eSRobert Watson 
1081d8cd39eSRobert Watson 	/*
1091d8cd39eSRobert Watson 	 * If we're running with Giant over the network stack, there is no
1101d8cd39eSRobert Watson 	 * problem.
1111d8cd39eSRobert Watson 	 */
1121d8cd39eSRobert Watson 	if (!debug_mpsafenet)
1131d8cd39eSRobert Watson 		return;
1141d8cd39eSRobert Watson 
1151d8cd39eSRobert Watson 	/*
1161d8cd39eSRobert Watson 	 * If it's not too late to change the MPSAFE setting for the network
1171d8cd39eSRobert Watson 	 * stack, do so now.  This effectively suppresses warnings by
1181d8cd39eSRobert Watson 	 * components registering later.
1191d8cd39eSRobert Watson 	 */
1201d8cd39eSRobert Watson 	if (!debug_mpsafenet_toolatetotwiddle) {
1211d8cd39eSRobert Watson 		debug_mpsafenet = 0;
122ace437c3SRobert Watson 		printf("WARNING: debug.mpsafenet forced to 0 as %s requires "
1231d8cd39eSRobert Watson 		    "Giant\n", component);
1241d8cd39eSRobert Watson 		return;
1251d8cd39eSRobert Watson 	}
1261d8cd39eSRobert Watson 
1271d8cd39eSRobert Watson 	/*
1281d8cd39eSRobert Watson 	 * We must run without Giant, so generate a console warning with some
1291d8cd39eSRobert Watson 	 * information with what to do about it.  The system may be operating
1301d8cd39eSRobert Watson 	 * unsafely, however.
1311d8cd39eSRobert Watson 	 */
1321d8cd39eSRobert Watson 	printf("WARNING: Network stack Giant-free, but %s requires Giant.\n",
1331d8cd39eSRobert Watson 	    component);
1341d8cd39eSRobert Watson 	if (mpsafe_warn_count == 0)
1351d8cd39eSRobert Watson 		printf("    Consider adding 'options NET_WITH_GIANT' or "
1361d8cd39eSRobert Watson 		    "setting debug.mpsafenet=0\n");
1371d8cd39eSRobert Watson 	mpsafe_warn_count++;
1381d8cd39eSRobert Watson }
1391d8cd39eSRobert Watson 
1401d8cd39eSRobert Watson /*
1411d8cd39eSRobert Watson  * This sysinit is run after any pre-loaded or compiled-in components have
1421d8cd39eSRobert Watson  * announced that they require Giant, but before any modules loaded at
1431d8cd39eSRobert Watson  * run-time.
1441d8cd39eSRobert Watson  */
1451d8cd39eSRobert Watson static void
1461d8cd39eSRobert Watson net_mpsafe_toolate(void *arg)
1471d8cd39eSRobert Watson {
1481d8cd39eSRobert Watson 
1491d8cd39eSRobert Watson 	debug_mpsafenet_toolatetotwiddle = 1;
1501d8cd39eSRobert Watson 
1511d8cd39eSRobert Watson 	if (!debug_mpsafenet)
1521d8cd39eSRobert Watson 		printf("WARNING: MPSAFE network stack disabled, expect "
1531d8cd39eSRobert Watson 		    "reduced performance.\n");
1541d8cd39eSRobert Watson }
1551d8cd39eSRobert Watson 
1561d8cd39eSRobert Watson SYSINIT(net_mpsafe_toolate, SI_SUB_SETTINGS, SI_ORDER_ANY, net_mpsafe_toolate,
1571d8cd39eSRobert Watson     NULL);
1581d8cd39eSRobert Watson 
159e3b6e33cSJake Burkholder void
160e3b6e33cSJake Burkholder legacy_setsoftnet(void)
161e3b6e33cSJake Burkholder {
162e3b6e33cSJake Burkholder 	swi_sched(net_ih, 0);
163e3b6e33cSJake Burkholder }
164e3b6e33cSJake Burkholder 
1651cafed39SJonathan Lemon void
1667902224cSSam Leffler netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags)
167e3b6e33cSJake Burkholder {
168e3b6e33cSJake Burkholder 
1691cafed39SJonathan Lemon 	KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
1701cafed39SJonathan Lemon 	    ("bad isr %d", num));
1711cafed39SJonathan Lemon 	netisrs[num].ni_handler = handler;
1721cafed39SJonathan Lemon 	netisrs[num].ni_queue = inq;
1737902224cSSam Leffler 	if ((flags & NETISR_MPSAFE) && !debug_mpsafenet)
1747902224cSSam Leffler 		flags &= ~NETISR_MPSAFE;
1757902224cSSam Leffler 	netisrs[num].ni_flags = flags;
176e3b6e33cSJake Burkholder }
177e3b6e33cSJake Burkholder 
1781cafed39SJonathan Lemon void
1791cafed39SJonathan Lemon netisr_unregister(int num)
180e3b6e33cSJake Burkholder {
1811cafed39SJonathan Lemon 	struct netisr *ni;
182e3b6e33cSJake Burkholder 
1831cafed39SJonathan Lemon 	KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
1841cafed39SJonathan Lemon 	    ("bad isr %d", num));
1851cafed39SJonathan Lemon 	ni = &netisrs[num];
1861cafed39SJonathan Lemon 	ni->ni_handler = NULL;
1877902224cSSam Leffler 	if (ni->ni_queue != NULL)
1881cafed39SJonathan Lemon 		IF_DRAIN(ni->ni_queue);
189de10fe70SAndre Oppermann 	ni->ni_queue = NULL;
1901cafed39SJonathan Lemon }
1911cafed39SJonathan Lemon 
1921cafed39SJonathan Lemon struct isrstat {
1931cafed39SJonathan Lemon 	int	isrs_count;			/* dispatch count */
1947902224cSSam Leffler 	int	isrs_directed;			/* ...directly dispatched */
1951cafed39SJonathan Lemon 	int	isrs_deferred;			/* ...queued instead */
1961cafed39SJonathan Lemon 	int	isrs_queued;			/* intentionally queueued */
1977902224cSSam Leffler 	int	isrs_drop;			/* dropped 'cuz no handler */
1981cafed39SJonathan Lemon 	int	isrs_swi_count;			/* swi_net handlers called */
1991cafed39SJonathan Lemon };
2001cafed39SJonathan Lemon static struct isrstat isrstat;
2011cafed39SJonathan Lemon 
2021cafed39SJonathan Lemon SYSCTL_NODE(_net, OID_AUTO, isr, CTLFLAG_RW, 0, "netisr counters");
2031cafed39SJonathan Lemon 
204cea2165bSRobert Watson static int	netisr_direct = 0;
205cea2165bSRobert Watson SYSCTL_INT(_net_isr, OID_AUTO, direct, CTLFLAG_RW,
206cea2165bSRobert Watson     &netisr_direct, 0, "enable direct dispatch");
207cea2165bSRobert Watson TUNABLE_INT("net.isr.direct", &netisr_direct);
2081cafed39SJonathan Lemon 
2091cafed39SJonathan Lemon SYSCTL_INT(_net_isr, OID_AUTO, count, CTLFLAG_RD,
2101cafed39SJonathan Lemon     &isrstat.isrs_count, 0, "");
2111cafed39SJonathan Lemon SYSCTL_INT(_net_isr, OID_AUTO, directed, CTLFLAG_RD,
2121cafed39SJonathan Lemon     &isrstat.isrs_directed, 0, "");
2131cafed39SJonathan Lemon SYSCTL_INT(_net_isr, OID_AUTO, deferred, CTLFLAG_RD,
2141cafed39SJonathan Lemon     &isrstat.isrs_deferred, 0, "");
2151cafed39SJonathan Lemon SYSCTL_INT(_net_isr, OID_AUTO, queued, CTLFLAG_RD,
2161cafed39SJonathan Lemon     &isrstat.isrs_queued, 0, "");
2177902224cSSam Leffler SYSCTL_INT(_net_isr, OID_AUTO, drop, CTLFLAG_RD,
2187902224cSSam Leffler     &isrstat.isrs_drop, 0, "");
2191cafed39SJonathan Lemon SYSCTL_INT(_net_isr, OID_AUTO, swi_count, CTLFLAG_RD,
2201cafed39SJonathan Lemon     &isrstat.isrs_swi_count, 0, "");
2211cafed39SJonathan Lemon 
2221cafed39SJonathan Lemon /*
2235fd04e38SRobert Watson  * Process all packets currently present in a netisr queue.  Used to
2245fd04e38SRobert Watson  * drain an existing set of packets waiting for processing when we
2255fd04e38SRobert Watson  * begin direct dispatch, to avoid processing packets out of order.
2265fd04e38SRobert Watson  */
2275fd04e38SRobert Watson static void
2285fd04e38SRobert Watson netisr_processqueue(struct netisr *ni)
2295fd04e38SRobert Watson {
2305fd04e38SRobert Watson 	struct mbuf *m;
2315fd04e38SRobert Watson 
2325fd04e38SRobert Watson 	for (;;) {
2335fd04e38SRobert Watson 		IF_DEQUEUE(ni->ni_queue, m);
2345fd04e38SRobert Watson 		if (m == NULL)
2355fd04e38SRobert Watson 			break;
2365fd04e38SRobert Watson 		ni->ni_handler(m);
2375fd04e38SRobert Watson 	}
2385fd04e38SRobert Watson }
2395fd04e38SRobert Watson 
2405fd04e38SRobert Watson /*
2411cafed39SJonathan Lemon  * Call the netisr directly instead of queueing the packet, if possible.
2421cafed39SJonathan Lemon  */
2431cafed39SJonathan Lemon void
2441cafed39SJonathan Lemon netisr_dispatch(int num, struct mbuf *m)
2451cafed39SJonathan Lemon {
2461cafed39SJonathan Lemon 	struct netisr *ni;
2471cafed39SJonathan Lemon 
2487902224cSSam Leffler 	isrstat.isrs_count++;		/* XXX redundant */
2491cafed39SJonathan Lemon 	KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
2501cafed39SJonathan Lemon 	    ("bad isr %d", num));
2511cafed39SJonathan Lemon 	ni = &netisrs[num];
252fb68148fSJonathan Lemon 	if (ni->ni_queue == NULL) {
2537902224cSSam Leffler 		isrstat.isrs_drop++;
254fb68148fSJonathan Lemon 		m_freem(m);
255fb68148fSJonathan Lemon 		return;
256fb68148fSJonathan Lemon 	}
2577902224cSSam Leffler 	/*
2587902224cSSam Leffler 	 * Do direct dispatch only for MPSAFE netisrs (and
2597902224cSSam Leffler 	 * only when enabled).  Note that when a netisr is
2607902224cSSam Leffler 	 * marked MPSAFE we permit multiple concurrent instances
2617902224cSSam Leffler 	 * to run.  We guarantee only the order in which
2627902224cSSam Leffler 	 * packets are processed for each "dispatch point" in
2637902224cSSam Leffler 	 * the system (i.e. call to netisr_dispatch or
2647902224cSSam Leffler 	 * netisr_queue).  This insures ordering of packets
2657902224cSSam Leffler 	 * from an interface but does not guarantee ordering
2667902224cSSam Leffler 	 * between multiple places in the system (e.g. IP
2677902224cSSam Leffler 	 * dispatched from interfaces vs. IP queued from IPSec).
2687902224cSSam Leffler 	 */
269cea2165bSRobert Watson 	if (netisr_direct && (ni->ni_flags & NETISR_MPSAFE)) {
2701cafed39SJonathan Lemon 		isrstat.isrs_directed++;
2711cafed39SJonathan Lemon 		/*
2727902224cSSam Leffler 		 * NB: We used to drain the queue before handling
2737902224cSSam Leffler 		 * the packet but now do not.  Doing so here will
2747902224cSSam Leffler 		 * not preserve ordering so instead we fallback to
2757902224cSSam Leffler 		 * guaranteeing order only from dispatch points
2767902224cSSam Leffler 		 * in the system (see above).
2771cafed39SJonathan Lemon 		 */
2781cafed39SJonathan Lemon 		ni->ni_handler(m);
2791cafed39SJonathan Lemon 	} else {
2801cafed39SJonathan Lemon 		isrstat.isrs_deferred++;
2811cafed39SJonathan Lemon 		if (IF_HANDOFF(ni->ni_queue, m, NULL))
2821cafed39SJonathan Lemon 			schednetisr(num);
2831cafed39SJonathan Lemon 	}
2841cafed39SJonathan Lemon }
2851cafed39SJonathan Lemon 
2861cafed39SJonathan Lemon /*
2871cafed39SJonathan Lemon  * Same as above, but always queue.
2881cafed39SJonathan Lemon  * This is either used in places where we are not confident that
2891cafed39SJonathan Lemon  * direct dispatch is possible, or where queueing is required.
2903161f583SAndre Oppermann  * It returns (0) on success and ERRNO on failure.  On failure the
2913161f583SAndre Oppermann  * mbuf has been free'd.
2921cafed39SJonathan Lemon  */
2931cafed39SJonathan Lemon int
2941cafed39SJonathan Lemon netisr_queue(int num, struct mbuf *m)
2951cafed39SJonathan Lemon {
2961cafed39SJonathan Lemon 	struct netisr *ni;
2971cafed39SJonathan Lemon 
2981cafed39SJonathan Lemon 	KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))),
2991cafed39SJonathan Lemon 	    ("bad isr %d", num));
3001cafed39SJonathan Lemon 	ni = &netisrs[num];
301fb68148fSJonathan Lemon 	if (ni->ni_queue == NULL) {
3027902224cSSam Leffler 		isrstat.isrs_drop++;
303fb68148fSJonathan Lemon 		m_freem(m);
3043161f583SAndre Oppermann 		return (ENXIO);
305fb68148fSJonathan Lemon 	}
3061cafed39SJonathan Lemon 	isrstat.isrs_queued++;
3071cafed39SJonathan Lemon 	if (!IF_HANDOFF(ni->ni_queue, m, NULL))
3083161f583SAndre Oppermann 		return (ENOBUFS);	/* IF_HANDOFF has free'd the mbuf */
3091cafed39SJonathan Lemon 	schednetisr(num);
3103161f583SAndre Oppermann 	return (0);
311e3b6e33cSJake Burkholder }
312e3b6e33cSJake Burkholder 
313e3b6e33cSJake Burkholder static void
314e3b6e33cSJake Burkholder swi_net(void *dummy)
315e3b6e33cSJake Burkholder {
3161cafed39SJonathan Lemon 	struct netisr *ni;
317e3b6e33cSJake Burkholder 	u_int bits;
318e3b6e33cSJake Burkholder 	int i;
3191cafed39SJonathan Lemon #ifdef DEVICE_POLLING
3201cafed39SJonathan Lemon 	const int polling = 1;
3211cafed39SJonathan Lemon #else
3221cafed39SJonathan Lemon 	const int polling = 0;
3231cafed39SJonathan Lemon #endif
324e3b6e33cSJake Burkholder 
3251cafed39SJonathan Lemon 	do {
326e3b6e33cSJake Burkholder 		bits = atomic_readandclear_int(&netisr);
327e3b6e33cSJake Burkholder 		if (bits == 0)
3281cafed39SJonathan Lemon 			break;
329e3b6e33cSJake Burkholder 		while ((i = ffs(bits)) != 0) {
3301cafed39SJonathan Lemon 			isrstat.isrs_swi_count++;
331e3b6e33cSJake Burkholder 			i--;
332e3b6e33cSJake Burkholder 			bits &= ~(1 << i);
3331cafed39SJonathan Lemon 			ni = &netisrs[i];
3341cafed39SJonathan Lemon 			if (ni->ni_handler == NULL) {
3351cafed39SJonathan Lemon 				printf("swi_net: unregistered isr %d.\n", i);
3361cafed39SJonathan Lemon 				continue;
337e3b6e33cSJake Burkholder 			}
3387902224cSSam Leffler 			if ((ni->ni_flags & NETISR_MPSAFE) == 0) {
3397902224cSSam Leffler 				mtx_lock(&Giant);
3407902224cSSam Leffler 				if (ni->ni_queue == NULL)
3417902224cSSam Leffler 					ni->ni_handler(NULL);
3427902224cSSam Leffler 				else
3437902224cSSam Leffler 					netisr_processqueue(ni);
3447902224cSSam Leffler 				mtx_unlock(&Giant);
3457902224cSSam Leffler 			} else {
3461cafed39SJonathan Lemon 				if (ni->ni_queue == NULL)
3471cafed39SJonathan Lemon 					ni->ni_handler(NULL);
3481cafed39SJonathan Lemon 				else
3495fd04e38SRobert Watson 					netisr_processqueue(ni);
3501cafed39SJonathan Lemon 			}
3517902224cSSam Leffler 		}
3521cafed39SJonathan Lemon 	} while (polling);
353e3b6e33cSJake Burkholder }
354e3b6e33cSJake Burkholder 
355e3b6e33cSJake Burkholder static void
356e3b6e33cSJake Burkholder start_netisr(void *dummy)
357e3b6e33cSJake Burkholder {
358e3b6e33cSJake Burkholder 
3597902224cSSam Leffler 	if (swi_add(NULL, "net", swi_net, NULL, SWI_NET, INTR_MPSAFE, &net_ih))
360e3b6e33cSJake Burkholder 		panic("start_netisr");
361e3b6e33cSJake Burkholder }
362e3b6e33cSJake Burkholder SYSINIT(start_netisr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_netisr, NULL)
363