svn commit: r297179 - head/sys/dev/ipmi
Alexander Motin
mav at FreeBSD.org
Tue Mar 22 06:24:53 UTC 2016
Author: mav
Date: Tue Mar 22 06:24:52 2016
New Revision: 297179
URL: https://svnweb.freebsd.org/changeset/base/297179
Log:
Optimize IPMI watchdog patting.
Set watchdog timer parameters only when they really need to be changed.
In other cases just restart the timer with single Reset command instead
of two (Set and Reset).
From one side this visually reduces amount of CPU time burned in tight
loop waiting while some slow BMC configures its watchdog hardware, that
seems to be much more complicated task then just resetting the timer.
From another side on some BMCs those slow Set commands sometimes tend to
timeout, that leads to noisy log messages and even more CPU time burned,
so avoiding them can provide even bigger bonuses.
MFC after: 2 weeks
Modified:
head/sys/dev/ipmi/ipmi.c
Modified: head/sys/dev/ipmi/ipmi.c
==============================================================================
--- head/sys/dev/ipmi/ipmi.c Tue Mar 22 06:23:09 2016 (r297178)
+++ head/sys/dev/ipmi/ipmi.c Tue Mar 22 06:24:52 2016 (r297179)
@@ -603,6 +603,20 @@ ipmi_polled_enqueue_request(struct ipmi_
*/
static int
+ipmi_reset_watchdog(struct ipmi_softc *sc)
+{
+ struct ipmi_request *req;
+ int error;
+
+ IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
+ IPMI_RESET_WDOG, 0, 0);
+ error = ipmi_submit_driver_request(sc, req, 0);
+ if (error)
+ device_printf(sc->ipmi_dev, "Failed to reset watchdog\n");
+ return (error);
+}
+
+static int
ipmi_set_watchdog(struct ipmi_softc *sc, unsigned int sec)
{
struct ipmi_request *req;
@@ -613,7 +627,6 @@ ipmi_set_watchdog(struct ipmi_softc *sc,
IPMI_ALLOC_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
IPMI_SET_WDOG, 6, 0);
-
if (sec) {
req->ir_request[0] = IPMI_SET_WD_TIMER_DONT_STOP
| IPMI_SET_WD_TIMER_SMS_OS;
@@ -630,24 +643,10 @@ ipmi_set_watchdog(struct ipmi_softc *sc,
req->ir_request[4] = 0;
req->ir_request[5] = 0;
}
-
error = ipmi_submit_driver_request(sc, req, 0);
if (error)
device_printf(sc->ipmi_dev, "Failed to set watchdog\n");
- else if (sec) {
- IPMI_INIT_DRIVER_REQUEST(req, IPMI_ADDR(IPMI_APP_REQUEST, 0),
- IPMI_RESET_WDOG, 0, 0);
-
- error = ipmi_submit_driver_request(sc, req, 0);
- if (error)
- device_printf(sc->ipmi_dev,
- "Failed to reset watchdog\n");
- }
-
return (error);
- /*
- dump_watchdog(sc);
- */
}
static void
@@ -665,12 +664,24 @@ ipmi_wd_event(void *arg, unsigned int cm
timeout = ((uint64_t)1 << cmd) / 1000000000;
if (timeout == 0)
timeout = 1;
- e = ipmi_set_watchdog(sc, timeout);
- if (e == 0) {
- *error = 0;
- sc->ipmi_watchdog_active = 1;
- } else
- (void)ipmi_set_watchdog(sc, 0);
+ if (timeout != sc->ipmi_watchdog_active) {
+ e = ipmi_set_watchdog(sc, timeout);
+ if (e == 0) {
+ sc->ipmi_watchdog_active = timeout;
+ } else {
+ (void)ipmi_set_watchdog(sc, 0);
+ sc->ipmi_watchdog_active = 0;
+ }
+ }
+ if (sc->ipmi_watchdog_active != 0) {
+ e = ipmi_reset_watchdog(sc);
+ if (e == 0) {
+ *error = 0;
+ } else {
+ (void)ipmi_set_watchdog(sc, 0);
+ sc->ipmi_watchdog_active = 0;
+ }
+ }
} else if (atomic_readandclear_int(&sc->ipmi_watchdog_active) != 0) {
e = ipmi_set_watchdog(sc, 0);
if (e != 0 && cmd == 0)
More information about the svn-src-all
mailing list