DF-3733 / fix.diff
--- a/sys/dev/raid/ciss/ciss.c +++ b/sys/dev/raid/ciss/ciss.c @@ -425,9 +425,13 @@ sc = device_get_softc(dev); sc->ciss_dev = dev; lockinit(&sc->ciss_lock, "cissmtx", 0, LK_CANRECURSE); - callout_init_mp(&sc->ciss_periodic); + /* Serialize the periodic callout with ciss_lock: with _lk the callout + * subsystem holds ciss_lock while running/stopping/re-arming the + * callout, so callout_stop() in ciss_free() cannot race the re-arm + * at the tail of ciss_periodic(). */ + callout_init_lk(&sc->ciss_periodic, &sc->ciss_lock); /* * Do PCI-specific init. */ @@ -482,9 +482,11 @@ /* * Start the heartbeat routine and event chain. */ - ciss_periodic(sc); + lockmgr(&sc->ciss_lock, LK_EXCLUSIVE); + ciss_periodic(sc); + lockmgr(&sc->ciss_lock, LK_RELEASE); /* * Create the control device. */ @@ -3379,10 +3379,9 @@ struct ciss_request *cr = NULL; struct ciss_command *cc = NULL; int error = 0; - lockmgr(&sc->ciss_lock, LK_EXCLUSIVE); - debug_called(1); + debug_called(1); /* * Check the adapter heartbeat. */ @@ -3392,10 +3392,9 @@ sc->ciss_heartbeat, sc->ciss_heart_attack); if (sc->ciss_heart_attack == 3) { ciss_printf(sc, "ADAPTER HEARTBEAT FAILED\n"); ciss_disable_adapter(sc); - lockmgr(&sc->ciss_lock, LK_RELEASE); - return; + return; } } else { sc->ciss_heartbeat = sc->ciss_cfg->heartbeat; sc->ciss_heart_attack = 0; @@ -3427,9 +3427,8 @@ if (!(sc->ciss_flags & CISS_FLAG_NOTIFY_OK)) { debug(0, "(re)starting Event Notify chain"); ciss_notify_event(sc); } - lockmgr(&sc->ciss_lock, LK_RELEASE); /* * Reschedule. */ |