DF-4986 / fix.diff
--- a/sys/dev/raid/mfi/mfi_pci.c +++ b/sys/dev/raid/mfi/mfi_pci.c @@ -226,10 +226,17 @@ mfi_pci_attach(device_t dev) u_int irq_flags; sc = device_get_softc(dev); bzero(sc, sizeof(*sc)); sc->mfi_dev = dev; + + /* + * Initialize the watchdog callout before anything can fail: + * every failure unwind below (including the DMA-tag failure that + * runs before mfi_attach()) goes through mfi_free(), which does + * callout_terminate(&sc->mfi_watchdog_callout). Terminating a + * never-initialized (bzero'd) callout trips + * KKASSERT(cc->flags & CALLOUT_DID_INIT) in kern_timeout.c and + * panics INVARIANTS kernels (stock X86_64_GENERIC). + */ + callout_init_mp(&sc->mfi_watchdog_callout); + m = mfi_find_ident(dev); sc->mfi_flags = m->flags; /* Verify that the adapter can be set up in PCI space */ --- a/sys/dev/raid/mfi/mfi.c +++ b/sys/dev/raid/mfi/mfi.c @@ -738,8 +738,7 @@ mfi_attach(struct mfi_softc *sc) bus_generic_attach(sc->mfi_dev); /* Start the timeout watchdog */ - callout_init_mp(&sc->mfi_watchdog_callout); - callout_reset(&sc->mfi_watchdog_callout, mfi_cmd_timeout * hz, + callout_reset(&sc->mfi_watchdog_callout, mfi_cmd_timeout * hz, mfi_timeout, sc); return (0); |