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;