Module Name: src Committed By: knakahara Date: Mon Jun 20 06:52:44 UTC 2016
Modified Files: src/sys/net: if_loop.c Log Message: make looutput() MP-safe, so that lo(4) can enable IFEF_OUTPUT_MPSAFE. making MP-scalable is future work. To generate a diff of this commit: cvs rdiff -u -r1.87 -r1.88 src/sys/net/if_loop.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_loop.c diff -u src/sys/net/if_loop.c:1.87 src/sys/net/if_loop.c:1.88 --- src/sys/net/if_loop.c:1.87 Fri Jun 10 13:27:16 2016 +++ src/sys/net/if_loop.c Mon Jun 20 06:52:44 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if_loop.c,v 1.87 2016/06/10 13:27:16 ozaki-r Exp $ */ +/* $NetBSD: if_loop.c,v 1.88 2016/06/20 06:52:44 knakahara Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.87 2016/06/10 13:27:16 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_loop.c,v 1.88 2016/06/20 06:52:44 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -157,6 +157,7 @@ loop_clone_create(struct if_clone *ifc, ifp->if_mtu = LOMTU; ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST | IFF_RUNNING; + ifp->if_extflags = IFEF_OUTPUT_MPSAFE; ifp->if_ioctl = loioctl; ifp->if_output = looutput; #ifdef ALTQ @@ -211,12 +212,12 @@ looutput(struct ifnet *ifp, struct mbuf struct ifqueue *ifq = NULL; int s, isr = -1; int csum_flags; + int error = 0; size_t pktlen; MCLAIM(m, ifp->if_mowner); -#ifndef NET_MPSAFE - KASSERT(KERNEL_LOCKED_P()); -#endif + + KERNEL_LOCK(1, NULL); if ((m->m_flags & M_PKTHDR) == 0) panic("looutput: no header mbuf"); @@ -226,8 +227,9 @@ looutput(struct ifnet *ifp, struct mbuf if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) { m_freem(m); - return (rt->rt_flags & RTF_BLACKHOLE ? 0 : + error = (rt->rt_flags & RTF_BLACKHOLE ? 0 : rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH); + goto out; } pktlen = m->m_pkthdr.len; @@ -241,8 +243,6 @@ looutput(struct ifnet *ifp, struct mbuf */ if ((ALTQ_IS_ENABLED(&ifp->if_snd) || TBR_IS_ENABLED(&ifp->if_snd)) && ifp->if_start == lostart) { - int error; - /* * If the queueing discipline needs packet classification, * do it before prepending the link headers. @@ -250,12 +250,14 @@ looutput(struct ifnet *ifp, struct mbuf IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); M_PREPEND(m, sizeof(uint32_t), M_DONTWAIT); - if (m == NULL) - return (ENOBUFS); + if (m == NULL) { + error = ENOBUFS; + goto out; + } *(mtod(m, uint32_t *)) = dst->sa_family; error = ifp->if_transmit(ifp, m); - return (error); + goto out; } #endif /* ALTQ */ @@ -310,12 +312,13 @@ looutput(struct ifnet *ifp, struct mbuf printf("%s: can't handle af%d\n", ifp->if_xname, dst->sa_family); m_freem(m); - return (EAFNOSUPPORT); + error = EAFNOSUPPORT; + goto out; } s = splnet(); if (__predict_true(pktq)) { - int error = 0; + error = 0; if (__predict_true(pktq_enqueue(pktq, m, 0))) { ifp->if_ipackets++; @@ -325,20 +328,23 @@ looutput(struct ifnet *ifp, struct mbuf error = ENOBUFS; } splx(s); - return error; + goto out; } if (IF_QFULL(ifq)) { IF_DROP(ifq); m_freem(m); splx(s); - return (ENOBUFS); + error = ENOBUFS; + goto out; } IF_ENQUEUE(ifq, m); schednetisr(isr); ifp->if_ipackets++; ifp->if_ibytes += m->m_pkthdr.len; splx(s); - return (0); +out: + KERNEL_UNLOCK_ONE(NULL); + return error; } #ifdef ALTQ