From owner-svn-src-all@freebsd.org Sat Jan 13 14:10:07 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D3461E684CC; Sat, 13 Jan 2018 14:10:07 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8E6413669; Sat, 13 Jan 2018 14:10:07 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C121413D8A; Sat, 13 Jan 2018 14:10:06 +0000 (UTC) (envelope-from karels@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0DEA61X071621; Sat, 13 Jan 2018 14:10:06 GMT (envelope-from karels@FreeBSD.org) Received: (from karels@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0DEA6Xn071615; Sat, 13 Jan 2018 14:10:06 GMT (envelope-from karels@FreeBSD.org) Message-Id: <201801131410.w0DEA6Xn071615@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: karels set sender to karels@FreeBSD.org using -f From: Mike Karels Date: Sat, 13 Jan 2018 14:10:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r327920 - in stable/11: share/man/man4 sys/conf sys/dev/watchdog sys/kern sys/sys X-SVN-Group: stable-11 X-SVN-Commit-Author: karels X-SVN-Commit-Paths: in stable/11: share/man/man4 sys/conf sys/dev/watchdog sys/kern sys/sys X-SVN-Commit-Revision: 327920 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 13 Jan 2018 14:10:07 -0000 Author: karels Date: Sat Jan 13 14:10:05 2018 New Revision: 327920 URL: https://svnweb.freebsd.org/changeset/base/327920 Log: MFC r327505: make SW_WATCHDOG dynamic Enable the hardclock-based watchdog previously conditional on the SW_WATCHDOG option whenever hardware watchdogs are not found, and watchdogd attempts to enable the watchdog. The SW_WATCHDOG option still causes the sofware watchdog to be enabled even if there is a hardware watchdog. This does not change the other software-based watchdog enabled by the --softtimeout option to watchdogd. Note that the code to reprime the watchdog during kernel core dumps is no longer conditional on SW_WATCHDOG. I think this was previously a bug. Reviewed by: imp alfred bjk MFC after: 1 week Relnotes: yes Differential Revision: https://reviews.freebsd.org/D13713 Modified: stable/11/share/man/man4/watchdog.4 stable/11/sys/conf/NOTES stable/11/sys/dev/watchdog/watchdog.c stable/11/sys/kern/kern_clock.c stable/11/sys/kern/kern_dump.c stable/11/sys/sys/watchdog.h Modified: stable/11/share/man/man4/watchdog.4 ============================================================================== --- stable/11/share/man/man4/watchdog.4 Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/share/man/man4/watchdog.4 Sat Jan 13 14:10:05 2018 (r327920) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 21, 2009 +.Dd January 2, 2018 .Dt WATCHDOG 4 .Os .Sh NAME @@ -40,8 +40,11 @@ facility is used for controlling hardware and software .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 @@ indicates that the 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 @@ To disable the watchdogs pass 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 @@ Watchdog could not be disabled (timeout value of 0). .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 @@ -122,8 +178,10 @@ Enables a watchdog to recover from a potentially freez .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 Modified: stable/11/sys/conf/NOTES ============================================================================== --- stable/11/sys/conf/NOTES Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/sys/conf/NOTES Sat Jan 13 14:10:05 2018 (r327920) @@ -2656,7 +2656,9 @@ options BOOTP_WIRED_TO=fxp0 # Use interface fxp0 for 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 Modified: stable/11/sys/dev/watchdog/watchdog.c ============================================================================== --- stable/11/sys/dev/watchdog/watchdog.c Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/sys/dev/watchdog/watchdog.c Sat Jan 13 14:10:05 2018 (r327920) @@ -76,6 +76,9 @@ SYSCTL_UINT(_hw_watchdog, OID_AUTO, wd_last_u_secs, CT 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) { @@ -118,6 +121,7 @@ int wdog_kern_pat(u_int utim) { int error; + static int first = 1; if ((utim & WD_LASTVAL) != 0 && (utim & WD_INTERVAL) > 0) return (EINVAL); @@ -159,6 +163,17 @@ wdog_kern_pat(u_int utim) } 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 Modified: stable/11/sys/kern/kern_clock.c ============================================================================== --- stable/11/sys/kern/kern_clock.c Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/sys/kern/kern_clock.c Sat Jan 13 14:10:05 2018 (r327920) @@ -333,15 +333,19 @@ read_cpu_time(long *cp_time) } } -#ifdef SW_WATCHDOG #include 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. * @@ -409,8 +413,14 @@ initclocks(dummy) 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 } @@ -481,10 +491,8 @@ hardclock(int usermode, uintfptr_t pc) #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 @@ -495,9 +503,7 @@ hardclock_cnt(int cnt, int usermode) 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. @@ -557,13 +563,11 @@ hardclock_cnt(int cnt, int usermode) 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 @@ SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, 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 @@ watchdog_fire(void) panic("watchdog timeout"); #endif } - -#endif /* SW_WATCHDOG */ Modified: stable/11/sys/kern/kern_dump.c ============================================================================== --- stable/11/sys/kern/kern_dump.c Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/sys/kern/kern_dump.c Sat Jan 13 14:10:05 2018 (r327920) @@ -27,8 +27,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_watchdog.h" - #include #include #include @@ -36,9 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef SW_WATCHDOG #include -#endif #include #include #include @@ -195,9 +191,7 @@ dumpsys_cb_dumpdata(struct dump_pa *mdp, int seqnr, vo } dumpsys_map_chunk(pa, chunk, &va); -#ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); -#endif error = dump_write(di, va, 0, dumplo, sz); dumpsys_unmap_chunk(pa, chunk, va); Modified: stable/11/sys/sys/watchdog.h ============================================================================== --- stable/11/sys/sys/watchdog.h Sat Jan 13 13:59:35 2018 (r327919) +++ stable/11/sys/sys/watchdog.h Sat Jan 13 14:10:05 2018 (r327920) @@ -110,6 +110,14 @@ EVENTHANDLER_DECLARE(watchdog_list, watchdog_fn); 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 */