Module Name: src Committed By: riastradh Date: Tue Dec 3 19:55:33 UTC 2024
Modified Files: src/sys/dev: ipmi.c ipmivar.h Log Message: ipmi(4): Don't hold up boot -- just hold up wdogctl(8). While here, omit needless volatile qualifier on variables serialized by mutex (or by config_pending_incr/decr -- ipmi_detach can't run until ipmi_thread does config_pending_decr). It's not entirely clear that we even need to hold up wdogctl(8). Perhaps we can do that in parallel -- or really, interleaved -- with scanning for SDR sensors. But this is a safer change for now without requiring thought about that. PR kern/56568: ipmi.c 1.7 causes large boot delays To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ipmi.c cvs rdiff -u -r1.3 -r1.4 src/sys/dev/ipmivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ipmi.c diff -u src/sys/dev/ipmi.c:1.10 src/sys/dev/ipmi.c:1.11 --- src/sys/dev/ipmi.c:1.10 Wed Mar 22 13:00:54 2023 +++ src/sys/dev/ipmi.c Tue Dec 3 19:55:33 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ipmi.c,v 1.10 2023/03/22 13:00:54 mlelstv Exp $ */ +/* $NetBSD: ipmi.c,v 1.11 2024/12/03 19:55:33 riastradh Exp $ */ /* * Copyright (c) 2019 Michael van Elst @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.10 2023/03/22 13:00:54 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipmi.c,v 1.11 2024/12/03 19:55:33 riastradh Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -1998,6 +1998,23 @@ ipmi_thread(void *cookie) /* Map registers */ ipmi_map_regs(sc, ia); + /* Setup Watchdog timer */ + sc->sc_wdog.smw_name = device_xname(sc->sc_dev); + sc->sc_wdog.smw_cookie = sc; + sc->sc_wdog.smw_setmode = ipmi_watchdog_setmode; + sc->sc_wdog.smw_tickle = ipmi_watchdog_tickle; + sysmon_wdog_register(&sc->sc_wdog); + + /* Set up a power handler so we can possibly sleep */ + if (!pmf_device_register(self, ipmi_suspend, NULL)) + aprint_error_dev(self, "couldn't establish a power handler\n"); + + /* + * Allow boot to proceed -- we'll do the rest asynchronously + * since it requires talking to the device. + */ + config_pending_decr(self); + memset(&id, 0, sizeof(id)); if (ipmi_get_device_id(sc, &id)) aprint_error_dev(self, "Failed to re-query device ID\n"); @@ -2098,20 +2115,9 @@ ipmi_thread(void *cookie) /* setup flag to exclude iic */ ipmi_enabled = 1; - /* Setup Watchdog timer */ - sc->sc_wdog.smw_name = device_xname(sc->sc_dev); - sc->sc_wdog.smw_cookie = sc; - sc->sc_wdog.smw_setmode = ipmi_watchdog_setmode; - sc->sc_wdog.smw_tickle = ipmi_watchdog_tickle; - sysmon_wdog_register(&sc->sc_wdog); - - /* Set up a power handler so we can possibly sleep */ - if (!pmf_device_register(self, ipmi_suspend, NULL)) - aprint_error_dev(self, "couldn't establish a power handler\n"); - - config_pending_decr(self); - mutex_enter(&sc->sc_poll_mtx); + sc->sc_thread_ready = true; + cv_broadcast(&sc->sc_mode_cv); while (sc->sc_thread_running) { while (sc->sc_mode == IPMI_MODE_COMMAND) cv_wait(&sc->sc_mode_cv, &sc->sc_poll_mtx); @@ -2259,6 +2265,15 @@ ipmi_watchdog_setmode(struct sysmon_wdog else sc->sc_wdog.smw_period = smwdog->smw_period; + /* Wait until the device is initialized */ + rc = 0; + mutex_enter(&sc->sc_poll_mtx); + while (sc->sc_thread_ready) + rc = cv_wait_sig(&sc->sc_mode_cv, &sc->sc_poll_mtx); + mutex_exit(&sc->sc_poll_mtx); + if (rc) + return rc; + mutex_enter(&sc->sc_cmd_mtx); /* see if we can properly task to the watchdog */ rc = ipmi_sendcmd(sc, BMC_SA, BMC_LUN, APP_NETFN, Index: src/sys/dev/ipmivar.h diff -u src/sys/dev/ipmivar.h:1.3 src/sys/dev/ipmivar.h:1.4 --- src/sys/dev/ipmivar.h:1.3 Sat May 18 08:38:00 2019 +++ src/sys/dev/ipmivar.h Tue Dec 3 19:55:33 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ipmivar.h,v 1.3 2019/05/18 08:38:00 mlelstv Exp $ */ +/* $NetBSD: ipmivar.h,v 1.4 2024/12/03 19:55:33 riastradh Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave @@ -101,8 +101,9 @@ struct ipmi_softc { struct ipmi_bmc_args *sc_iowait_args; struct ipmi_sensor *current_sensor; - volatile bool sc_thread_running; - volatile bool sc_tickle_due; + bool sc_thread_running; + bool sc_thread_ready; + bool sc_tickle_due; struct sysmon_wdog sc_wdog; struct sysmon_envsys *sc_envsys; envsys_data_t *sc_sensor;