Source-Changes-HG archive

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

[src/trunk]: src/sys Lock IFQ operations when NET_MPSAFE



details:   https://anonhg.NetBSD.org/src/rev/6b5b50351104
branches:  trunk
changeset: 797011:6b5b50351104
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Tue Jul 01 10:16:02 2014 +0000

description:
Lock IFQ operations when NET_MPSAFE

- Introduce NET_MPSAFE
  - not defined by default
- Add ifq_lock to protect ifnet#if_snd
- Initialize ifq_lock and lock IFQ operations
  when NET_MPSAFE

When NET_MPSAFE isn't defined, this modification
doesn't change its behavior and adds trivial
performance overheads.

Discussed with matt@ on tech-net

diffstat:

 sys/altq/if_altq.h |   3 ++-
 sys/net/if.c       |  13 +++++++++++--
 sys/net/if.h       |  53 +++++++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 56 insertions(+), 13 deletions(-)

diffs (212 lines):

diff -r b7109ca41c89 -r 6b5b50351104 sys/altq/if_altq.h
--- a/sys/altq/if_altq.h        Tue Jul 01 07:51:29 2014 +0000
+++ b/sys/altq/if_altq.h        Tue Jul 01 10:16:02 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_altq.h,v 1.13 2009/08/18 17:20:20 dyoung Exp $      */
+/*     $NetBSD: if_altq.h,v 1.14 2014/07/01 10:16:02 ozaki-r Exp $     */
 /*     $KAME: if_altq.h,v 1.12 2005/04/13 03:44:25 suz Exp $   */
 
 /*
@@ -45,6 +45,7 @@
        int     ifq_len;
        int     ifq_maxlen;
        int     ifq_drops;
+       kmutex_t        *ifq_lock;
 
        /* alternate queueing related fields */
        int     altq_type;              /* discipline type */
diff -r b7109ca41c89 -r 6b5b50351104 sys/net/if.c
--- a/sys/net/if.c      Tue Jul 01 07:51:29 2014 +0000
+++ b/sys/net/if.c      Tue Jul 01 10:16:02 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.c,v 1.284 2014/07/01 05:49:18 rtr Exp $     */
+/*     $NetBSD: if.c,v 1.285 2014/07/01 10:16:02 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.284 2014/07/01 05:49:18 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.285 2014/07/01 10:16:02 ozaki-r Exp $");
 
 #include "opt_inet.h"
 
@@ -611,6 +611,12 @@
        ifp->if_snd.altq_ifp  = ifp;
 #endif
 
+#ifdef NET_MPSAFE
+       ifp->if_snd.ifq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+#else
+       ifp->if_snd.ifq_lock = NULL;
+#endif
+
        ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
        (void)pfil_run_hooks(if_pfil,
            (struct mbuf **)PFIL_IFNET_ATTACH, ifp, PFIL_IFNET);
@@ -732,6 +738,9 @@
                altq_detach(&ifp->if_snd);
 #endif
 
+       if (ifp->if_snd.ifq_lock)
+               mutex_obj_free(ifp->if_snd.ifq_lock);
+
        sysctl_teardown(&ifp->if_sysctl_log);
 
 #if NCARP > 0
diff -r b7109ca41c89 -r 6b5b50351104 sys/net/if.h
--- a/sys/net/if.h      Tue Jul 01 07:51:29 2014 +0000
+++ b/sys/net/if.h      Tue Jul 01 10:16:02 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if.h,v 1.168 2014/07/01 05:49:18 rtr Exp $     */
+/*     $NetBSD: if.h,v 1.169 2014/07/01 10:16:02 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -86,6 +86,8 @@
 #include <net/pktqueue.h>
 #endif
 
+//#define NET_MPSAFE 1
+
 /*
  * Always include ALTQ glue here -- we use the ALTQ interface queue
  * structure even when ALTQ is not configured into the kernel so that
@@ -198,11 +200,12 @@
  * Structure defining a queue for a network interface.
  */
 struct ifqueue {
-       struct  mbuf *ifq_head;
-       struct  mbuf *ifq_tail;
-       int     ifq_len;
-       int     ifq_maxlen;
-       int     ifq_drops;
+       struct          mbuf *ifq_head;
+       struct          mbuf *ifq_tail;
+       int             ifq_len;
+       int             ifq_maxlen;
+       int             ifq_drops;
+       kmutex_t        *ifq_lock;
 };
 
 struct ifnet_lock;
@@ -424,6 +427,9 @@
        "\23TSO6"               \
        "\24LRO"                \
 
+#define IFQ_LOCK(_ifq)         if ((_ifq)->ifq_lock) mutex_enter((_ifq)->ifq_lock)
+#define IFQ_UNLOCK(_ifq)       if ((_ifq)->ifq_lock) mutex_exit((_ifq)->ifq_lock)
+
 /*
  * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1)
  * input routines have queues of messages stored on ifqueue structures
@@ -752,6 +758,7 @@
 
 #define IFQ_ENQUEUE(ifq, m, pattr, err)                                        \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (ALTQ_IS_ENABLED((ifq)))                                     \
                ALTQ_ENQUEUE((ifq), (m), (pattr), (err));               \
        else {                                                          \
@@ -765,34 +772,41 @@
        }                                                               \
        if ((err))                                                      \
                (ifq)->ifq_drops++;                                     \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 
 #define IFQ_DEQUEUE(ifq, m)                                            \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (TBR_IS_ENABLED((ifq)))                                      \
                (m) = tbr_dequeue((ifq), ALTDQ_REMOVE);                 \
        else if (ALTQ_IS_ENABLED((ifq)))                                \
                ALTQ_DEQUEUE((ifq), (m));                               \
        else                                                            \
                IF_DEQUEUE((ifq), (m));                                 \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 
 #define        IFQ_POLL(ifq, m)                                                \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (TBR_IS_ENABLED((ifq)))                                      \
                (m) = tbr_dequeue((ifq), ALTDQ_POLL);                   \
        else if (ALTQ_IS_ENABLED((ifq)))                                \
                ALTQ_POLL((ifq), (m));                                  \
        else                                                            \
                IF_POLL((ifq), (m));                                    \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 
 #define        IFQ_PURGE(ifq)                                                  \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (ALTQ_IS_ENABLED((ifq)))                                     \
                ALTQ_PURGE((ifq));                                      \
        else                                                            \
                IF_PURGE((ifq));                                        \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 
 #define        IFQ_SET_READY(ifq)                                              \
@@ -802,6 +816,7 @@
 
 #define        IFQ_CLASSIFY(ifq, m, af, pattr)                                 \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (ALTQ_IS_ENABLED((ifq))) {                                   \
                if (ALTQ_NEEDS_CLASSIFY((ifq)))                         \
                        (pattr)->pattr_class = (*(ifq)->altq_classify)  \
@@ -809,6 +824,7 @@
                (pattr)->pattr_af = (af);                               \
                (pattr)->pattr_hdr = mtod((m), void *);         \
        }                                                               \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 #else /* ! ALTQ */
 #define        ALTQ_DECL(x)            /* nothing */
@@ -816,6 +832,7 @@
 
 #define        IFQ_ENQUEUE(ifq, m, pattr, err)                                 \
 do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
        if (IF_QFULL((ifq))) {                                          \
                m_freem((m));                                           \
                (err) = ENOBUFS;                                        \
@@ -825,13 +842,29 @@
        }                                                               \
        if ((err))                                                      \
                (ifq)->ifq_drops++;                                     \
+       IFQ_UNLOCK((ifq));                                              \
+} while (/*CONSTCOND*/ 0)
+
+#define        IFQ_DEQUEUE(ifq, m)                                             \
+do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
+       IF_DEQUEUE((ifq), (m));                                         \
+       IFQ_UNLOCK((ifq));                                              \
 } while (/*CONSTCOND*/ 0)
 
-#define        IFQ_DEQUEUE(ifq, m)     IF_DEQUEUE((ifq), (m))
+#define        IFQ_POLL(ifq, m)                                                \
+do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
+       IF_POLL((ifq), (m));                                            \
+       IFQ_UNLOCK((ifq));                                              \
+} while (/*CONSTCOND*/ 0)
 
-#define        IFQ_POLL(ifq, m)        IF_POLL((ifq), (m))
-
-#define        IFQ_PURGE(ifq)          IF_PURGE((ifq))
+#define        IFQ_PURGE(ifq)                                                  \
+do {                                                                   \
+       IFQ_LOCK((ifq));                                                \
+       IF_PURGE((ifq));                                                \
+       IFQ_UNLOCK((ifq));                                              \
+} while (/*CONSTCOND*/ 0)
 
 #define        IFQ_SET_READY(ifq)      /* nothing */
 



Home | Main Index | Thread Index | Old Index