Push kernel lock down to net_sysctl().
authormvs <mvs@openbsd.org>
Wed, 14 Aug 2024 17:52:47 +0000 (17:52 +0000)
committermvs <mvs@openbsd.org>
Wed, 14 Aug 2024 17:52:47 +0000 (17:52 +0000)
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
sys/kern/uipc_domain.c
sys/netmpls/mpls_raw.c

index 9c4a647..99c8181 100644 (file)
@@ -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:
index d96641a..1c31480 100644 (file)
@@ -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);
 }
 
index a297ead..dc7afc4 100644 (file)
@@ -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;
 }