diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/if_ppp.c | 7 | ||||
-rw-r--r-- | sys/net/netisr.c | 46 | ||||
-rw-r--r-- | sys/net/netisr.h | 2 | ||||
-rw-r--r-- | sys/net/rtsock.c | 2 |
4 files changed, 21 insertions, 36 deletions
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 5030ac58..a24cd81 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -274,7 +274,8 @@ ppp_modevent(module_t mod, int type, void *data) 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 @@ pppintr() 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 @@ pppintr() } } PPP_LIST_UNLOCK(); + mtx_unlock(&Giant); } #ifdef PPP_COMPRESS diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 9307b53..ed5466c 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -77,6 +77,8 @@ netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags) KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), ("bad isr %d", num)); + KASSERT(flags == 0 || flags == NETISR_FORCEQUEUE, + ("netisr_register: bad flags 0x%x\n", flags)); netisrs[num].ni_handler = handler; netisrs[num].ni_queue = inq; netisrs[num].ni_flags = flags; @@ -161,27 +163,18 @@ netisr_dispatch(int num, struct mbuf *m) 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 +235,10 @@ swi_net(void *dummy) 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); } diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 1fb411c..d5bd8e7 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -83,7 +83,7 @@ typedef void netisr_t (struct mbuf *); 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); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 9511035..99e0257 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -117,7 +117,7 @@ rts_init(void) 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); |