Let's start to unlock (*pr_sysctl)() handlers. We have many of them, so
introduce temporary PR_MPSAFE flag to mark MP safe instead of pushing
kernel lock within handlers.

Unlock ip_sysctl(). Still take kernel lock within IPCTL_MRTSTATS case.
It looks like `mrtstat' protection is inconsistent, so keep locking as
it was. Since `mrtstat' are counters, it make sense to rework them into
per CPU counters with separate diffs.

mrt_sysctl_mfc() and mrt_sysctl_vif() do read-only access so, netlock
could be replaced by shared netlock and pushed within, but also with
separate diffs.

ok?

This is not related to (*pr_sysctl)() unlocking, but if there is no
objections, I want to replace tabs by space after #define in PR_* flags
definitions.

Index: sys/kern/uipc_domain.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_domain.c,v
retrieving revision 1.61
diff -u -p -r1.61 uipc_domain.c
--- sys/kern/uipc_domain.c      4 May 2023 09:40:36 -0000       1.61
+++ sys/kern/uipc_domain.c      16 May 2023 10:50:53 -0000
@@ -244,10 +244,12 @@ net_sysctl(int *name, u_int namelen, voi
        protocol = name[1];
        for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
                if (pr->pr_protocol == protocol && pr->pr_sysctl) {
-                       KERNEL_LOCK();
+                       if ((pr->pr_flags & PR_MPSAFE) == 0)
+                               KERNEL_LOCK();
                        error = (*pr->pr_sysctl)(name + 2, namelen - 2,
                            oldp, oldlenp, newp, newlen);
-                       KERNEL_UNLOCK();
+                       if ((pr->pr_flags & PR_MPSAFE) == 0)
+                               KERNEL_UNLOCK();
                        return (error);
                }
        return (ENOPROTOOPT);
Index: sys/netinet/in_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_proto.c,v
retrieving revision 1.99
diff -u -p -r1.99 in_proto.c
--- sys/netinet/in_proto.c      15 Aug 2022 09:11:38 -0000      1.99
+++ sys/netinet/in_proto.c      16 May 2023 10:50:53 -0000
@@ -177,6 +177,7 @@ u_char ip_protox[IPPROTO_MAX];
 const struct protosw inetsw[] = {
 {
   .pr_domain   = &inetdomain,
+  .pr_flags    = PR_MPSAFE,
   .pr_init     = ip_init,
   .pr_slowtimo = ip_slowtimo,
   .pr_sysctl   = ip_sysctl
Index: sys/netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.383
diff -u -p -r1.383 ip_input.c
--- sys/netinet/ip_input.c      5 Apr 2023 21:51:47 -0000       1.383
+++ sys/netinet/ip_input.c      16 May 2023 10:50:53 -0000
@@ -1704,8 +1704,11 @@ ip_sysctl(int *name, u_int namelen, void
                return (ip_sysctl_ipstat(oldp, oldlenp, newp));
 #ifdef MROUTING
        case IPCTL_MRTSTATS:
-               return (sysctl_rdstruct(oldp, oldlenp, newp,
-                   &mrtstat, sizeof(mrtstat)));
+               KERNEL_LOCK();
+               error = sysctl_rdstruct(oldp, oldlenp, newp,
+                   &mrtstat, sizeof(mrtstat));
+               KERNEL_UNLOCK();
+               return (error);
        case IPCTL_MRTMFC:
                if (newp)
                        return (EPERM);
Index: sys/sys/protosw.h
===================================================================
RCS file: /cvs/src/sys/sys/protosw.h,v
retrieving revision 1.59
diff -u -p -r1.59 protosw.h
--- sys/sys/protosw.h   26 Nov 2022 17:52:35 -0000      1.59
+++ sys/sys/protosw.h   16 May 2023 10:50:53 -0000
@@ -131,6 +131,8 @@ struct protosw {
 #define        PR_ABRTACPTDIS  0x20            /* abort on accept(2) to 
disconnected
                                           socket */
 #define        PR_SPLICE       0x40            /* socket splicing is possible 
*/
+#define        PR_MPSAFE       0x80            /* (*pr_sysctl)() doesn't 
require
+                                          kernel lock */
 
 /*
  * The arguments to usrreq are:

Reply via email to