Page MenuHomeFreeBSD

D13713.id37434.diff
No OneTemporary

D13713.id37434.diff

Index: head/share/man/man4/watchdog.4
===================================================================
--- head/share/man/man4/watchdog.4
+++ head/share/man/man4/watchdog.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 21, 2009
+.Dd January 2, 2018
.Dt WATCHDOG 4
.Os
.Sh NAME
@@ -40,8 +40,11 @@
.Pp
The device
.Pa /dev/fido
-responds to a single
+supports several optional
.Xr ioctl 2
+calls for configuration, and
+responds to a single operational
+.Xr ioctl
call,
.Dv WDIOCPATPAT .
It takes a single argument which represents a timeout value specified as a
@@ -60,12 +63,16 @@
will be kept from timing out from the kernel.
.Pp
The
+.Dv WDIOCPATPAT
.Xr ioctl 2
call will return success if just one of the available
.Xr watchdog 9
implementations supports setting the timeout to the specified timeout.
This
means that at least one watchdog is armed.
+By default, this will be a hardware watchdog if one is present, but if
+no hardware watchdog is able to process the request, a default software
+watchdog is enabled.
If the call fails, for instance if
none of
.Xr watchdog 9
@@ -77,8 +84,53 @@
If disarming the watchdog(s) failed an error is returned.
The watchdog might
still be armed!
+.Pp
+The optional configuration
+.Xr ioctl
+commands are listed here, along with the type of the parameter used.
+Examples of their use can be found in
+.Xr watchdogd 8 .
+.Bl -tag -width "WDIOC_SETSOFTTIMEOUTACT int "
+.It Dv WDIOC_SETTIMEOUT Fa int
+set/reset the timer
+.It Dv WDIOC_GETTIMEOUT Fa int
+get total timeout
+.It Dv WDIOC_GETTIMELEFT Fa int
+get time left
+.It Dv WDIOC_GETPRETIMEOUT Fa int
+get the pre-timeout
+.It Dv WDIOC_SETPRETIMEOUT Fa int
+set the pre-timeout
+.It Dv WDIOC_SETPRETIMEOUTACT Fa int
+Set the action when a pre-timeout occurs (see
+.Li WD_SOFT_*
+below).
+.It Dv WDIOC_SETSOFT Fa int
+Use an internal software watchdog instead of hardware.
+There is also an external software watchdog, which is used by default
+if no hardware watchdog was attached.
+.It Dv WDIOC_SETSOFTTIMEOUTACT Fa int
+Set the action whan a soft timeout occurs.
+.El
+.Pp
+The actions that may be specified for the pre-timeout or the internal software
+watchdog are listed here.
+Multiple actions can be specified by ORing values together.
+.Bl -tag -width WD_SOFT_PRINT
+.It Dv WD_SOFT_PANIC
+panic
+.It Dv WD_SOFT_DDB
+enter debugger
+.It Dv WD_SOFT_LOG
+log(9)
+.It Dv WD_SOFT_PRINT
+printf(9)
+.El
.Sh RETURN VALUES
-The ioctl returns zero on success and non-zero on failure.
+The
+.Dv WDIOCPATPAT
+.Xr ioctl
+returns zero on success and non-zero on failure.
.Bl -tag -width Er
.It Bq Er EOPNOTSUPP
No watchdog present in the kernel or
@@ -89,6 +141,10 @@
.It Bq Er EINVAL
Invalid flag combination passed.
.El
+.Pp
+The configuration
+.Xr ioctl
+operations return zero on success and non-zero on failure.
.Sh EXAMPLES
.Bd -literal -offset indent
#include <paths.h>
@@ -122,8 +178,10 @@
.Pp
.Dl "options SW_WATCHDOG"
.Pp
-in your kernel config adds a software watchdog in the kernel, dropping to KDB
-or panic-ing when firing.
+in your kernel config forces a software watchdog in the kernel
+to be configured even if a hardware watchdog is configured,
+dropping to KDB or panicking when firing, depending
+on the KDB and KDB_UNATTENDED kernel configuration options.
.Sh SEE ALSO
.Xr watchdogd 8 ,
.Xr watchdog 9
Index: head/sys/conf/NOTES
===================================================================
--- head/sys/conf/NOTES
+++ head/sys/conf/NOTES
@@ -2609,7 +2609,9 @@
options BOOTP_BLOCKSIZE=8192 # Override NFS block size
#
-# Add software watchdog routines.
+# Enable software watchdog routines, even if hardware watchdog is present.
+# By default, software watchdog timer is enabled only if no hardware watchdog
+# is present.
#
options SW_WATCHDOG
Index: head/sys/dev/watchdog/watchdog.c
===================================================================
--- head/sys/dev/watchdog/watchdog.c
+++ head/sys/dev/watchdog/watchdog.c
@@ -78,6 +78,9 @@
static int wd_lastpat_valid = 0;
static time_t wd_lastpat = 0; /* when the watchdog was last patted */
+/* Hook for external software watchdog to register for use if needed */
+void (*wdog_software_attach)(void);
+
static void
pow2ns_to_ts(int pow2ns, struct timespec *ts)
{
@@ -120,6 +123,7 @@
wdog_kern_pat(u_int utim)
{
int error;
+ static int first = 1;
if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0)
return (EINVAL);
@@ -161,6 +165,17 @@
} else {
EVENTHANDLER_INVOKE(watchdog_list, utim, &error);
}
+ /*
+ * If we no hardware watchdog responded, we have not tried to
+ * attach an external software watchdog, and one is available,
+ * attach it now and retry.
+ */
+ if (error == EOPNOTSUPP && first && *wdog_software_attach != NULL) {
+ (*wdog_software_attach)();
+ EVENTHANDLER_INVOKE(watchdog_list, utim, &error);
+ }
+ first = 0;
+
wd_set_pretimeout(wd_pretimeout, true);
/*
* If we were able to arm/strobe the watchdog, then
Index: head/sys/kern/kern_clock.c
===================================================================
--- head/sys/kern/kern_clock.c
+++ head/sys/kern/kern_clock.c
@@ -335,15 +335,19 @@
}
}
-#ifdef SW_WATCHDOG
#include <sys/watchdog.h>
static int watchdog_ticks;
static int watchdog_enabled;
static void watchdog_fire(void);
static void watchdog_config(void *, u_int, int *);
-#endif /* SW_WATCHDOG */
+static void
+watchdog_attach(void)
+{
+ EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0);
+}
+
/*
* Clock handling routines.
*
@@ -410,8 +414,14 @@
if (profhz == 0)
profhz = i;
psratio = profhz / i;
+
#ifdef SW_WATCHDOG
- EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0);
+ /* Enable hardclock watchdog now, even if a hardware watchdog exists. */
+ watchdog_attach();
+#else
+ /* Volunteer to run a software watchdog. */
+ if (wdog_software_attach == NULL)
+ wdog_software_attach = watchdog_attach;
#endif
}
@@ -482,10 +492,8 @@
#ifdef DEVICE_POLLING
hardclock_device_poll(); /* this is very short and quick */
#endif /* DEVICE_POLLING */
-#ifdef SW_WATCHDOG
if (watchdog_enabled > 0 && --watchdog_ticks <= 0)
watchdog_fire();
-#endif /* SW_WATCHDOG */
}
void
@@ -496,9 +504,7 @@
struct proc *p = td->td_proc;
int *t = DPCPU_PTR(pcputicks);
int flags, global, newticks;
-#ifdef SW_WATCHDOG
int i;
-#endif /* SW_WATCHDOG */
/*
* Update per-CPU and possibly global ticks values.
@@ -558,13 +564,11 @@
atomic_store_rel_int(&devpoll_run, 0);
}
#endif /* DEVICE_POLLING */
-#ifdef SW_WATCHDOG
if (watchdog_enabled > 0) {
i = atomic_fetchadd_int(&watchdog_ticks, -newticks);
if (i > 0 && i <= newticks)
watchdog_fire();
}
-#endif /* SW_WATCHDOG */
}
if (curcpu == CPU_FIRST())
cpu_tick_calibration();
@@ -841,8 +845,6 @@
0, 0, sysctl_kern_clockrate, "S,clockinfo",
"Rate and period of various kernel clocks");
-#ifdef SW_WATCHDOG
-
static void
watchdog_config(void *unused __unused, u_int cmd, int *error)
{
@@ -891,5 +893,3 @@
panic("watchdog timeout");
#endif
}
-
-#endif /* SW_WATCHDOG */
Index: head/sys/kern/kern_dump.c
===================================================================
--- head/sys/kern/kern_dump.c
+++ head/sys/kern/kern_dump.c
@@ -27,8 +27,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include "opt_watchdog.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
@@ -36,9 +34,7 @@
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/kerneldump.h>
-#ifdef SW_WATCHDOG
#include <sys/watchdog.h>
-#endif
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -205,9 +201,7 @@
}
dumpsys_map_chunk(pa, chunk, &va);
-#ifdef SW_WATCHDOG
wdog_kern_pat(WD_LASTVAL);
-#endif
error = dump_append(di, va, 0, sz);
dumpsys_unmap_chunk(pa, chunk, va);
Index: head/sys/sys/watchdog.h
===================================================================
--- head/sys/sys/watchdog.h
+++ head/sys/sys/watchdog.h
@@ -112,6 +112,14 @@
u_int wdog_kern_last_timeout(void);
int wdog_kern_pat(u_int utim);
+
+/*
+ * The following function pointer is used to attach a software watchdog
+ * if no hardware watchdog has been attached, and if the software module
+ * has initialized the function pointer.
+ */
+
+extern void (*wdog_software_attach)(void);
#endif
#endif /* _SYS_WATCHDOG_H */

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 9, 2:13 PM (11 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26827371
Default Alt Text
D13713.id37434.diff (8 KB)

Event Timeline