One of the last things the system does before it tries to mount root is
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Feb 2005 02:57:20 +0000 (02:57 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Feb 2005 02:57:20 +0000 (02:57 +0000)
wait for interrupt-driven configuration hooks to finish.  This is one of
the common places where the system locks up due to e.g. blown interrupt
routing.

Wait up to 60 seconds for interrupt driven hooks to complete.  Generate
a warning every 10 seconds listing the hooks that have not yet completed.
Name all the hook structures to make the listing meaningful.  After 60
seconds, give up and continue booting.  The system might actually
be useable enough to aid in debugging depending on which device failed.

12 files changed:
sys/bus/cam/cam_xpt.c
sys/dev/disk/ata/ata-all.c
sys/dev/disk/isp/isp_freebsd.c
sys/dev/raid/aac/aac.c
sys/dev/raid/amr/amr.c
sys/dev/raid/ips/ips_pci.c
sys/dev/raid/pst/pst-iop.c
sys/dev/raid/twa/twa_freebsd.c
sys/dev/raid/twe/twe_freebsd.c
sys/dev/sound/pci/ich.c
sys/kern/subr_autoconf.c
sys/sys/kernel.h

index 1dab104..19d1291 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_xpt.c,v 1.80.2.18 2002/12/09 17:31:55 gibbs Exp $
- * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.20 2005/02/01 22:41:19 dillon Exp $
+ * $DragonFly: src/sys/bus/cam/cam_xpt.c,v 1.21 2005/02/04 02:55:40 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1365,6 +1365,7 @@ xpt_init(dummy)
        xpt_config_hook = malloc(sizeof(struct intr_config_hook),
                                  M_TEMP, M_INTWAIT | M_ZERO);
        xpt_config_hook->ich_func = xpt_config;
+       xpt_config_hook->ich_desc = "xpt";
        if (config_intrhook_establish(xpt_config_hook) != 0) {
                free (xpt_config_hook, M_TEMP);
                printf("xpt_init: config_intrhook_establish failed "
index 9bcb7ee..b724927 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ata/ata-all.c,v 1.50.2.45 2003/03/12 14:47:12 sos Exp $
- * $DragonFly: src/sys/dev/disk/ata/ata-all.c,v 1.21 2004/08/17 20:59:39 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/ata/ata-all.c,v 1.22 2005/02/04 02:55:41 dillon Exp $
  */
 
 #include "opt_ata.h"
@@ -1596,6 +1596,7 @@ ata_init(void)
                                      M_TEMP, M_WAITOK | M_ZERO);
 
     ata_delayed_attach->ich_func = (void*)ata_boot_attach;
+    ata_delayed_attach->ich_desc = "ata";
     if (config_intrhook_establish(ata_delayed_attach) != 0) {
        printf("ata: config_intrhook_establish failed\n");
        free(ata_delayed_attach, M_TEMP);
index 10dd467..8e47bbe 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/dev/isp/isp_freebsd.c,v 1.32.2.20 2002/10/11 18:49:25 mjacob Exp $ */
-/* $DragonFly: src/sys/dev/disk/isp/isp_freebsd.c,v 1.11 2004/09/17 03:39:39 joerg Exp $ */
+/* $DragonFly: src/sys/dev/disk/isp/isp_freebsd.c,v 1.12 2005/02/04 02:55:43 dillon Exp $ */
 /*
  * Platform (FreeBSD) dependent common attachment code for Qlogic adapters.
  *
@@ -105,6 +105,7 @@ isp_attach(struct ispsoftc *isp)
 
        isp->isp_osinfo.ehook.ich_func = isp_intr_enable;
        isp->isp_osinfo.ehook.ich_arg = isp;
+       isp->isp_osinfo.ehook.ich_desc = "isp";
        ISPLOCK_2_CAMLOCK(isp);
        if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) {
                cam_sim_free(sim);
index 4bfacb1..91c33a7 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/dev/aac/aac.c,v 1.9.2.14 2003/04/08 13:22:08 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac.c,v 1.16 2004/09/15 16:23:51 joerg Exp $
+ *     $DragonFly: src/sys/dev/raid/aac/aac.c,v 1.17 2005/02/04 02:55:44 dillon Exp $
  */
 
 /*
@@ -287,6 +287,7 @@ aac_attach(struct aac_softc *sc)
 
        sc->aac_ich.ich_func = aac_startup;
        sc->aac_ich.ich_arg = sc;
+       sc->aac_ich.ich_desc = "aac";
        if (config_intrhook_establish(&sc->aac_ich) != 0) {
                device_printf(sc->aac_dev,
                              "can't establish configuration hook\n");
index d5b419a..c2d7e86 100644 (file)
@@ -53,7 +53,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/dev/amr/amr.c,v 1.7.2.13 2003/01/15 13:41:18 emoore Exp $
- *     $DragonFly: src/sys/dev/raid/amr/amr.c,v 1.13 2004/09/15 16:25:12 joerg Exp $
+ *     $DragonFly: src/sys/dev/raid/amr/amr.c,v 1.14 2005/02/04 02:55:46 dillon Exp $
  */
 
 /*
@@ -267,6 +267,7 @@ amr_attach(struct amr_softc *sc)
     bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
     sc->amr_ich.ich_func = amr_startup;
     sc->amr_ich.ich_arg = sc;
+    sc->amr_ich.ich_desc = "amr";
     if (config_intrhook_establish(&sc->amr_ich) != 0) {
        device_printf(sc->amr_dev, "can't establish configuration hook\n");
        return(ENOMEM);
index 0b4ba2f..73030df 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ips/ips_pci.c,v 1.10 2004/03/19 17:36:47 scottl Exp $
- * $DragonFly: src/sys/dev/raid/ips/ips_pci.c,v 1.9 2004/12/10 04:09:46 y0netan1 Exp $
+ * $DragonFly: src/sys/dev/raid/ips/ips_pci.c,v 1.10 2005/02/04 02:55:48 dillon Exp $
  */
 
 #include <dev/raid/ips/ips.h>
@@ -147,6 +147,7 @@ ips_pci_attach(device_t dev)
        }
        sc->ips_ich.ich_func = ips_intrhook;
        sc->ips_ich.ich_arg = sc;
+       sc->ips_ich.ich_arg = "ips";
        if (config_intrhook_establish(&sc->ips_ich) != 0) {
                printf("IPS can't establish configuration hook\n");
                goto error;
index e78c791..09c29c8 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/pst/pst-iop.c,v 1.2.2.1 2002/08/18 12:32:36 sos Exp $
- * $DragonFly: src/sys/dev/raid/pst/pst-iop.c,v 1.4 2004/06/21 15:39:31 dillon Exp $
+ * $DragonFly: src/sys/dev/raid/pst/pst-iop.c,v 1.5 2005/02/04 02:55:48 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -81,6 +81,7 @@ iop_init(struct iop_softc *sc)
                                   M_PSTIOP, M_INTWAIT | M_ZERO);
     sc->iop_delayed_attach->ich_func = (void *)iop_attach;
     sc->iop_delayed_attach->ich_arg = (void *)sc;
+    sc->iop_delayed_attach->ich_desc = "pst";
     if (config_intrhook_establish(sc->iop_delayed_attach)) {
        printf("pstiop: config_intrhook_establish failed\n");
        free(sc->iop_delayed_attach, M_PSTIOP);
index ae0a681..581ce6a 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD$
- * $DragonFly: src/sys/dev/raid/twa/twa_freebsd.c,v 1.4 2004/06/25 03:37:03 hmp Exp $
+ * $DragonFly: src/sys/dev/raid/twa/twa_freebsd.c,v 1.5 2005/02/04 02:55:48 dillon Exp $
  */
 
 /*
@@ -313,6 +313,7 @@ twa_attach(device_t dev)
         */
        sc->twa_ich.ich_func = twa_intrhook;
        sc->twa_ich.ich_arg = sc;
+       sc->twa_ich.ich_desc = "twa";
        if (config_intrhook_establish(&sc->twa_ich) != 0) {
                twa_printf(sc, "Can't establish configuration hook.\n");
                twa_free(sc);
index 1baeff5..43af346 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/twe/twe_freebsd.c,v 1.2.2.5 2002/03/07 09:57:02 msmith Exp $
- * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.11 2004/06/21 15:35:41 dillon Exp $
+ * $DragonFly: src/sys/dev/raid/twe/twe_freebsd.c,v 1.12 2005/02/04 02:55:48 dillon Exp $
  */
 
 /*
@@ -325,6 +325,7 @@ twe_attach(device_t dev)
      */
     sc->twe_ich.ich_func = twe_intrhook;
     sc->twe_ich.ich_arg = sc;
+    sc->twe_ich.ich_desc = "twe";
     if (config_intrhook_establish(&sc->twe_ich) != 0) {
        twe_printf(sc, "can't establish configuration hook\n");
        twe_free(sc);
index e12d103..e480208 100644 (file)
@@ -25,7 +25,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/sound/pci/ich.c,v 1.3.2.12 2003/01/20 03:59:42 orion Exp $
- * $DragonFly: src/sys/dev/sound/pci/ich.c,v 1.6 2004/04/08 15:16:50 joerg Exp $
+ * $DragonFly: src/sys/dev/sound/pci/ich.c,v 1.7 2005/02/04 02:57:20 dillon Exp $
  */
 
 #include <dev/sound/pcm/sound.h>
@@ -35,7 +35,7 @@
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
-SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/ich.c,v 1.6 2004/04/08 15:16:50 joerg Exp $");
+SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/ich.c,v 1.7 2005/02/04 02:57:20 dillon Exp $");
 
 /* -------------------------------------------------------------------- */
 
@@ -765,6 +765,7 @@ ich_pci_attach(device_t dev)
 
        sc->intrhook.ich_func = ich_calibrate;
        sc->intrhook.ich_arg = sc;
+       sc->intrhook.ich_desc = "ich";
        sc->use_intrhook = 1;
        if (config_intrhook_establish(&sc->intrhook) != 0) {
                device_printf(dev, "Cannot establish calibration hook, will calibrate now\n");
index 55adef6..22c0a75 100644 (file)
  *     @(#)subr_autoconf.c     8.1 (Berkeley) 6/10/93
  *
  * $FreeBSD: src/sys/kern/subr_autoconf.c,v 1.14 1999/10/05 21:19:41 n_hibma Exp $
- * $DragonFly: src/sys/kern/subr_autoconf.c,v 1.5 2004/05/26 20:04:07 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_autoconf.c,v 1.6 2005/02/04 02:55:37 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
+#include <sys/thread.h>
+#include <sys/thread2.h>
 
 /*
  * Autoconfiguration subroutines.
@@ -67,6 +69,7 @@ static void
 run_interrupt_driven_config_hooks(void *dummy)
 {
        struct intr_config_hook *hook_entry, *next_entry;
+       int waiting;
 
        for (hook_entry = TAILQ_FIRST(&intr_config_hook_list);
             hook_entry != NULL;
@@ -75,8 +78,26 @@ run_interrupt_driven_config_hooks(void *dummy)
                (*hook_entry->ich_func)(hook_entry->ich_arg);
        }
 
+       waiting = 0;
        while (!TAILQ_EMPTY(&intr_config_hook_list)) {
-               tsleep(&intr_config_hook_list, 0, "conifhk", 0);
+               if (waiting) {
+                       crit_enter();
+                       printf("**WARNING** waiting for the following device to finish configuring:\n");
+                       TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) {
+                           printf("  %s:\tfunc=%p arg=%p\n",
+                               (hook_entry->ich_desc ?
+                                   hook_entry->ich_desc : "?"),
+                               hook_entry->ich_func,
+                               hook_entry->ich_arg);
+                       }
+                       crit_exit();
+                       if (waiting >= 60) {
+                               printf("Giving up, interrupt routing is probably hosed\n");
+                               break;
+                       }
+               }
+               tsleep(&intr_config_hook_list, 0, "conifhk", hz * 10);
+               waiting += 10;
        }
 }
 SYSINIT(intr_config_hooks, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_FIRST,
index 9ffedaf..bc36534 100644 (file)
@@ -40,7 +40,7 @@
  *
  *     @(#)kernel.h    8.3 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/sys/kernel.h,v 1.63.2.9 2002/07/02 23:00:30 archie Exp $
- * $DragonFly: src/sys/sys/kernel.h,v 1.12 2005/02/01 16:09:37 hrs Exp $
+ * $DragonFly: src/sys/sys/kernel.h,v 1.13 2005/02/04 02:55:38 dillon Exp $
  */
 
 #ifndef _SYS_KERNEL_H_
@@ -363,6 +363,7 @@ struct intr_config_hook {
        TAILQ_ENTRY(intr_config_hook) ich_links;
        void    (*ich_func) (void *);
        void    *ich_arg;
+       const char *ich_desc;
 };
 
 int    config_intrhook_establish (struct intr_config_hook *);