NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/56568: ipmi.c 1.7 causes large boot delays
The attached patch -- compile-tested only -- tries to resolve the
present conflict between long ipmi(4) initialization time and early
use of wdogctl(8) at boot by:
(a) allowing boot to proceed with config_pending_decr sooner, before
device initialization has completed; and
(b) making watchdog configuration wait until initialization has
completed.
Testing welcome!
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1733184792 0
# Tue Dec 03 00:13:12 2024 +0000
# Branch trunk
# Node ID 32dee81c8e034a77811fddb38816c166f46bb530
# Parent 9e743b738fb8d4ce4e33ddccdc9acb6e8e81f9df
# EXP-Topic riastradh-pr56568-ipmidelay
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).
PR kern/56568: ipmi.c 1.7 causes large boot delays
diff -r 9e743b738fb8 -r 32dee81c8e03 sys/dev/ipmi.c
--- a/sys/dev/ipmi.c Sun Dec 01 11:10:34 2024 +0000
+++ b/sys/dev/ipmi.c Tue Dec 03 00:13:12 2024 +0000
@@ -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,
diff -r 9e743b738fb8 -r 32dee81c8e03 sys/dev/ipmivar.h
--- a/sys/dev/ipmivar.h Sun Dec 01 11:10:34 2024 +0000
+++ b/sys/dev/ipmivar.h Tue Dec 03 00:13:12 2024 +0000
@@ -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;
Home |
Main Index |
Thread Index |
Old Index