diff --git a/sys/dev/raid/mps/mps.c b/sys/dev/raid/mps/mps.c index 1111111..2222222 100644 --- a/sys/dev/raid/mps/mps.c +++ b/sys/dev/raid/mps/mps.c @@ -857,7 +857,10 @@ cm->cm_desc.Default.SMID = i; cm->cm_sc = sc; TAILQ_INIT(&cm->cm_chain_list); - callout_init_mp(&cm->cm_callout); + /* + * DF-3892: the timeout callbacks (mpssas_scsiio_timeout, + * mpssas_tm_timeout) assume mps_lock is held; tie the + * callout to the lock like mpr(4) does (mpr.c:1539). + */ + callout_init_lk(&cm->cm_callout, &sc->mps_lock); /* XXX Is a failure here a critical problem? */ if (bus_dmamap_create(sc->buffer_dmat, 0, &cm->cm_dmamap) == 0) diff --git a/sys/dev/raid/mps/mps_sas.c b/sys/dev/raid/mps/mps_sas.c index 1111111..3333333 100644 --- a/sys/dev/raid/mps/mps_sas.c +++ b/sys/dev/raid/mps/mps_sas.c @@ -1121,12 +1121,14 @@ mpssas_target_reset_complete(struct mps_softc *sc, struct mps_command *tm) static void mpssas_tm_timeout(void *data) { struct mps_command *tm = data; struct mps_softc *sc = tm->cm_sc; - mps_lock(sc); + /* DF-3892: cm_callout is now lock-tied (callout_init_lk), the + * callout subsystem already holds mps_lock; taking it again + * would self-deadlock. */ + KKASSERT(lockowned(&sc->mps_lock)); mpssas_log_command(tm, "task mgmt %p timed out\n", tm); mps_reinit(sc); - mps_unlock(sc); } static void mpssas_logical_unit_reset_complete(struct mps_softc *sc, struct mps_command *tm)