diff options
author | 2015-04-01 04:00:55 +0000 | |
---|---|---|
committer | 2015-04-01 04:00:55 +0000 | |
commit | ca233e95fa36a014c391ad2f321c221e12d07d37 (patch) | |
tree | c0661ffdfd80fe45ada9437884771e3c73f10ae5 | |
parent | adapt to recent hostfile.c change: when parsing known_hosts without (diff) | |
download | wireguard-openbsd-ca233e95fa36a014c391ad2f321c221e12d07d37.tar.xz wireguard-openbsd-ca233e95fa36a014c391ad2f321c221e12d07d37.zip |
create a taskq for network tasks to run in. cut ether_input_mbuf
and if_input up so the work ether_input does gets run on the task
instead of directly from hardware receive handlers.
this is a step toward letting hardware drivers run without biglock
by shoving the work the stack does which needs that lock sideways.
general agreement at s2k15
ok mpi@ kettenis@ claudio@
-rw-r--r-- | sys/net/if.c | 57 | ||||
-rw-r--r-- | sys/net/if_var.h | 5 |
2 files changed, 55 insertions, 7 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index b24758a5b14..06851a75445 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.324 2015/03/29 01:05:02 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.325 2015/04/01 04:00:55 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -142,6 +142,8 @@ int if_group_egress_build(void); void if_link_state_change_task(void *); +void if_input_process(void *); + #ifdef DDB void ifa_print_all(void); #endif @@ -155,6 +157,8 @@ void net_tick(void *); int net_livelocked(void); int ifq_congestion; +struct taskq *softnettq; + /* * Network interface utility routines. * @@ -166,6 +170,11 @@ ifinit() { timeout_set(&net_tick_to, net_tick, &net_tick_to); + softnettq = taskq_create("softnet", 1, IPL_NET, + TASKQ_MPSAFE | TASKQ_CANTSLEEP); + if (softnettq == NULL) + panic("unable to create softnet taskq"); + net_tick(&net_tick_to); } @@ -431,28 +440,68 @@ if_start(struct ifnet *ifp) } } +struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); +struct task if_input_task = TASK_INITIALIZER(if_input_process, &if_input_queue); + void if_input(struct ifnet *ifp, struct mbuf_list *ml) { struct mbuf *m; - struct ifih *ifih; splassert(IPL_NET); - while ((m = ml_dequeue(ml)) != NULL) { + MBUF_LIST_FOREACH(ml, m) { m->m_pkthdr.rcvif = ifp; m->m_pkthdr.ph_rtableid = ifp->if_rdomain; + } #if NBPFILTER > 0 - if (ifp->if_bpf) + if (ifp->if_bpf) { + MBUF_LIST_FOREACH(ml, m) bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_IN); + } #endif + mq_enlist(&if_input_queue, ml); + task_add(softnettq, &if_input_task); +} + +void +ether_input_mbuf(struct ifnet *ifp, struct mbuf *m) +{ + mq_enqueue(&if_input_queue, m); + task_add(softnettq, &if_input_task); +} + +void +if_input_process(void *xmq) +{ + struct mbuf_queue *mq = xmq; + struct mbuf_list ml; + struct mbuf *m; + struct ifnet *ifp; + struct ifih *ifih; + int mit = 0; + int s; + + mq_delist(mq, &ml); + if (ml_empty(&ml)) + return; + + KERNEL_LOCK(); + s = splnet(); + while ((m = ml_dequeue(&ml)) != NULL) { + if ((++mit & 0x1f) == 0) + yield(); + + ifp = m->m_pkthdr.rcvif; SLIST_FOREACH(ifih, &ifp->if_inputs, ifih_next) { if ((*ifih->ifih_input)(ifp, NULL, m)) break; } } + splx(s); + KERNEL_UNLOCK(); } void diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 101a53b1f18..fbd66380bb6 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.22 2015/03/25 11:49:02 dlg Exp $ */ +/* $OpenBSD: if_var.h,v 1.23 2015/04/01 04:00:55 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -418,8 +418,7 @@ extern struct ifnet *lo0ifp; void if_start(struct ifnet *); void if_input(struct ifnet *, struct mbuf_list *); -#define ether_input_mbuf(ifp, m) ether_input((ifp), NULL, (m)) - +void ether_input_mbuf(struct ifnet *, struct mbuf *); void ether_ifattach(struct ifnet *); void ether_ifdetach(struct ifnet *); int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); |