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;

Reply via email to