Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Avoid storing a pointer of an interface in a mbuf
details: https://anonhg.NetBSD.org/src/rev/c1fa23a8b4ca
branches: trunk
changeset: 345839:c1fa23a8b4ca
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Fri Jun 10 13:31:43 2016 +0000
description:
Avoid storing a pointer of an interface in a mbuf
Having a pointer of an interface in a mbuf isn't safe if we remove big
kernel locks; an interface object (ifnet) can be destroyed anytime in any
packet processing and accessing such object via a pointer is racy. Instead
we have to get an object from the interface collection (ifindex2ifnet) via
an interface index (if_index) that is stored to a mbuf instead of an
pointer.
The change provides two APIs: m_{get,put}_rcvif_psref that use psref(9)
for sleep-able critical sections and m_{get,put}_rcvif that use
pserialize(9) for other critical sections. The change also adds another
API called m_get_rcvif_NOMPSAFE, that is NOT MP-safe and for transition
moratorium, i.e., it is intended to be used for places where are not
planned to be MP-ified soon.
The change adds some overhead due to psref to performance sensitive paths,
however the overhead is not serious, 2% down at worst.
Proposed on tech-kern and tech-net.
diffstat:
sys/altq/altq_cdnr.c | 6 +-
sys/dev/pci/if_lmc.c | 6 +-
sys/dist/pf/net/if_pfsync.c | 6 +-
sys/external/bsd/ipf/netinet/ip_compat.h | 5 +-
sys/kern/uipc_mbuf.c | 8 +-
sys/net/bpf.c | 12 ++--
sys/net/if.c | 26 ++++++++-
sys/net/if.h | 16 +++--
sys/net/if_bridge.c | 29 ++++++---
sys/net/if_mpls.c | 8 +-
sys/net/if_pppoe.c | 34 ++++++++---
sys/net/if_stf.c | 8 +-
sys/netatalk/ddp_input.c | 8 +-
sys/netinet/if_arp.c | 51 ++++++++++++------
sys/netinet/igmp.c | 26 +++++---
sys/netinet/in_gif.c | 13 +++-
sys/netinet/ip_carp.c | 34 ++++++-----
sys/netinet/ip_flow.c | 19 ++++--
sys/netinet/ip_icmp.c | 36 ++++++++----
sys/netinet/ip_input.c | 67 ++++++++++++++++-------
sys/netinet/sctp_input.c | 10 +-
sys/netinet/sctp_output.c | 21 +++----
sys/netinet/tcp_input.c | 35 ++++++++---
sys/netinet/udp_usrreq.c | 10 +-
sys/netinet6/icmp6.c | 66 +++++++++++++++++++----
sys/netinet6/in6_gif.c | 12 ++-
sys/netinet6/ip6_forward.c | 58 ++++++++++----------
sys/netinet6/ip6_input.c | 23 +++++---
sys/netinet6/ip6_mroute.c | 12 ++--
sys/netinet6/ip6_var.h | 4 +-
sys/netinet6/mld6.c | 19 +++--
sys/netinet6/nd6_nbr.c | 28 ++++++++-
sys/netinet6/nd6_rtr.c | 32 ++++++++--
sys/netinet6/raw_ip6.c | 43 +++++++++-----
sys/netinet6/sctp6_usrreq.c | 8 +-
sys/netinet6/udp6_output.c | 7 +-
sys/netinet6/udp6_usrreq.c | 6 +-
sys/netipsec/ipsec_input.c | 7 +-
sys/netipsec/key_debug.c | 6 +-
sys/netipsec/xform_ipip.c | 8 +-
sys/netmpls/mpls_ttl.c | 6 +-
sys/netnatm/natm.c | 6 +-
sys/sys/mbuf.h | 89 ++++++++++++++++++++++++++++---
43 files changed, 619 insertions(+), 315 deletions(-)
diffs (truncated from 3189 to 300 lines):
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/altq/altq_cdnr.c
--- a/sys/altq/altq_cdnr.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/altq/altq_cdnr.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: altq_cdnr.c,v 1.20 2011/11/19 22:51:18 tls Exp $ */
+/* $NetBSD: altq_cdnr.c,v 1.21 2016/06/10 13:31:43 ozaki-r Exp $ */
/* $KAME: altq_cdnr.c,v 1.15 2005/04/13 03:44:24 suz Exp $ */
/*
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.20 2011/11/19 22:51:18 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_cdnr.c,v 1.21 2016/06/10 13:31:43 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_altq.h"
@@ -139,7 +139,7 @@
struct cdnr_block *cb;
struct cdnr_pktinfo pktinfo;
- ifp = m->m_pkthdr.rcvif;
+ ifp = m_get_rcvif_NOMPSAFE(m);
if (!ALTQ_IS_CNDTNING(&ifp->if_snd))
/* traffic conditioner is not enabled on this interface */
return (1);
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/dev/pci/if_lmc.c
--- a/sys/dev/pci/if_lmc.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/dev/pci/if_lmc.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_lmc.c,v 1.60 2016/06/10 13:27:14 ozaki-r Exp $ */
+/* $NetBSD: if_lmc.c,v 1.61 2016/06/10 13:31:43 ozaki-r Exp $ */
/*-
* Copyright (c) 2002-2006 David Boggs. <boggs%boggs.palo-alto.ca.us@localhost>
@@ -74,7 +74,7 @@
*/
# include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_lmc.c,v 1.60 2016/06/10 13:27:14 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_lmc.c,v 1.61 2016/06/10 13:31:43 ozaki-r Exp $");
# include <sys/param.h> /* OS version */
# include "opt_inet.h" /* INET6, INET */
# include "opt_altq_enabled.h" /* ALTQ */
@@ -4279,7 +4279,7 @@
MGETHDR(new_mbuf, M_DONTWAIT, MT_DATA);
if (new_mbuf)
{
- m_set_rcvif(new_mbuf, first_mbuf->m_pkthdr.rcvif);
+ m_copy_rcvif(new_mbuf, first_mbuf);
new_mbuf->m_pkthdr.len = first_mbuf->m_pkthdr.len;
new_mbuf->m_len = first_mbuf->m_len;
memcpy(new_mbuf->m_data, first_mbuf->m_data,
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/dist/pf/net/if_pfsync.c
--- a/sys/dist/pf/net/if_pfsync.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/dist/pf/net/if_pfsync.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pfsync.c,v 1.13 2016/06/10 13:27:15 ozaki-r Exp $ */
+/* $NetBSD: if_pfsync.c,v 1.14 2016/06/10 13:31:44 ozaki-r Exp $ */
/* $OpenBSD: if_pfsync.c,v 1.83 2007/06/26 14:44:12 mcbride Exp $ */
/*
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.13 2016/06/10 13:27:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pfsync.c,v 1.14 2016/06/10 13:31:44 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -374,7 +374,7 @@
goto done;
/* verify that the packet came in on the right interface */
- if (sc->sc_sync_ifp != m->m_pkthdr.rcvif) {
+ if (sc->sc_sync_ifp->if_index != m->m_pkthdr.rcvif_index) {
PFSYNC_STATINC(PFSYNC_STAT_BADIF);
goto done;
}
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/external/bsd/ipf/netinet/ip_compat.h
--- a/sys/external/bsd/ipf/netinet/ip_compat.h Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/external/bsd/ipf/netinet/ip_compat.h Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ip_compat.h,v 1.9 2016/06/10 13:27:15 ozaki-r Exp $ */
+/* $NetBSD: ip_compat.h,v 1.10 2016/06/10 13:31:44 ozaki-r Exp $ */
/*
* Copyright (C) 2012 by Darren Reed.
@@ -1964,8 +1964,7 @@
if (_o->m_flags & M_PKTHDR) { \
(m)->m_pkthdr.len += \
_o->m_pkthdr.len; \
- m_set_rcvif((m), \
- _o->m_pkthdr.rcvif); \
+ m_copy_rcvif((m), _o); \
} \
} while (0)
# endif
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/kern/uipc_mbuf.c
--- a/sys/kern/uipc_mbuf.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/kern/uipc_mbuf.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_mbuf.c,v 1.166 2016/06/10 13:27:15 ozaki-r Exp $ */
+/* $NetBSD: uipc_mbuf.c,v 1.167 2016/06/10 13:31:44 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2001 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.166 2016/06/10 13:27:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_mbuf.c,v 1.167 2016/06/10 13:31:44 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_mbuftrace.h"
@@ -1171,7 +1171,7 @@
if (n == NULL)
return NULL;
MCLAIM(n, m0->m_owner);
- m_set_rcvif(n, m0->m_pkthdr.rcvif);
+ m_copy_rcvif(n, m0);
n->m_pkthdr.len = m0->m_pkthdr.len - len0;
len_save = m0->m_pkthdr.len;
m0->m_pkthdr.len = len0;
@@ -1783,7 +1783,7 @@
snprintb(buf, sizeof(buf), M_CSUM_BITS, m->m_pkthdr.csum_flags);
(*pr)(" pktlen=%d, rcvif=%p, csum_flags=0x%s, csum_data=0x%"
PRIx32 ", segsz=%u\n",
- m->m_pkthdr.len, m->m_pkthdr.rcvif,
+ m->m_pkthdr.len, m_get_rcvif_NOMPSAFE(m),
buf, m->m_pkthdr.csum_data, m->m_pkthdr.segsz);
}
if ((m->m_flags & M_EXT)) {
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/net/bpf.c
--- a/sys/net/bpf.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/net/bpf.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.c,v 1.197 2016/06/10 13:27:15 ozaki-r Exp $ */
+/* $NetBSD: bpf.c,v 1.198 2016/06/10 13:31:44 ozaki-r Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.197 2016/06/10 13:27:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.198 2016/06/10 13:31:44 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_bpf.h"
@@ -1469,7 +1469,7 @@
struct mbuf mb;
/* Skip outgoing duplicate packets. */
- if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
+ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif_index == 0) {
m->m_flags &= ~M_PROMISC;
return;
}
@@ -1486,7 +1486,7 @@
mb.m_data = data;
mb.m_len = dlen;
- bpf_deliver(bp, bpf_mcpy, &mb, pktlen, 0, m->m_pkthdr.rcvif != NULL);
+ bpf_deliver(bp, bpf_mcpy, &mb, pktlen, 0, m->m_pkthdr.rcvif_index != 0);
}
/*
@@ -1500,7 +1500,7 @@
void *marg;
/* Skip outgoing duplicate packets. */
- if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif == NULL) {
+ if ((m->m_flags & M_PROMISC) != 0 && m->m_pkthdr.rcvif_index == 0) {
m->m_flags &= ~M_PROMISC;
return;
}
@@ -1517,7 +1517,7 @@
buflen = 0;
}
- bpf_deliver(bp, cpfn, marg, pktlen, buflen, m->m_pkthdr.rcvif != NULL);
+ bpf_deliver(bp, cpfn, marg, pktlen, buflen, m->m_pkthdr.rcvif_index != 0);
}
/*
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/net/if.c
--- a/sys/net/if.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/net/if.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.c,v 1.337 2016/05/31 04:05:01 ozaki-r Exp $ */
+/* $NetBSD: if.c,v 1.338 2016/06/10 13:31:44 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.337 2016/05/31 04:05:01 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.338 2016/06/10 13:31:44 ozaki-r Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@@ -1245,7 +1245,7 @@
KASSERT((m->m_flags & M_PKTHDR) != 0);
next = m->m_nextpkt;
- if (m->m_pkthdr.rcvif != ifp) {
+ if (m->m_pkthdr.rcvif_index != ifp->if_index) {
prev = m;
continue;
}
@@ -2223,6 +2223,26 @@
return ifp;
}
+/*
+ * XXX unsafe
+ */
+void
+if_acquire_unsafe(struct ifnet *ifp, struct psref *psref)
+{
+
+ KASSERT(ifp->if_index != 0);
+ KASSERT(if_byindex(ifp->if_index) != NULL);
+ psref_acquire(psref, &ifp->if_psref, ifnet_psref_class);
+}
+
+bool
+if_held(struct ifnet *ifp)
+{
+
+ return psref_held(&ifp->if_psref, ifnet_psref_class);
+}
+
+
/* common */
int
ifioctl_common(struct ifnet *ifp, u_long cmd, void *data)
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/net/if.h
--- a/sys/net/if.h Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/net/if.h Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if.h,v 1.206 2016/05/16 01:16:24 ozaki-r Exp $ */
+/* $NetBSD: if.h,v 1.207 2016/06/10 13:31:44 ozaki-r Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -890,16 +890,20 @@
extern int (*ifioctl)(struct socket *, u_long, void *, struct lwp *);
int ifioctl_common(struct ifnet *, u_long, void *);
int ifpromisc(struct ifnet *, int);
+int if_addr_init(ifnet_t *, struct ifaddr *, bool);
+int if_do_dad(struct ifnet *);
+int if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
+int if_flags_set(struct ifnet *, const short);
+int if_clone_list(int, char *, int *);
+
struct ifnet *ifunit(const char *);
struct ifnet *if_get(const char *, struct psref *);
ifnet_t *if_byindex(u_int);
ifnet_t *if_get_byindex(u_int, struct psref *);
void if_put(const struct ifnet *, struct psref *);
-int if_addr_init(ifnet_t *, struct ifaddr *, bool);
-int if_do_dad(struct ifnet *);
-int if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
-int if_flags_set(struct ifnet *, const short);
-int if_clone_list(int, char *, int *);
+void if_acquire_unsafe(struct ifnet *, struct psref *);
+
+bool if_held(struct ifnet *);
void if_input(struct ifnet *, struct mbuf *);
diff -r 70107fcd7ea9 -r c1fa23a8b4ca sys/net/if_bridge.c
--- a/sys/net/if_bridge.c Fri Jun 10 13:27:10 2016 +0000
+++ b/sys/net/if_bridge.c Fri Jun 10 13:31:43 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_bridge.c,v 1.124 2016/06/10 13:27:16 ozaki-r Exp $ */
+/* $NetBSD: if_bridge.c,v 1.125 2016/06/10 13:31:44 ozaki-r Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.124 2016/06/10 13:27:16 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.125 2016/06/10 13:31:44 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_bridge_ipf.h"
@@ -1610,12 +1610,18 @@
struct ifnet *src_if, *dst_if;
struct ether_header *eh;
Home |
Main Index |
Thread Index |
Old Index