Index: sys/kern/subr_autoconf.c =================================================================== --- sys/kern/subr_autoconf.c +++ sys/kern/subr_autoconf.c @@ -45,6 +45,7 @@ #include #include #include +#include #include /* @@ -60,6 +61,19 @@ static struct mtx intr_config_hook_lock; MTX_SYSINIT(intr_config_hook, &intr_config_hook_lock, "intr config", MTX_DEF); + +SYSCTL_NODE(_kern, OID_AUTO, autoconf, CTLFLAG_RW, 0, ""); + +#define WARNING_INTERVAL_SECS 60 +static int intrhook_interval_secs = WARNING_INTERVAL_SECS; +SYSCTL_INT(_kern_autoconf, OID_AUTO, intrhook_seconds, CTLFLAG_RDTUN, + &intrhook_interval_secs, 0, "Intrhook loop timeout in seconds"); + +#define WARNING_INTERVAL_LOOPS 5 +static int intrhook_interval_loops = WARNING_INTERVAL_LOOPS; +SYSCTL_INT(_kern_autoconf, OID_AUTO, intrhook_loops, CTLFLAG_RDTUN, + &intrhook_interval_loops, 0, "Intrhook loop count"); + /* ARGSUSED */ static void run_interrupt_driven_config_hooks(void); @@ -88,7 +102,6 @@ * If we wait too long for an interrupt-driven config hook to return, print * a diagnostic. */ -#define WARNING_INTERVAL_SECS 60 static void run_interrupt_driven_config_hooks_warning(int warned) { @@ -96,9 +109,9 @@ char namebuf[64]; long offset; - if (warned < 6) { + if (warned < intrhook_interval_loops) { printf("run_interrupt_driven_hooks: still waiting after %d " - "seconds for", warned * WARNING_INTERVAL_SECS); + "seconds for", warned * intrhook_interval_secs); TAILQ_FOREACH(hook_entry, &intr_config_hook_list, ich_links) { if (linker_search_symbol_name( (caddr_t)hook_entry->ich_func, namebuf, @@ -109,7 +122,8 @@ } printf("\n"); } - KASSERT(warned < 6, + + KASSERT(warned < intrhook_interval_loops, ("run_interrupt_driven_config_hooks: waited too long")); } @@ -156,12 +170,22 @@ mtx_lock(&intr_config_hook_lock); warned = 0; while (!TAILQ_EMPTY(&intr_config_hook_list)) { + if (warned >= intrhook_interval_loops) { + + /* + * Allow the system to break out early rather than risk + * never making progress. + */ + if (warned == 0) + run_interrupt_driven_config_hooks_warning(warned); + printf("Continuing with boot\n"); + break; + } if (msleep(&intr_config_hook_list, &intr_config_hook_lock, - 0, "conifhk", WARNING_INTERVAL_SECS * hz) == + 0, "conifhk", intrhook_interval_secs * hz) == EWOULDBLOCK) { mtx_unlock(&intr_config_hook_lock); - warned++; - run_interrupt_driven_config_hooks_warning(warned); + run_interrupt_driven_config_hooks_warning(warned++); mtx_lock(&intr_config_hook_lock); } }