Module Name:    src
Committed By:   ozaki-r
Date:           Mon Oct  3 11:06:06 UTC 2016

Modified Files:
        src/sys/net: if.c if.h if_arcsubr.c if_atmsubr.c if_ecosubr.c
            if_ethersubr.c if_fddisubr.c if_ieee1394subr.c if_mpls.c if_pppoe.c
            if_spppsubr.c if_tokensubr.c rtsock.c
        src/sys/netatalk: ddp_input.c ddp_usrreq.c
        src/sys/netinet: if_arp.c
        src/sys/netmpls: mpls_proto.c
        src/sys/netnatm: natm.c natm_proto.c

Log Message:
Fix race condition on ifqueue used by traditional netisr

If a underlying network device driver supports MSI/MSI-X, RX interrupts
can be delivered to arbitrary CPUs. This means that Layer 2 subroutines
such as ether_input (softint) and subsequent Layer 3 subroutines (softint)
which are called via traditional netisr can be dispatched on an arbitrary
CPU. Layer 2 subroutines now run without any locks (expected) and so a
Layer 2 subroutine and a Layer 3 subroutine can run in parallel.

There is a shared data between a Layer 2 routine and a Layer 3 routine,
that is ifqueue and IF_ENQUEUE (from L2) and IF_DEQUEUE (from L3) on it
are racy now.

To fix the race condition, use ifqueue#ifq_lock to protect ifqueue
instead of splnet that is meaningless now.

The same race condition exists in route_intr. Fix it as well.

Reviewed by knakahara@


To generate a diff of this commit:
cvs rdiff -u -r1.357 -r1.358 src/sys/net/if.c
cvs rdiff -u -r1.226 -r1.227 src/sys/net/if.h
cvs rdiff -u -r1.73 -r1.74 src/sys/net/if_arcsubr.c
cvs rdiff -u -r1.59 -r1.60 src/sys/net/if_atmsubr.c
cvs rdiff -u -r1.48 -r1.49 src/sys/net/if_ecosubr.c
cvs rdiff -u -r1.227 -r1.228 src/sys/net/if_ethersubr.c
cvs rdiff -u -r1.101 -r1.102 src/sys/net/if_fddisubr.c
cvs rdiff -u -r1.57 -r1.58 src/sys/net/if_ieee1394subr.c
cvs rdiff -u -r1.27 -r1.28 src/sys/net/if_mpls.c
cvs rdiff -u -r1.117 -r1.118 src/sys/net/if_pppoe.c
cvs rdiff -u -r1.154 -r1.155 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.77 -r1.78 src/sys/net/if_tokensubr.c
cvs rdiff -u -r1.196 -r1.197 src/sys/net/rtsock.c
cvs rdiff -u -r1.27 -r1.28 src/sys/netatalk/ddp_input.c
cvs rdiff -u -r1.68 -r1.69 src/sys/netatalk/ddp_usrreq.c
cvs rdiff -u -r1.227 -r1.228 src/sys/netinet/if_arp.c
cvs rdiff -u -r1.29 -r1.30 src/sys/netmpls/mpls_proto.c
cvs rdiff -u -r1.52 -r1.53 src/sys/netnatm/natm.c
cvs rdiff -u -r1.16 -r1.17 src/sys/netnatm/natm_proto.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.c
diff -u src/sys/net/if.c:1.357 src/sys/net/if.c:1.358
--- src/sys/net/if.c:1.357	Mon Aug  1 03:15:30 2016
+++ src/sys/net/if.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.357 2016/08/01 03:15:30 ozaki-r Exp $	*/
+/*	$NetBSD: if.c,v 1.358 2016/10/03 11:06:06 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.357 2016/08/01 03:15:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.358 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -657,7 +657,7 @@ if_initialize(ifnet_t *ifp)
 	ifp->if_snd.altq_ifp  = ifp;
 #endif
 
-	ifp->if_snd.ifq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
+	IFQ_LOCK_INIT(&ifp->if_snd);
 
 	ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
 	(void)pfil_run_hooks(if_pfil,

Index: src/sys/net/if.h
diff -u src/sys/net/if.h:1.226 src/sys/net/if.h:1.227
--- src/sys/net/if.h:1.226	Wed Sep 21 10:50:22 2016
+++ src/sys/net/if.h	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.h,v 1.226 2016/09/21 10:50:22 roy Exp $	*/
+/*	$NetBSD: if.h,v 1.227 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -917,6 +917,11 @@ do {									\
 
 #endif /* ALTQ */
 
+#define IFQ_LOCK_INIT(ifq)	(ifq)->ifq_lock =			\
+	    mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET)
+#define IFQ_LOCK(ifq)		mutex_enter((ifq)->ifq_lock)
+#define IFQ_UNLOCK(ifq)		mutex_exit((ifq)->ifq_lock)
+
 #define	IFQ_IS_EMPTY(ifq)		IF_IS_EMPTY((ifq))
 #define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
 #define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)

Index: src/sys/net/if_arcsubr.c
diff -u src/sys/net/if_arcsubr.c:1.73 src/sys/net/if_arcsubr.c:1.74
--- src/sys/net/if_arcsubr.c:1.73	Thu Apr 28 14:40:09 2016
+++ src/sys/net/if_arcsubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arcsubr.c,v 1.73 2016/04/28 14:40:09 ozaki-r Exp $	*/
+/*	$NetBSD: if_arcsubr.c,v 1.74 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Ignatios Souvatzis
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.73 2016/04/28 14:40:09 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arcsubr.c,v 1.74 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -505,7 +505,6 @@ arc_input(struct ifnet *ifp, struct mbuf
 	struct ifqueue *inq;
 	uint8_t atype;
 	int isr = 0;
-	int s;
 
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		m_freem(m);
@@ -568,22 +567,23 @@ arc_input(struct ifnet *ifp, struct mbuf
 		return;
 	}
 
-	s = splnet();
 	if (__predict_true(pktq)) {
 		if (__predict_false(!pktq_enqueue(pktq, m, 0))) {
 			m_freem(m);
 		}
-		splx(s);
 		return;
 	}
+
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
-	splx(s);
 }
 
 /*

Index: src/sys/net/if_atmsubr.c
diff -u src/sys/net/if_atmsubr.c:1.59 src/sys/net/if_atmsubr.c:1.60
--- src/sys/net/if_atmsubr.c:1.59	Fri Jun 10 13:27:15 2016
+++ src/sys/net/if_atmsubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*      $NetBSD: if_atmsubr.c,v 1.59 2016/06/10 13:27:15 ozaki-r Exp $       */
+/*      $NetBSD: if_atmsubr.c,v 1.60 2016/10/03 11:06:06 ozaki-r Exp $       */
 
 /*
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c,v 1.59 2016/06/10 13:27:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_atmsubr.c,v 1.60 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -216,15 +216,16 @@ atm_input(struct ifnet *ifp, struct atm_
 		inq = &natmintrq;
 		m_set_rcvif(m, rxhand); /* XXX: overload */
 
-		s = splnet();
+		IFQ_LOCK(inq);
 		if (IF_QFULL(inq)) {
 			IF_DROP(inq);
+			IFQ_UNLOCK(inq);
 			m_freem(m);
 		} else {
 			IF_ENQUEUE(inq, m);
+			IFQ_UNLOCK(inq);
 			schednetisr(isr);
 		}
-		splx(s);
 #else
 		printf("%s: NATM detected but not configured in kernel\n",
 		    __func__);

Index: src/sys/net/if_ecosubr.c
diff -u src/sys/net/if_ecosubr.c:1.48 src/sys/net/if_ecosubr.c:1.49
--- src/sys/net/if_ecosubr.c:1.48	Mon Jun 20 08:30:58 2016
+++ src/sys/net/if_ecosubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ecosubr.c,v 1.48 2016/06/20 08:30:58 knakahara Exp $	*/
+/*	$NetBSD: if_ecosubr.c,v 1.49 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 2001 Ben Harris
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.48 2016/06/20 08:30:58 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ecosubr.c,v 1.49 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -326,7 +326,6 @@ eco_input(struct ifnet *ifp, struct mbuf
 	struct ifqueue *inq;
 	struct eco_header ehdr, *eh;
 	int isr = 0;
-	int s;
 #ifdef INET
 	int i;
 	struct arphdr *ah;
@@ -449,15 +448,15 @@ eco_input(struct ifnet *ifp, struct mbuf
 		return;
 	}
 
-	s = splnet();
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
-		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
-	splx(s);
 }
 
 static void

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.227 src/sys/net/if_ethersubr.c:1.228
--- src/sys/net/if_ethersubr.c:1.227	Mon Aug  1 03:15:30 2016
+++ src/sys/net/if_ethersubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.227 2016/08/01 03:15:30 ozaki-r Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.227 2016/08/01 03:15:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -896,11 +896,15 @@ ether_input(struct ifnet *ifp, struct mb
 		m_freem(m);
 		return;
 	}
+
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
 }

Index: src/sys/net/if_fddisubr.c
diff -u src/sys/net/if_fddisubr.c:1.101 src/sys/net/if_fddisubr.c:1.102
--- src/sys/net/if_fddisubr.c:1.101	Mon Oct  3 07:13:29 2016
+++ src/sys/net/if_fddisubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_fddisubr.c,v 1.101 2016/10/03 07:13:29 ozaki-r Exp $	*/
+/*	$NetBSD: if_fddisubr.c,v 1.102 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_fddisubr.c,v 1.101 2016/10/03 07:13:29 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_fddisubr.c,v 1.102 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_gateway.h"
@@ -435,7 +435,6 @@ fddi_input(struct ifnet *ifp, struct mbu
 #if defined(NETATALK)
 	struct ifqueue *inq = NULL;
 	int isr = 0;
-	int s;
 #endif
 
 	struct llc *l;
@@ -587,15 +586,16 @@ fddi_input(struct ifnet *ifp, struct mbu
 		m_freem(m);
 		return;
 	}
-	s = splnet();
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
-	splx(s);
 #endif
 }
 

Index: src/sys/net/if_ieee1394subr.c
diff -u src/sys/net/if_ieee1394subr.c:1.57 src/sys/net/if_ieee1394subr.c:1.58
--- src/sys/net/if_ieee1394subr.c:1.57	Mon Aug 15 09:14:12 2016
+++ src/sys/net/if_ieee1394subr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ieee1394subr.c,v 1.57 2016/08/15 09:14:12 maxv Exp $	*/
+/*	$NetBSD: if_ieee1394subr.c,v 1.58 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ieee1394subr.c,v 1.57 2016/08/15 09:14:12 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ieee1394subr.c,v 1.58 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -318,7 +318,6 @@ ieee1394_input(struct ifnet *ifp, struct
 	pktqueue_t *pktq = NULL;
 	struct ifqueue *inq;
 	uint16_t etype;
-	int s;
 	struct ieee1394_unfraghdr *iuh;
 	int isr = 0;
 
@@ -395,15 +394,16 @@ ieee1394_input(struct ifnet *ifp, struct
 		return;
 	}
 
-	s = splnet();
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
-	splx(s);
 }
 
 static struct mbuf *

Index: src/sys/net/if_mpls.c
diff -u src/sys/net/if_mpls.c:1.27 src/sys/net/if_mpls.c:1.28
--- src/sys/net/if_mpls.c:1.27	Sun Aug  7 17:38:34 2016
+++ src/sys/net/if_mpls.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_mpls.c,v 1.27 2016/08/07 17:38:34 christos Exp $ */
+/*	$NetBSD: if_mpls.c,v 1.28 2016/10/03 11:06:06 ozaki-r Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_mpls.c,v 1.27 2016/08/07 17:38:34 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_mpls.c,v 1.28 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -205,13 +205,13 @@ mpls_input(struct ifnet *ifp, struct mbu
 void
 mplsintr(void)
 {
+
 	struct mbuf *m;
-	int s;
 
-	while (!IF_IS_EMPTY(&mplsintrq)) {
-		s = splnet();
+	for (;;) {
+		IFQ_LOCK(&mplsintrq);
 		IF_DEQUEUE(&mplsintrq, m);
-		splx(s);
+		IFQ_UNLOCK(&mplsintrq);
 
 		if (!m)
 			return;

Index: src/sys/net/if_pppoe.c
diff -u src/sys/net/if_pppoe.c:1.117 src/sys/net/if_pppoe.c:1.118
--- src/sys/net/if_pppoe.c:1.117	Thu Aug 11 15:16:07 2016
+++ src/sys/net/if_pppoe.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pppoe.c,v 1.117 2016/08/11 15:16:07 christos Exp $ */
+/* $NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $ */
 
 /*-
  * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.117 2016/08/11 15:16:07 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.118 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "pppoe.h"
@@ -231,6 +231,9 @@ pppoeinit(void)
 	pppoe_softintr = softint_establish(SOFTINT_NET, pppoe_softintr_handler,
 	    NULL);
 	sysctl_net_pppoe_setup(&pppoe_sysctl_clog);
+
+	IFQ_LOCK_INIT(&ppoediscinq);
+	IFQ_LOCK_INIT(&ppoeinq);
 }
 
 static int
@@ -394,24 +397,24 @@ static void
 pppoeintr(void)
 {
 	struct mbuf *m;
-	int s, disc_done, data_done;
+	int disc_done, data_done;
 
 	do {
 		disc_done = 0;
 		data_done = 0;
 		for (;;) {
-			s = splnet();
+			IFQ_LOCK(&ppoediscinq);
 			IF_DEQUEUE(&ppoediscinq, m);
-			splx(s);
+			IFQ_UNLOCK(&ppoediscinq);
 			if (m == NULL) break;
 			disc_done = 1;
 			pppoe_disc_input(m);
 		}
 
 		for (;;) {
-			s = splnet();
+			IFQ_LOCK(&ppoeinq);
 			IF_DEQUEUE(&ppoeinq, m);
-			splx(s);
+			IFQ_UNLOCK(&ppoeinq);
 			if (m == NULL) break;
 			data_done = 1;
 			pppoe_data_input(m);
@@ -1631,11 +1634,14 @@ pppoe_enqueue(struct ifqueue *inq, struc
 	}
 #endif
 
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		softint_schedule(pppoe_softintr);
 	}
 	return;

Index: src/sys/net/if_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.154 src/sys/net/if_spppsubr.c:1.155
--- src/sys/net/if_spppsubr.c:1.154	Thu Sep 29 15:04:17 2016
+++ src/sys/net/if_spppsubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.154 2016/09/29 15:04:17 roy Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.155 2016/10/03 11:06:06 ozaki-r Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.154 2016/09/29 15:04:17 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.155 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -478,7 +478,6 @@ sppp_input(struct ifnet *ifp, struct mbu
 	pktqueue_t *pktq = NULL;
 	struct ifqueue *inq = NULL;
 	uint16_t protocol;
-	int s;
 	struct sppp *sp = (struct sppp *)ifp;
 	int debug = ifp->if_flags & IFF_DEBUG;
 	int isr = 0;
@@ -642,19 +641,19 @@ queue_pkt:
 		return;
 	}
 
-	s = splnet();
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		/* Queue overflow. */
 		IF_DROP(inq);
-		splx(s);
+		IFQ_UNLOCK(inq);
 		if (debug)
 			log(LOG_DEBUG, "%s: protocol queue overflow\n",
 				ifp->if_xname);
 		goto drop;
 	}
 	IF_ENQUEUE(inq, m);
+	IFQ_UNLOCK(inq);
 	schednetisr(isr);
-	splx(s);
 }
 
 /*

Index: src/sys/net/if_tokensubr.c
diff -u src/sys/net/if_tokensubr.c:1.77 src/sys/net/if_tokensubr.c:1.78
--- src/sys/net/if_tokensubr.c:1.77	Mon Aug  1 03:15:30 2016
+++ src/sys/net/if_tokensubr.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_tokensubr.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $	*/
+/*	$NetBSD: if_tokensubr.c,v 1.78 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1982, 1989, 1993
@@ -92,7 +92,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.77 2016/08/01 03:15:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.78 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -394,7 +394,7 @@ token_input(struct ifnet *ifp, struct mb
 	struct ifqueue *inq = NULL;
 	struct llc *l;
 	struct token_header *trh;
-	int s, lan_hdr_len;
+	int lan_hdr_len;
 	int isr = 0;
 
 	if ((ifp->if_flags & IFF_UP) == 0) {
@@ -483,15 +483,16 @@ token_input(struct ifnet *ifp, struct mb
 		return;
 	}
 
-	s = splnet();
+	IFQ_LOCK(inq);
 	if (IF_QFULL(inq)) {
 		IF_DROP(inq);
+		IFQ_UNLOCK(inq);
 		m_freem(m);
 	} else {
 		IF_ENQUEUE(inq, m);
+		IFQ_UNLOCK(inq);
 		schednetisr(isr);
 	}
-	splx(s);
 }
 
 /*

Index: src/sys/net/rtsock.c
diff -u src/sys/net/rtsock.c:1.196 src/sys/net/rtsock.c:1.197
--- src/sys/net/rtsock.c:1.196	Wed Sep 21 10:50:22 2016
+++ src/sys/net/rtsock.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock.c,v 1.196 2016/09/21 10:50:22 roy Exp $	*/
+/*	$NetBSD: rtsock.c,v 1.197 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.196 2016/09/21 10:50:22 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.197 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -1806,14 +1806,13 @@ COMPATNAME(route_intr)(void *cookie)
 	struct sockproto proto = { .sp_family = PF_XROUTE, };
 	struct route_info * const ri = &COMPATNAME(route_info);
 	struct mbuf *m;
-	int s;
 
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
-	while (!IF_IS_EMPTY(&ri->ri_intrq)) {
-		s = splnet();
+	for (;;) {
+		IFQ_LOCK(&ri->ri_intrq);
 		IF_DEQUEUE(&ri->ri_intrq, m);
-		splx(s);
+		IFQ_UNLOCK(&ri->ri_intrq);
 		if (m == NULL)
 			break;
 		proto.sp_protocol = M_GETCTX(m, uintptr_t);
@@ -1830,20 +1829,24 @@ void
 COMPATNAME(route_enqueue)(struct mbuf *m, int family)
 {
 	struct route_info * const ri = &COMPATNAME(route_info);
-	int s, wasempty;
+	int wasempty;
 
-	s = splnet();
+	IFQ_LOCK(&ri->ri_intrq);
 	if (IF_QFULL(&ri->ri_intrq)) {
 		IF_DROP(&ri->ri_intrq);
+		IFQ_UNLOCK(&ri->ri_intrq);
 		m_freem(m);
 	} else {
 		wasempty = IF_IS_EMPTY(&ri->ri_intrq);
 		M_SETCTX(m, (uintptr_t)family);
 		IF_ENQUEUE(&ri->ri_intrq, m);
-		if (wasempty)
+		IFQ_UNLOCK(&ri->ri_intrq);
+		if (wasempty) {
+			kpreempt_disable();
 			softint_schedule(ri->ri_sih);
+			kpreempt_enable();
+		}
 	}
-	splx(s);
 }
 
 static void
@@ -1859,6 +1862,7 @@ COMPATNAME(route_init)(void)
 	ri->ri_intrq.ifq_maxlen = ri->ri_maxqlen;
 	ri->ri_sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
 	    COMPATNAME(route_intr), NULL);
+	IFQ_LOCK_INIT(&ri->ri_intrq);
 }
 
 /*

Index: src/sys/netatalk/ddp_input.c
diff -u src/sys/netatalk/ddp_input.c:1.27 src/sys/netatalk/ddp_input.c:1.28
--- src/sys/netatalk/ddp_input.c:1.27	Fri Jun 10 13:31:44 2016
+++ src/sys/netatalk/ddp_input.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ddp_input.c,v 1.27 2016/06/10 13:31:44 ozaki-r Exp $	 */
+/*	$NetBSD: ddp_input.c,v 1.28 2016/10/03 11:06:06 ozaki-r Exp $	 */
 
 /*
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.27 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.28 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -65,15 +65,12 @@ atintr(void)
 	struct ifnet   *ifp;
 	struct mbuf    *m;
 	struct at_ifaddr *aa;
-	int             s;
 
 	mutex_enter(softnet_lock);
 	for (;;) {
-		s = splnet();
-
+		IFQ_LOCK(&atintrq2);
 		IF_DEQUEUE(&atintrq2, m);
-
-		splx(s);
+		IFQ_UNLOCK(&atintrq2);
 
 		if (m == 0)	/* no more queued packets */
 			break;
@@ -92,11 +89,9 @@ atintr(void)
 	}
 
 	for (;;) {
-		s = splnet();
-
+		IFQ_LOCK(&atintrq1);
 		IF_DEQUEUE(&atintrq1, m);
-
-		splx(s);
+		IFQ_UNLOCK(&atintrq1);
 
 		if (m == 0)	/* no more queued packets */
 

Index: src/sys/netatalk/ddp_usrreq.c
diff -u src/sys/netatalk/ddp_usrreq.c:1.68 src/sys/netatalk/ddp_usrreq.c:1.69
--- src/sys/netatalk/ddp_usrreq.c:1.68	Sat May  2 17:18:03 2015
+++ src/sys/netatalk/ddp_usrreq.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: ddp_usrreq.c,v 1.68 2015/05/02 17:18:03 rtr Exp $	 */
+/*	$NetBSD: ddp_usrreq.c,v 1.69 2016/10/03 11:06:06 ozaki-r Exp $	 */
 
 /*
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.68 2015/05/02 17:18:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.69 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #include "opt_mbuftrace.h"
 
@@ -597,6 +597,8 @@ ddp_init(void)
 	TAILQ_INIT(&at_ifaddr);
 	atintrq1.ifq_maxlen = IFQ_MAXLEN;
 	atintrq2.ifq_maxlen = IFQ_MAXLEN;
+	IFQ_LOCK_INIT(&atintrq1);
+	IFQ_LOCK_INIT(&atintrq2);
 
 	MOWNER_ATTACH(&atalk_tx_mowner);
 	MOWNER_ATTACH(&atalk_rx_mowner);

Index: src/sys/netinet/if_arp.c
diff -u src/sys/netinet/if_arp.c:1.227 src/sys/netinet/if_arp.c:1.228
--- src/sys/netinet/if_arp.c:1.227	Sun Sep 18 02:17:43 2016
+++ src/sys/netinet/if_arp.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_arp.c,v 1.227 2016/09/18 02:17:43 christos Exp $	*/
+/*	$NetBSD: if_arp.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.227 2016/09/18 02:17:43 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.228 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -288,6 +288,7 @@ arp_init(void)
 
 	sysctl_net_inet_arp_setup(NULL);
 	arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
+	IFQ_LOCK_INIT(&arpintrq);
 }
 
 static void
@@ -914,13 +915,15 @@ arpintr(void)
 
 	mutex_enter(softnet_lock);
 	KERNEL_LOCK(1, NULL);
-	while (arpintrq.ifq_head) {
+	for (;;) {
 		struct ifnet *rcvif;
 
-		s = splnet();
+		IFQ_LOCK(&arpintrq);
 		IF_DEQUEUE(&arpintrq, m);
-		splx(s);
-		if (m == NULL || (m->m_flags & M_PKTHDR) == 0)
+		IFQ_UNLOCK(&arpintrq);
+		if (m == NULL)
+			goto out;
+		if ((m->m_flags & M_PKTHDR) == 0)
 			panic("arpintr");
 
 		MCLAIM(m, &arpdomain.dom_mowner);
@@ -962,6 +965,7 @@ badlen:
 		}
 		m_freem(m);
 	}
+out:
 	KERNEL_UNLOCK_ONE(NULL);
 	mutex_exit(softnet_lock);
 }

Index: src/sys/netmpls/mpls_proto.c
diff -u src/sys/netmpls/mpls_proto.c:1.29 src/sys/netmpls/mpls_proto.c:1.30
--- src/sys/netmpls/mpls_proto.c:1.29	Mon Aug 24 22:21:27 2015
+++ src/sys/netmpls/mpls_proto.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: mpls_proto.c,v 1.29 2015/08/24 22:21:27 pooka Exp $ */
+/*	$NetBSD: mpls_proto.c,v 1.30 2016/10/03 11:06:06 ozaki-r Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.29 2015/08/24 22:21:27 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.30 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -75,6 +75,7 @@ void mpls_init(void)
 #endif
 	memset(&mplsintrq, 0, sizeof(mplsintrq));
 	mplsintrq.ifq_maxlen = 256;
+	IFQ_LOCK_INIT(&mplsintrq);
 
 	sysctl_net_mpls_setup(NULL);
 }

Index: src/sys/netnatm/natm.c
diff -u src/sys/netnatm/natm.c:1.52 src/sys/netnatm/natm.c:1.53
--- src/sys/netnatm/natm.c:1.52	Fri Jun 10 13:31:44 2016
+++ src/sys/netnatm/natm.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: natm.c,v 1.52 2016/06/10 13:31:44 ozaki-r Exp $	*/
+/*	$NetBSD: natm.c,v 1.53 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.52 2016/06/10 13:31:44 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.53 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -444,9 +444,9 @@ natmintr(void)
 
   mutex_enter(softnet_lock);
 next:
-  s = splnet();
+  IFQ_LOCK(&natmintrq);
   IF_DEQUEUE(&natmintrq, m);
-  splx(s);
+  IFQ_UNLOCK(&natmintrq);
   if (m == NULL) {
     mutex_exit(softnet_lock);
     return;

Index: src/sys/netnatm/natm_proto.c
diff -u src/sys/netnatm/natm_proto.c:1.16 src/sys/netnatm/natm_proto.c:1.17
--- src/sys/netnatm/natm_proto.c:1.16	Wed Jan 20 21:44:00 2016
+++ src/sys/netnatm/natm_proto.c	Mon Oct  3 11:06:06 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: natm_proto.c,v 1.16 2016/01/20 21:44:00 riastradh Exp $	*/
+/*	$NetBSD: natm_proto.c,v 1.17 2016/10/03 11:06:06 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: natm_proto.c,v 1.16 2016/01/20 21:44:00 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: natm_proto.c,v 1.17 2016/10/03 11:06:06 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -117,4 +117,5 @@ u_int natm_sookbytes = 0;		/* # of bytes
 void natm_init(void)
 {
 	natmintrq.ifq_maxlen = natmqmaxlen;
+	IFQ_LOCK_INIT(&natmintrq);
 }

Reply via email to