diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-10-09 08:35:39 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-10-09 08:35:39 +0000 |
commit | 1a50b2beba0c4dbdca6896cfada79d51fe09f032 (patch) | |
tree | b711148996636dd12aa605080d14f8c65ddac843 /sys/netinet6 | |
parent | 6cd55fecbaf42a75cd6f0827f8989adb17a0bc96 (diff) |
Reduces the scope of the NET_LOCK() in sysctl(2) path.
Exposes per-CPU counters to real parrallelism.
ok visa@, bluhm@, jca@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 14 | ||||
-rw-r--r-- | sys/netinet6/ip6_divert.c | 26 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 33 |
3 files changed, 52 insertions, 21 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 9602b127d07..3becc223313 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.216 2017/09/01 15:05:31 mpi Exp $ */ +/* $OpenBSD: icmp6.c,v 1.217 2017/10/09 08:35:38 mpi Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1887,6 +1887,8 @@ int icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return ENOTDIR; @@ -1896,9 +1898,13 @@ icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case ICMPV6CTL_STATS: return icmp6_sysctl_icmp6stat(oldp, oldlenp, newp); default: - if (name[0] < ICMPV6CTL_MAXID) - return (sysctl_int_arr(icmpv6ctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < ICMPV6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(icmpv6ctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return ENOPROTOOPT; } /* NOTREACHED */ diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c index 011514a521e..1f20dc64d83 100644 --- a/sys/netinet6/ip6_divert.c +++ b/sys/netinet6/ip6_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.c,v 1.53 2017/10/06 22:08:30 bluhm Exp $ */ +/* $OpenBSD: ip6_divert.c,v 1.54 2017/10/09 08:35:38 mpi Exp $ */ /* * Copyright (c) 2009 Michele Marchetto <michele@openbsd.org> @@ -363,23 +363,35 @@ int divert6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { + int error; + /* All sysctl names at this level are terminal. */ if (namelen != 1) return (ENOTDIR); switch (name[0]) { case DIVERT6CTL_SENDSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert6_sendspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert6_sendspace); + NET_UNLOCK(); + return (error); case DIVERT6CTL_RECVSPACE: - return (sysctl_int(oldp, oldlenp, newp, newlen, - &divert6_recvspace)); + NET_LOCK(); + error = sysctl_int(oldp, oldlenp, newp, newlen, + &divert6_recvspace); + NET_UNLOCK(); + return (error); case DIVERT6CTL_STATS: return (divert6_sysctl_div6stat(oldp, oldlenp, newp)); default: - if (name[0] < DIVERT6CTL_MAXID) - return sysctl_int_arr(divert6ctl_vars, name, namelen, + if (name[0] < DIVERT6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(divert6ctl_vars, name, namelen, oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (ENOPROTOOPT); } diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index ade41a8a03b..4e588d83394 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.202 2017/08/22 15:02:34 mpi Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.203 2017/10/09 08:35:38 mpi Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -1383,8 +1383,6 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, #endif int error; - NET_ASSERT_LOCKED(); - /* Almost all sysctl names at this level are terminal. */ if (namelen != 1 && name[0] != IPV6CTL_IFQUEUE) return (ENOTDIR); @@ -1398,18 +1396,27 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IPV6CTL_MRTSTATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &mrt6stat, sizeof(mrt6stat))); + NET_LOCK(); + error = sysctl_struct(oldp, oldlenp, newp, newlen, + &mrt6stat, sizeof(mrt6stat)); + NET_UNLOCK(); + return (error); case IPV6CTL_MRTPROTO: return sysctl_rdint(oldp, oldlenp, newp, ip6_mrtproto); case IPV6CTL_MRTMIF: if (newp) return (EPERM); - return mrt6_sysctl_mif(oldp, oldlenp); + NET_LOCK(); + error = mrt6_sysctl_mif(oldp, oldlenp); + NET_UNLOCK(); + return (error); case IPV6CTL_MRTMFC: if (newp) return (EPERM); - return mrt6_sysctl_mfc(oldp, oldlenp); + NET_LOCK(); + error = mrt6_sysctl_mfc(oldp, oldlenp); + NET_UNLOCK(); + return (error); #else case IPV6CTL_MRTSTATS: case IPV6CTL_MRTPROTO: @@ -1418,19 +1425,25 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, return (EOPNOTSUPP); #endif case IPV6CTL_MTUDISCTIMEOUT: + NET_LOCK(); error = sysctl_int(oldp, oldlenp, newp, newlen, &ip6_mtudisc_timeout); if (icmp6_mtudisc_timeout_q != NULL) rt_timer_queue_change(icmp6_mtudisc_timeout_q, ip6_mtudisc_timeout); + NET_UNLOCK(); return (error); case IPV6CTL_IFQUEUE: return (sysctl_niq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &ip6intrq)); default: - if (name[0] < IPV6CTL_MAXID) - return (sysctl_int_arr(ipv6ctl_vars, name, namelen, - oldp, oldlenp, newp, newlen)); + if (name[0] < IPV6CTL_MAXID) { + NET_LOCK(); + error = sysctl_int_arr(ipv6ctl_vars, name, namelen, + oldp, oldlenp, newp, newlen); + NET_UNLOCK(); + return (error); + } return (EOPNOTSUPP); } /* NOTREACHED */ |