From 7af15f03dac24b2518f4ed336f8e8cd00d70cef5 Mon Sep 17 00:00:00 2001 From: mvs Date: Wed, 14 Aug 2024 17:52:47 +0000 Subject: [PATCH] Push kernel lock down to net_sysctl(). All except PF_MPLS paths are mp-safe: - net_link_sysctl() and following net_ifiq_sysctl() only return EOPNOTSUPP; - uipc_sysctl() - mp-safe atomic access to integers; - bpf_sysctl() - mp-safe atomic access to integers; - pflow_sysctl() - returns statistics from per-CPU counters; - pipex_sysctl() - mp-safe atomic access to integer; Push kernel lock down to mpls_sysctl(). sysctl_int_bounded() do copying with local variable, so context switch is safe. No need to wire memory or take `sysctl_lock' rwlock(9). Keep protocols locked as they was include pages wiring. Copying will not sleep - no network slowdown while doing it with net lock held. ok bluhm --- sys/kern/kern_sysctl.c | 3 ++- sys/kern/uipc_domain.c | 17 +++++++++++++---- sys/netmpls/mpls_raw.c | 10 ++++++++-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 9c4a64744ab..99c8181f720 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.438 2024/08/14 13:54:08 mvs Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.439 2024/08/14 17:52:47 mvs Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -252,6 +252,7 @@ sys_sysctl(struct proc *p, void *v, register_t *retval) fn = uvm_sysctl; break; case CTL_NET: + dolock = 0; fn = net_sysctl; break; case CTL_FS: diff --git a/sys/kern/uipc_domain.c b/sys/kern/uipc_domain.c index d96641af6be..1c314806bb6 100644 --- a/sys/kern/uipc_domain.c +++ b/sys/kern/uipc_domain.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_domain.c,v 1.66 2024/08/12 11:25:27 bluhm Exp $ */ +/* $OpenBSD: uipc_domain.c,v 1.67 2024/08/14 17:52:47 mvs Exp $ */ /* $NetBSD: uipc_domain.c,v 1.14 1996/02/09 19:00:44 christos Exp $ */ /* @@ -236,9 +236,18 @@ net_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (EISDIR); /* overloaded */ protocol = name[1]; for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) - if (pr->pr_protocol == protocol && pr->pr_sysctl) - return ((*pr->pr_sysctl)(name + 2, namelen - 2, - oldp, oldlenp, newp, newlen)); + if (pr->pr_protocol == protocol && pr->pr_sysctl) { + size_t savelen = *oldlenp; + int error; + + if ((error = sysctl_vslock(oldp, savelen))) + return (error); + error = (*pr->pr_sysctl)(name + 2, namelen - 2, + oldp, oldlenp, newp, newlen); + sysctl_vsunlock(oldp, savelen); + + return (error); + } return (ENOPROTOOPT); } diff --git a/sys/netmpls/mpls_raw.c b/sys/netmpls/mpls_raw.c index a297ead23c6..dc7afc45e94 100644 --- a/sys/netmpls/mpls_raw.c +++ b/sys/netmpls/mpls_raw.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_raw.c,v 1.20 2024/04/29 00:29:48 jsg Exp $ */ +/* $OpenBSD: mpls_raw.c,v 1.21 2024/08/14 17:52:47 mvs Exp $ */ /* * Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project. @@ -58,6 +58,12 @@ int mpls_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - return sysctl_bounded_arr(mplsctl_vars, nitems(mplsctl_vars), + int error; + + KERNEL_LOCK(); + error = sysctl_bounded_arr(mplsctl_vars, nitems(mplsctl_vars), name, namelen, oldp, oldlenp, newp, newlen); + KERNEL_UNLOCK(); + + return error; } -- 2.20.1