Index: if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.626 diff -u -p -r1.626 if.c --- if.c 1 Feb 2021 07:43:33 -0000 1.626 +++ if.c 16 Feb 2021 12:29:25 -0000 @@ -238,7 +238,7 @@ int ifq_congestion; int netisr; -#define NET_TASKQ 1 +#define NET_TASKQ 4 struct taskq *nettqmp[NET_TASKQ]; struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL); @@ -831,10 +831,8 @@ if_input_process(struct ifnet *ifp, stru * to PF globals, pipex globals, unicast and multicast addresses * lists and the socket layer. */ - NET_LOCK(); while ((m = ml_dequeue(ml)) != NULL) (*ifp->if_input)(ifp, m); - NET_UNLOCK(); } void Index: if_loop.c =================================================================== RCS file: /cvs/src/sys/net/if_loop.c,v retrieving revision 1.91 diff -u -p -r1.91 if_loop.c --- if_loop.c 22 Jul 2020 02:16:01 -0000 1.91 +++ if_loop.c 16 Feb 2021 12:29:25 -0000 @@ -231,11 +231,17 @@ void loinput(struct ifnet *ifp, struct mbuf *m) { int error; + int unlocked; if ((m->m_flags & M_PKTHDR) == 0) panic("%s: no header mbuf", __func__); + unlocked = (rw_status(&netlock) != RW_WRITE); + if (unlocked) + NET_LOCK(); error = if_input_local(ifp, m, m->m_pkthdr.ph_family); + if (unlocked) + NET_UNLOCK(); if (error) ifp->if_ierrors++; } Index: if_tun.c =================================================================== RCS file: /cvs/src/sys/net/if_tun.c,v retrieving revision 1.229 diff -u -p -r1.229 if_tun.c --- if_tun.c 19 Jan 2021 19:39:58 -0000 1.229 +++ if_tun.c 16 Feb 2021 12:29:25 -0000 @@ -865,9 +865,7 @@ tun_dev_write(dev_t dev, struct uio *uio if (error != 0) goto drop; - NET_LOCK(); if_vinput(ifp, m0); - NET_UNLOCK(); tun_put(sc); return (0); @@ -883,6 +881,8 @@ void tun_input(struct ifnet *ifp, struct mbuf *m0) { uint32_t af; + void (*input)(struct ifnet *, struct mbuf *); + int unlocked; KASSERT(m0->m_len >= sizeof(af)); @@ -892,22 +892,29 @@ tun_input(struct ifnet *ifp, struct mbuf switch (ntohl(af)) { case AF_INET: - ipv4_input(ifp, m0); + input = ipv4_input; break; #ifdef INET6 case AF_INET6: - ipv6_input(ifp, m0); + input = ipv6_input; break; #endif #ifdef MPLS case AF_MPLS: - mpls_input(ifp, m0); + input = mpls_input; break; #endif default: m_freem(m0); - break; + return; } + + unlocked = (rw_status(&netlock) != RW_WRITE); + if (unlocked) + NET_LOCK(); + (*input)(ifp, m0); + if (unlocked) + NET_UNLOCK(); } /*