DF-4773 / fix.diff
--- a/sys/dev/apple/smc/smc.c +++ b/sys/dev/apple/smc/smc.c @@ -503,6 +503,24 @@ apple_smc_detach(device_t dev) { struct apple_smc_softc *sc = device_get_softc(dev); + struct sysctl_ctx_list *sysctlctx; + + /* + * Tear down the sysctl tree BEFORE freeing anything its handlers + * dereference (sensor key arrays in smc_sysctl.c:179/219/224/229/234, + * the softc, the backend resources). The device sysctl context is + * otherwise only destroyed by newbus at device_delete time -- long + * after this function returns -- leaving every registered oid + * pointing at freed state for the whole detach..delete window. + * + * sysctl_ctx_free() on an already-drained context is a no-op, so + * the later device_sysctl_fini() call stays harmless. This must + * run in detach context (no sysctl lock held); a handler-side + * removal would self-deadlock on the sysctllock. + */ + sysctlctx = device_get_sysctl_ctx(dev); + if (sysctlctx != NULL) + sysctl_ctx_free(sysctlctx); apple_smc_free_sensors(sc->sc_temp_sensors, sc->sc_temp_count); apple_smc_free_sensors(sc->sc_dts_sensors, sc->sc_dts_count); |