Not all interface ioctls need the kernel lock, but they all grab it. Here's a mechanical diff splitting the single lock/unlock around ifioctl() into individual lock/unlock dances inside ifioctl().
>From there we can unlock individual ioctls piece by piece. Survives regress on sparc64 and didn't blow up on my amd64 notebook yet. Feedback? Objection? OK? Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.665 diff -u -p -r1.665 if.c --- net/if.c 8 Sep 2022 10:22:06 -0000 1.665 +++ net/if.c 7 Nov 2022 15:13:01 -0000 @@ -1942,19 +1942,25 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCIFCREATE: if ((error = suser(p)) != 0) return (error); + KERNEL_LOCK(); error = if_clone_create(ifr->ifr_name, 0); + KERNEL_UNLOCK(); return (error); case SIOCIFDESTROY: if ((error = suser(p)) != 0) return (error); + KERNEL_LOCK(); error = if_clone_destroy(ifr->ifr_name); + KERNEL_UNLOCK(); return (error); case SIOCSIFGATTR: if ((error = suser(p)) != 0) return (error); + KERNEL_LOCK(); NET_LOCK(); error = if_setgroupattribs(data); NET_UNLOCK(); + KERNEL_UNLOCK(); return (error); case SIOCGIFCONF: case SIOCIFGCLONERS: @@ -1973,12 +1979,19 @@ ifioctl(struct socket *so, u_long cmd, c case SIOCGIFRDOMAIN: case SIOCGIFGROUP: case SIOCGIFLLPRIO: - return (ifioctl_get(cmd, data)); + KERNEL_LOCK(); + error = ifioctl_get(cmd, data); + KERNEL_UNLOCK(); + return (error); } + KERNEL_LOCK(); + ifp = if_unit(ifr->ifr_name); - if (ifp == NULL) + if (ifp == NULL) { + KERNEL_UNLOCK(); return (ENXIO); + } oif_flags = ifp->if_flags; oif_xflags = ifp->if_xflags; @@ -2396,6 +2409,8 @@ forceup: if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) getmicrotime(&ifp->if_lastchange); + + KERNEL_UNLOCK(); if_put(ifp);