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);
}