Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net make looutput() MP-safe, so that lo(4) can enable IF...



details:   https://anonhg.NetBSD.org/src/rev/64f75ed35d5a
branches:  trunk
changeset: 346032:64f75ed35d5a
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Mon Jun 20 06:52:44 2016 +0000

description:
make looutput() MP-safe, so that lo(4) can enable IFEF_OUTPUT_MPSAFE.

making MP-scalable is future work.

diffstat:

 sys/net/if_loop.c |  38 ++++++++++++++++++++++----------------
 1 files changed, 22 insertions(+), 16 deletions(-)

diffs (123 lines):

diff -r deb38800d4b3 -r 64f75ed35d5a sys/net/if_loop.c
--- a/sys/net/if_loop.c Mon Jun 20 06:46:37 2016 +0000
+++ b/sys/net/if_loop.c Mon Jun 20 06:52:44 2016 +0000
@@ -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 @@
 
        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 @@
        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 @@
 
        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 @@
         */
        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 @@
                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 @@
                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 @@
                        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



Home | Main Index | Thread Index | Old Index