Module Name: src Committed By: pgoyette Date: Thu Jul 22 14:10:15 UTC 2010
Modified Files: src/share/man/man4: swwdog.4 src/sys/dev/sysmon: files.sysmon swwdog.c src/sys/rump/dev/lib/libsysmon: Makefile Added Files: src/sys/rump/dev/lib/libsysmon: SYSMON.ioconf Log Message: Convert swwdog(4) from a simple defpseudo device to a defpseudodev so that we can attach a power management handler. The handler prevents a suspend if the watchdog is active, to be consistent with other watchdog drivers. As discussed on tech-kern. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/share/man/man4/swwdog.4 cvs rdiff -u -r1.11 -r1.12 src/sys/dev/sysmon/files.sysmon cvs rdiff -u -r1.9 -r1.10 src/sys/dev/sysmon/swwdog.c cvs rdiff -u -r1.2 -r1.3 src/sys/rump/dev/lib/libsysmon/Makefile cvs rdiff -u -r0 -r1.1 src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/share/man/man4/swwdog.4 diff -u src/share/man/man4/swwdog.4:1.4 src/share/man/man4/swwdog.4:1.5 --- src/share/man/man4/swwdog.4:1.4 Sat Jan 30 21:55:28 2010 +++ src/share/man/man4/swwdog.4 Thu Jul 22 14:10:14 2010 @@ -1,4 +1,4 @@ -.\" $NetBSD: swwdog.4,v 1.4 2010/01/30 21:55:28 pooka Exp $ +.\" $NetBSD: swwdog.4,v 1.5 2010/07/22 14:10:14 pgoyette Exp $ .\" .\" Copyright (c) 2004, 2005 Steven M. Bellovin .\" All rights reserved. @@ -31,7 +31,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 30, 2010 +.Dd July 21, 2010 .\" Written by Steven M. Bellovin .Dt SWWDOG 4 .Os @@ -45,14 +45,26 @@ .Nm driver provides a software watchdog timer that works with .Xr wdogctl 8 . -If the timer expires, the system reboots unless the variable +If the timer expires, the system reboots unless the boolean variable .Va swwdog_panic -is non-zero; if it is, the system will panic instead. +is +.Dv true ; +if it is, the system will panic instead. +.Va swwdog_reboot +is accessible as a +.Xr sysctl 8 +variable, machdep.swwdog0.reboot and defaults to +.Dv false . .Pp The default period of .Nm is 60 seconds. +.Pp +As with other watchdog timers, the +.Nm +driver prevents a system from suspending when the watchdog is armed. .Sh SEE ALSO +.Xr sysctl 8 .Xr wdogctl 8 .Sh HISTORY The @@ -61,7 +73,10 @@ .An Steven M. Bellovin . .Sh BUGS Only one watchdog timer can be active at any given time. -Arguably, this is a bug in the watchdog timer framework. +(Arguably, this is a bug in the watchdog timer framework.) +Therefore, only a single instance of the +.Nm +device can be created. .Pp Kernel tickle mode is useless with .Nm Index: src/sys/dev/sysmon/files.sysmon diff -u src/sys/dev/sysmon/files.sysmon:1.11 src/sys/dev/sysmon/files.sysmon:1.12 --- src/sys/dev/sysmon/files.sysmon:1.11 Sat Jan 30 21:55:28 2010 +++ src/sys/dev/sysmon/files.sysmon Thu Jul 22 14:10:15 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files.sysmon,v 1.11 2010/01/30 21:55:28 pooka Exp $ +# $NetBSD: files.sysmon,v 1.12 2010/07/22 14:10:15 pgoyette Exp $ define sysmon_taskq file dev/sysmon/sysmon_taskq.c sysmon_taskq needs-flag @@ -18,5 +18,5 @@ file dev/sysmon/sysmon.c sysmon_envsys | sysmon_wdog | sysmon_power -defpseudo swwdog: sysmon_wdog +defpseudodev swwdog: sysmon_wdog file dev/sysmon/swwdog.c swwdog Index: src/sys/dev/sysmon/swwdog.c diff -u src/sys/dev/sysmon/swwdog.c:1.9 src/sys/dev/sysmon/swwdog.c:1.10 --- src/sys/dev/sysmon/swwdog.c:1.9 Sun Jan 31 02:54:56 2010 +++ src/sys/dev/sysmon/swwdog.c Thu Jul 22 14:10:15 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: swwdog.c,v 1.9 2010/01/31 02:54:56 pooka Exp $ */ +/* $NetBSD: swwdog.c,v 1.10 2010/07/22 14:10:15 pgoyette Exp $ */ /* * Copyright (c) 2004, 2005 Steven M. Bellovin @@ -33,7 +33,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.9 2010/01/31 02:54:56 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.10 2010/07/22 14:10:15 pgoyette Exp $"); /* * @@ -44,20 +44,28 @@ #include <sys/callout.h> #include <sys/device.h> #include <sys/kernel.h> +#include <sys/kmem.h> #include <sys/reboot.h> #include <sys/systm.h> +#include <sys/sysctl.h> #include <sys/wdog.h> #include <dev/sysmon/sysmonvar.h> -#define NSWWDOG 1 +#include "ioconf.h" + struct swwdog_softc { + device_t sc_dev; struct sysmon_wdog sc_smw; struct callout sc_c; - char sc_name[20]; int sc_wdog_armed; -} sc_wdog[NSWWDOG]; +}; + +void swwdogattach(int); -void swwdogattach(int); +static int swwdog_match(device_t, cfdata_t, void *); +static void swwdog_attach(device_t, device_t, void *); +static int swwdog_detach(device_t, int); +static bool swwdog_suspend(device_t, const pmf_qual_t *); static int swwdog_setmode(struct sysmon_wdog *); static int swwdog_tickle(struct sysmon_wdog *); @@ -67,34 +75,87 @@ static void swwdog_panic(void *); -int swwdog_reboot = 0; /* set for panic instead of reboot */ +bool swwdog_reboot = false; /* set for panic instead of reboot */ #define SWDOG_DEFAULT 60 /* 60-second default period */ +CFATTACH_DECL_NEW(swwdog, sizeof(struct swwdog_softc), + swwdog_match, swwdog_attach, swwdog_detach, NULL); + void -swwdogattach(int count __unused) +swwdogattach(int n __unused) { - int i; + int err; + static struct cfdata cf; - for (i = 0; i < NSWWDOG; i++) { - struct swwdog_softc *sc = &sc_wdog[i]; + err = config_cfattach_attach(swwdog_cd.cd_name, &swwdog_ca); + if (err) { + aprint_error("%s: couldn't register cfattach: %d\n", + swwdog_cd.cd_name, err); + config_cfdriver_detach(&swwdog_cd); + return; + } - snprintf(sc->sc_name, sizeof sc->sc_name, "swwdog%d", i); - printf("%s: ", sc->sc_name); - sc->sc_smw.smw_name = sc->sc_name; - sc->sc_smw.smw_cookie = sc; - sc->sc_smw.smw_setmode = swwdog_setmode; - sc->sc_smw.smw_tickle = swwdog_tickle; - sc->sc_smw.smw_period = SWDOG_DEFAULT; - callout_init(&sc->sc_c, 0); - callout_setfunc(&sc->sc_c, swwdog_panic, sc); + cf.cf_name = swwdog_cd.cd_name; + cf.cf_atname = swwdog_cd.cd_name; + cf.cf_unit = 0; + cf.cf_fstate = FSTATE_STAR; - if (sysmon_wdog_register(&sc->sc_smw) == 0) - printf("software watchdog initialized\n"); - else - printf("unable to register software watchdog " - "with sysmon\n"); - } + (void)config_attach_pseudo(&cf); + + return; +} + +static int +swwdog_match(device_t parent, cfdata_t data, void *aux) +{ + return 1; +} + +static void +swwdog_attach(device_t parent, device_t self, void *aux) +{ + struct swwdog_softc *sc = device_private(self); + + sc->sc_dev = self; + sc->sc_smw.smw_name = device_xname(self); + sc->sc_smw.smw_cookie = sc; + sc->sc_smw.smw_setmode = swwdog_setmode; + sc->sc_smw.smw_tickle = swwdog_tickle; + sc->sc_smw.smw_period = SWDOG_DEFAULT; + callout_init(&sc->sc_c, 0); + callout_setfunc(&sc->sc_c, swwdog_panic, sc); + + if (sysmon_wdog_register(&sc->sc_smw) == 0) + aprint_normal_dev(self, "software watchdog initialized\n"); + else + aprint_error_dev(self, "unable to register software " + "watchdog with sysmon\n"); + + if (!pmf_device_register(self, swwdog_suspend, NULL)) + aprint_error_dev(self, "couldn't establish power handler\n"); +} + +static int +swwdog_detach(device_t self, int flags) +{ + struct swwdog_softc *sc = device_private(self); + + swwdog_disarm(sc); + callout_destroy(&sc->sc_c); + + return 1; +} + +static bool +swwdog_suspend(device_t dev, const pmf_qual_t *qual) +{ + struct swwdog_softc *sc = device_private(dev); + + /* Don't allow suspend if watchdog is armed */ + if ((sc->sc_smw.smw_mode & WDOG_MODE_MASK) != WDOG_MODE_DISARMED) + return false; + return true; } static int @@ -144,13 +205,13 @@ swwdog_panic(void *vsc) { struct swwdog_softc *sc = vsc; - int do_panic; + bool do_panic; do_panic = swwdog_reboot; swwdog_reboot = 1; callout_schedule(&sc->sc_c, 60 * hz); /* deliberate double-panic */ - printf("%s: %d second timer expired\n", sc->sc_name, + printf("%s: %d second timer expired\n", device_xname(sc->sc_dev), sc->sc_smw.smw_period); if (do_panic) @@ -158,3 +219,26 @@ else cpu_reboot(0, NULL); } + +SYSCTL_SETUP(sysctl_swwdog, "swwdog subtree setup") +{ + int err; + const struct sysctlnode *me; + + err = sysctl_createv(NULL, 0, NULL, NULL, CTLFLAG_PERMANENT, + CTLTYPE_NODE, "machdep", NULL, + NULL, 0, NULL, 0, + CTL_HW, CTL_EOL); + + if (err == 0) + err = sysctl_createv(NULL, 0, NULL, &me, CTLFLAG_READWRITE, + CTLTYPE_NODE, "swwdog", NULL, + NULL, 0, NULL, 0, + CTL_HW, CTL_CREATE, CTL_EOL); + + if (err == 0) + err = sysctl_createv(NULL, 0, NULL, NULL, CTLFLAG_READWRITE, + CTLTYPE_BOOL, "reboot", "reboot if timer expires", + NULL, 0, &swwdog_reboot, sizeof(bool), + CTL_HW, me->sysctl_num, CTL_CREATE, CTL_EOL); +} Index: src/sys/rump/dev/lib/libsysmon/Makefile diff -u src/sys/rump/dev/lib/libsysmon/Makefile:1.2 src/sys/rump/dev/lib/libsysmon/Makefile:1.3 --- src/sys/rump/dev/lib/libsysmon/Makefile:1.2 Tue Feb 16 20:42:45 2010 +++ src/sys/rump/dev/lib/libsysmon/Makefile Thu Jul 22 14:10:14 2010 @@ -1,9 +1,10 @@ -# $NetBSD: Makefile,v 1.2 2010/02/16 20:42:45 pooka Exp $ +# $NetBSD: Makefile,v 1.3 2010/07/22 14:10:14 pgoyette Exp $ # .PATH: ${.CURDIR}/../../../../dev/sysmon LIB= rumpdev_sysmon +IOCONF= SYSMON.ioconf SRCS= sysmon_taskq.c sysmon_power.c sysmon_envsys.c sysmon_envsys_events.c \ sysmon_envsys_tables.c sysmon_envsys_util.c sysmon_wdog.c sysmon.c \ Added files: Index: src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf diff -u /dev/null src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf:1.1 --- /dev/null Thu Jul 22 14:10:15 2010 +++ src/sys/rump/dev/lib/libsysmon/SYSMON.ioconf Thu Jul 22 14:10:14 2010 @@ -0,0 +1,8 @@ +# $NetBSD: SYSMON.ioconf,v 1.1 2010/07/22 14:10:14 pgoyette Exp $ +# + +ioconf swwdog + +include "conf/files" + +pseudo-device swwdog