summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_ppp.c7
-rw-r--r--sys/net/netisr.c46
-rw-r--r--sys/net/netisr.h2
-rw-r--r--sys/net/rtsock.c2
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);
OpenPOWER on IntegriCloud