Index: kern/kern_poll.c =================================================================== --- kern/kern_poll.c (revision 180196) +++ kern/kern_poll.c (working copy) @@ -262,10 +262,9 @@ { mtx_init(&poll_mtx, "polling", NULL, MTX_DEF); - netisr_register(NETISR_POLL, (netisr_t *)netisr_poll, NULL, - NETISR_MPSAFE); + netisr_register(NETISR_POLL, (netisr_t *)netisr_poll, NULL, 0); netisr_register(NETISR_POLLMORE, (netisr_t *)netisr_pollmore, NULL, - NETISR_MPSAFE); + 0); } SYSINIT(device_poll, SI_SUB_CLOCKS, SI_ORDER_MIDDLE, init_device_poll, NULL); Index: netatalk/ddp_usrreq.c =================================================================== --- netatalk/ddp_usrreq.c (revision 180196) +++ netatalk/ddp_usrreq.c (working copy) @@ -267,9 +267,9 @@ mtx_init(&atintrq2.ifq_mtx, "at2_inq", NULL, MTX_DEF); mtx_init(&aarpintrq.ifq_mtx, "aarp_inq", NULL, MTX_DEF); DDP_LIST_LOCK_INIT(); - netisr_register(NETISR_ATALK1, at1intr, &atintrq1, NETISR_MPSAFE); - netisr_register(NETISR_ATALK2, at2intr, &atintrq2, NETISR_MPSAFE); - netisr_register(NETISR_AARP, aarpintr, &aarpintrq, NETISR_MPSAFE); + netisr_register(NETISR_ATALK1, at1intr, &atintrq1, 0); + netisr_register(NETISR_ATALK2, at2intr, &atintrq2, 0); + netisr_register(NETISR_AARP, aarpintr, &aarpintrq, 0); } #if 0 Index: netnatm/natm_proto.c =================================================================== --- netnatm/natm_proto.c (revision 180196) +++ netnatm/natm_proto.c (working copy) @@ -105,7 +105,7 @@ natmintrq.ifq_maxlen = natmqmaxlen; NATM_LOCK_INIT(); mtx_init(&natmintrq.ifq_mtx, "natm_inq", NULL, MTX_DEF); - netisr_register(NETISR_NATM, natmintr, &natmintrq, NETISR_MPSAFE); + netisr_register(NETISR_NATM, natmintr, &natmintrq, 0); } DOMAIN_SET(natm); Index: netinet/ip_input.c =================================================================== --- netinet/ip_input.c (revision 180196) +++ netinet/ip_input.c (working copy) @@ -267,7 +267,7 @@ ip_id = time_second & 0xffff; ipintrq.ifq_maxlen = ipqmaxlen; mtx_init(&ipintrq.ifq_mtx, "ip_inq", NULL, MTX_DEF); - netisr_register(NETISR_IP, ip_input, &ipintrq, NETISR_MPSAFE); + netisr_register(NETISR_IP, ip_input, &ipintrq, 0); } void Index: netinet/if_ether.c =================================================================== --- netinet/if_ether.c (revision 180196) +++ netinet/if_ether.c (working copy) @@ -1040,6 +1040,6 @@ arpintrq.ifq_maxlen = 50; mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF); - netisr_register(NETISR_ARP, arpintr, &arpintrq, NETISR_MPSAFE); + netisr_register(NETISR_ARP, arpintr, &arpintrq, 0); } SYSINIT(arp, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY, arp_init, 0); Index: netipx/ipx_input.c =================================================================== --- netipx/ipx_input.c (revision 180196) +++ netipx/ipx_input.c (working copy) @@ -153,7 +153,7 @@ ipxintrq.ifq_maxlen = ipxqmaxlen; mtx_init(&ipxintrq.ifq_mtx, "ipx_inq", NULL, MTX_DEF); - netisr_register(NETISR_IPX, ipxintr, &ipxintrq, NETISR_MPSAFE); + netisr_register(NETISR_IPX, ipxintr, &ipxintrq, 0); } /* Index: netgraph/ng_base.c =================================================================== --- netgraph/ng_base.c (revision 180196) +++ netgraph/ng_base.c (working copy) @@ -3068,7 +3068,7 @@ NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0); uma_zone_set_max(ng_qdzone, maxdata); netisr_register(NETISR_NETGRAPH, (netisr_t *)ngintr, NULL, - NETISR_MPSAFE); + 0); break; case MOD_UNLOAD: /* You can't unload it because an interface may be using it. */ Index: dev/usb/usb_ethersubr.c =================================================================== --- dev/usb/usb_ethersubr.c (revision 180196) +++ dev/usb/usb_ethersubr.c (working copy) @@ -82,6 +82,8 @@ struct usb_qdat *q; struct ifnet *ifp; + mtx_lock(&Giant); + /* Check the RX queue */ while(1) { IF_DEQUEUE(&usbq_rx, m); @@ -109,6 +111,8 @@ (*ifp->if_start)(ifp); } + mtx_unlock(&Giant); + return; } @@ -117,7 +121,8 @@ { if (mtx_inited) return; - netisr_register(NETISR_USB, (netisr_t *)usbintr, NULL, 0); + netisr_register(NETISR_USB, (netisr_t *)usbintr, NULL, + NETISR_FORCEQUEUE); mtx_init(&usbq_tx.ifq_mtx, "usbq_tx_mtx", NULL, MTX_DEF); mtx_init(&usbq_rx.ifq_mtx, "usbq_rx_mtx", NULL, MTX_DEF); mtx_inited++; Index: net/netisr.c =================================================================== --- net/netisr.c (revision 180196) +++ net/netisr.c (working copy) @@ -161,27 +161,18 @@ m_freem(m); return; } + /* - * Do direct dispatch only for MPSAFE netisrs (and - * only when enabled). Note that when a netisr is - * marked MPSAFE we permit multiple concurrent instances - * to run. We guarantee only the order in which - * packets are processed for each "dispatch point" in - * the system (i.e. call to netisr_dispatch or - * netisr_queue). This insures ordering of packets - * from an interface but does not guarantee ordering - * between multiple places in the system (e.g. IP - * dispatched from interfaces vs. IP queued from IPSec). + * Unless NETISR_FORCEQUEUE is set on the netisr (generally + * indicating that the handler still requires Giant, which cannot be + * acquired in arbitrary order with respect to a caller), directly + * dispatch handling of this packet. Source ordering is maintained + * by virtue of callers consistently calling one of queued or direct + * dispatch, and the forcequeue flag being immutable after + * registration. */ - if (netisr_direct && (ni->ni_flags & NETISR_MPSAFE)) { + if (netisr_direct && !(ni->ni_flags & NETISR_FORCEQUEUE)) { isrstat.isrs_directed++; - /* - * NB: We used to drain the queue before handling - * the packet but now do not. Doing so here will - * not preserve ordering so instead we fallback to - * guaranteeing order only from dispatch points - * in the system (see above). - */ ni->ni_handler(m); } else { isrstat.isrs_deferred++; @@ -242,19 +233,10 @@ printf("swi_net: unregistered isr %d.\n", i); continue; } - if ((ni->ni_flags & NETISR_MPSAFE) == 0) { - mtx_lock(&Giant); - if (ni->ni_queue == NULL) - ni->ni_handler(NULL); - else - netisr_processqueue(ni); - mtx_unlock(&Giant); - } else { - if (ni->ni_queue == NULL) - ni->ni_handler(NULL); - else - netisr_processqueue(ni); - } + if (ni->ni_queue == NULL) + ni->ni_handler(NULL); + else + netisr_processqueue(ni); } } while (polling); } Index: net/netisr.h =================================================================== --- net/netisr.h (revision 180196) +++ net/netisr.h (working copy) @@ -83,7 +83,7 @@ void netisr_dispatch(int, struct mbuf *); int netisr_queue(int, struct mbuf *); -#define NETISR_MPSAFE 0x0001 /* ISR does not need Giant */ +#define NETISR_FORCEQUEUE 0x0002 /* Force queued dispatch. */ void netisr_register(int, netisr_t *, struct ifqueue *, int); void netisr_unregister(int); Index: net/if_ppp.c =================================================================== --- net/if_ppp.c (revision 180196) +++ net/if_ppp.c (working copy) @@ -274,7 +274,8 @@ LIST_INIT(&ppp_softc_list); if_clone_attach(&ppp_cloner); - netisr_register(NETISR_PPP, (netisr_t *)pppintr, NULL, 0); + netisr_register(NETISR_PPP, (netisr_t *)pppintr, NULL, + NETISR_FORCEQUEUE); /* * XXX layering violation - if_ppp can work over any lower * level transport that cares to attach to it. @@ -1212,8 +1213,7 @@ int s; struct mbuf *m; - GIANT_REQUIRED; - + mtx_lock(&Giant); PPP_LIST_LOCK(); LIST_FOREACH(sc, &ppp_softc_list, sc_list) { s = splimp(); @@ -1237,6 +1237,7 @@ } } PPP_LIST_UNLOCK(); + mtx_unlock(&Giant); } #ifdef PPP_COMPRESS Index: net/rtsock.c =================================================================== --- net/rtsock.c (revision 180196) +++ net/rtsock.c (working copy) @@ -117,7 +117,7 @@ if (TUNABLE_INT_FETCH("net.route.netisr_maxqlen", &tmp)) rtsintrq.ifq_maxlen = tmp; mtx_init(&rtsintrq.ifq_mtx, "rts_inq", NULL, MTX_DEF); - netisr_register(NETISR_ROUTE, rts_input, &rtsintrq, NETISR_MPSAFE); + netisr_register(NETISR_ROUTE, rts_input, &rtsintrq, 0); } SYSINIT(rtsock, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, rts_init, 0); Index: netinet6/ip6_input.c =================================================================== --- netinet6/ip6_input.c (revision 180197) +++ netinet6/ip6_input.c (working copy) @@ -180,7 +180,7 @@ ip6intrq.ifq_maxlen = ip6qmaxlen; mtx_init(&ip6intrq.ifq_mtx, "ip6_inq", NULL, MTX_DEF); - netisr_register(NETISR_IPV6, ip6_input, &ip6intrq, NETISR_MPSAFE); + netisr_register(NETISR_IPV6, ip6_input, &ip6intrq, 0); scope6_init(); addrsel_policy_init(); nd6_init();