On Mon, May 25, 2026 at 04:45:26PM +0200, [email protected] wrote:
> >Synopsis: <Kernel panic at shutdoen/reboot when rad is enabled>
> >Category:
> >Environment:
> System : OpenBSD 7.9
> Details : OpenBSD 7.9 (GENERIC.MP) #222: Wed May 6 18:07:56 MDT
> 2026
>
> [email protected]:/usr/src/sys/arch/arm64/compile/GENERIC.MP
>
> Architecture: OpenBSD.arm64
> Machine : arm64
> >Description:
> When rad is enabled, the system panics at shutdoen/reboot, no orderly
> reboot possible
> >How-To-Repeat:
> rcctl enable rad
> rcctl start rad
> shutdowen -r now
> ... panic
> ... reboot
> rcctl disable rad
> rcctl stop rad
> ... panic
> ... reboot
> rcctl check rad
> rad (failed)
> shutdown -r now
> ... ok
> >Fix:
> disable rad
>
Hello,
I have no cad(4) device and I have no ability to compile this diff, so
I'm sending it offlist. Does it help?
Index: sys/dev/fdt/if_cad.c
===================================================================
RCS file: /cvs/src/sys/dev/fdt/if_cad.c,v
retrieving revision 1.16
diff -u -p -r1.16 if_cad.c
--- sys/dev/fdt/if_cad.c 17 Sep 2025 09:17:12 -0000 1.16
+++ sys/dev/fdt/if_cad.c 1 Jun 2026 06:33:49 -0000
@@ -589,21 +589,33 @@ cad_ioctl(struct ifnet *ifp, u_long cmd,
{
struct cad_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *)data;
- int error = 0, netlock_held = 1;
+ int error = 0, netlock_status;
int s;
- switch (cmd) {
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- case SIOCGIFSFFPAGE:
- netlock_held = 0;
+ netlock_status = rw_status(&netlock);
+ case RW_WRITE:
+ NET_UNLOCK();
+ break;
+ case RW_READ:
+ switch (cmd) {
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ /*
+ * We are called from sockets layer with socket
+ * lock and shared netlock held
+ */
+ NET_UNLOCK_SHARED();
+ break;
+ default:
+ /* The shared netlock was taken by another thread */
+ netlock_status = 0;
+ break;
+ }
break;
}
- if (netlock_held)
- NET_UNLOCK();
rw_enter_write(&sc->sc_cfg_lock);
- if (netlock_held)
+ if (netlock_status)
NET_LOCK();
s = splnet();
@@ -647,6 +659,15 @@ cad_ioctl(struct ifnet *ifp, u_long cmd,
}
splx(s);
+ switch (netlock_status) {
+ case RW_READ:
+ NET_UNLOCK();
+ NET_LOCK_SHARED();
+ break;
+ case RW_WRITE:
+ /* Exclusive netlock is already held */
+ break;
+ }
rw_exit_write(&sc->sc_cfg_lock);
return error;