Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.322 diff -u -p -r1.322 if.c --- net/if.c 18 Mar 2015 12:23:15 -0000 1.322 +++ net/if.c 18 Mar 2015 12:44:02 -0000 @@ -155,6 +155,8 @@ void net_tick(void *); int net_livelocked(void); int ifq_congestion; +struct taskq *softnettq; + /* * Network interface utility routines. * @@ -165,6 +167,11 @@ void 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); } Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.190 diff -u -p -r1.190 if_ethersubr.c --- net/if_ethersubr.c 17 Mar 2015 14:51:27 -0000 1.190 +++ net/if_ethersubr.c 18 Mar 2015 12:44:02 -0000 @@ -86,6 +86,8 @@ didn't get a copy, you may request one f #include #include #include +#include +#include #include /* required by if_trunk.h */ @@ -447,6 +449,55 @@ bad: m_freem(m); return (error); } + +void ether_input_process(void *); + +struct mbuf_queue ether_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); +struct task ether_input_task = + TASK_INITIALIZER(ether_input_process, ðer_input_queue); + +void +ether_input_list(struct ifnet *ifp, struct mbuf_list *ml) +{ + mq_enlist(ðer_input_queue, ml); + task_add(softnettq, ðer_input_task); +} + +void +ether_input_mbuf(struct ifnet *ifp, struct mbuf *m) +{ + mq_enqueue(ðer_input_queue, m); + task_add(softnettq, ðer_input_task); +} + +void +ether_input_process(void *xmq) +{ + struct mbuf_queue *mq = xmq; + struct mbuf *m0, *m; + u_int mit = 0; + int s; + + m0 = mq_dechain(mq); + if (m0 == NULL) + return; + + KERNEL_LOCK(); + s = splnet(); + do { + if ((++mit & 0x1f) == 0) + yield(); + + m = m0; + m0 = m->m_nextpkt; + m->m_nextpkt = NULL; + + ether_input(m->m_pkthdr.rcvif, NULL, m); + } while (m0 != NULL); + splx(s); + KERNEL_UNLOCK(); +} + /* * Process a received Ethernet packet; Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.21 diff -u -p -r1.21 if_var.h --- net/if_var.h 18 Mar 2015 12:23:15 -0000 1.21 +++ net/if_var.h 18 Mar 2015 12:44:02 -0000 @@ -393,11 +393,12 @@ do { \ extern struct ifnet_head ifnet; extern struct ifnet *lo0ifp; +extern struct taskq *softnettq; +void ether_input_list(struct ifnet *, struct mbuf_list *); +void ether_input_mbuf(struct ifnet *, struct mbuf *); 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_ifattach(struct ifnet *); void ether_ifdetach(struct ifnet *);