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 */
 

Reply via email to