Module Name: src Committed By: ozaki-r Date: Tue Jul 1 10:16:02 UTC 2014
Modified Files: src/sys/altq: if_altq.h src/sys/net: if.c if.h Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/sys/altq/if_altq.h cvs rdiff -u -r1.284 -r1.285 src/sys/net/if.c cvs rdiff -u -r1.168 -r1.169 src/sys/net/if.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/altq/if_altq.h diff -u src/sys/altq/if_altq.h:1.13 src/sys/altq/if_altq.h:1.14 --- src/sys/altq/if_altq.h:1.13 Tue Aug 18 17:20:20 2009 +++ src/sys/altq/if_altq.h Tue Jul 1 10:16:02 2014 @@ -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 @@ struct ifaltq { int ifq_len; int ifq_maxlen; int ifq_drops; + kmutex_t *ifq_lock; /* alternate queueing related fields */ int altq_type; /* discipline type */ Index: src/sys/net/if.c diff -u src/sys/net/if.c:1.284 src/sys/net/if.c:1.285 --- src/sys/net/if.c:1.284 Tue Jul 1 05:49:18 2014 +++ src/sys/net/if.c Tue Jul 1 10:16:02 2014 @@ -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 @@ if_attach(ifnet_t *ifp) 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 @@ if_detach(struct ifnet *ifp) 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 Index: src/sys/net/if.h diff -u src/sys/net/if.h:1.168 src/sys/net/if.h:1.169 --- src/sys/net/if.h:1.168 Tue Jul 1 05:49:18 2014 +++ src/sys/net/if.h Tue Jul 1 10:16:02 2014 @@ -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 @@ struct if_data { * 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 @@ typedef struct ifnet { "\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 @@ do { \ #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 @@ do { \ } \ 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 @@ do { \ #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 @@ do { \ (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 @@ do { \ #define IFQ_ENQUEUE(ifq, m, pattr, err) \ do { \ + IFQ_LOCK((ifq)); \ if (IF_QFULL((ifq))) { \ m_freem((m)); \ (err) = ENOBUFS; \ @@ -825,13 +842,29 @@ do { \ } \ if ((err)) \ (ifq)->ifq_drops++; \ + IFQ_UNLOCK((ifq)); \ } while (/*CONSTCOND*/ 0) -#define IFQ_DEQUEUE(ifq, m) IF_DEQUEUE((ifq), (m)) +#define IFQ_DEQUEUE(ifq, m) \ +do { \ + IFQ_LOCK((ifq)); \ + IF_DEQUEUE((ifq), (m)); \ + IFQ_UNLOCK((ifq)); \ +} while (/*CONSTCOND*/ 0) -#define IFQ_POLL(ifq, m) IF_POLL((ifq), (m)) +#define IFQ_POLL(ifq, m) \ +do { \ + IFQ_LOCK((ifq)); \ + IF_POLL((ifq), (m)); \ + IFQ_UNLOCK((ifq)); \ +} while (/*CONSTCOND*/ 0) -#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 */