On 08/01/18(Mon) 11:13, David Gwynne wrote: > this is tx mitigation again, ie, defer calling an interfaces start > routine until at least 4 packets are queued, or a task fires. > > the task firing is a problem for things like gif or vxlan that encap > a packet in ip and send it through the ip stack again. the ip stack > expects NET_RLOCK to be held. that is implicitly true when sending > out of the network stack, but not when the bundle task fires.
Well if_start() is a driver function. It should not require the NET_LOCK(). pf(4) has been fixed to not be re-entrant so the same thing has to be done for pseudo-driver. I like the fact that your diff is defining a new boundary between driver protected states and stack protected states. Here's a diff for gif(4), ok? Index: net/if_gif.c =================================================================== RCS file: /cvs/src/sys/net/if_gif.c,v retrieving revision 1.105 diff -u -p -r1.105 if_gif.c --- net/if_gif.c 20 Nov 2017 10:35:24 -0000 1.105 +++ net/if_gif.c 8 Jan 2018 14:05:45 -0000 @@ -231,17 +231,11 @@ gif_start(struct ifnet *ifp) switch (sc->gif_psrc->sa_family) { case AF_INET: - ip_output(m, NULL, NULL, 0, NULL, NULL, 0); + ip_send(m); break; #ifdef INET6 case AF_INET6: - /* - * force fragmentation to minimum MTU, to avoid path - * MTU discovery. It is too painful to ask for resend - * of inner packet, to achieve path MTU discovery for - * encapsulated packets. - */ - ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL); + ip6_send(m); break; #endif default: