Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Convert swwdog(4) from a simple defpseudo device to a defpse...
details: https://anonhg.NetBSD.org/src/rev/c9d77612bbd6
branches: trunk
changeset: 756545:c9d77612bbd6
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Thu Jul 22 14:10:14 2010 +0000
description:
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.
diffstat:
share/man/man4/swwdog.4 | 25 ++++-
sys/dev/sysmon/files.sysmon | 4 +-
sys/dev/sysmon/swwdog.c | 140 ++++++++++++++++++++++++------
sys/rump/dev/lib/libsysmon/Makefile | 3 +-
sys/rump/dev/lib/libsysmon/SYSMON.ioconf | 8 +
5 files changed, 144 insertions(+), 36 deletions(-)
diffs (truncated from 304 to 300 lines):
diff -r 245b76cc5fc9 -r c9d77612bbd6 share/man/man4/swwdog.4
--- a/share/man/man4/swwdog.4 Thu Jul 22 13:23:02 2010 +0000
+++ b/share/man/man4/swwdog.4 Thu Jul 22 14:10:14 2010 +0000
@@ -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
diff -r 245b76cc5fc9 -r c9d77612bbd6 sys/dev/sysmon/files.sysmon
--- a/sys/dev/sysmon/files.sysmon Thu Jul 22 13:23:02 2010 +0000
+++ b/sys/dev/sysmon/files.sysmon Thu Jul 22 14:10:14 2010 +0000
@@ -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
diff -r 245b76cc5fc9 -r c9d77612bbd6 sys/dev/sysmon/swwdog.c
--- a/sys/dev/sysmon/swwdog.c Thu Jul 22 13:23:02 2010 +0000
+++ b/sys/dev/sysmon/swwdog.c Thu Jul 22 14:10:14 2010 +0000
@@ -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;
+
+ 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;
+ }
+
+ cf.cf_name = swwdog_cd.cd_name;
+ cf.cf_atname = swwdog_cd.cd_name;
+ cf.cf_unit = 0;
+ cf.cf_fstate = FSTATE_STAR;
- for (i = 0; i < NSWWDOG; i++) {
- struct swwdog_softc *sc = &sc_wdog[i];
+ (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);
- 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);
+ 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");
+}
- if (sysmon_wdog_register(&sc->sc_smw) == 0)
- printf("software watchdog initialized\n");
- else
- printf("unable to register software watchdog "
- "with sysmon\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);
+}
diff -r 245b76cc5fc9 -r c9d77612bbd6 sys/rump/dev/lib/libsysmon/Makefile
--- a/sys/rump/dev/lib/libsysmon/Makefile Thu Jul 22 13:23:02 2010 +0000
+++ b/sys/rump/dev/lib/libsysmon/Makefile Thu Jul 22 14:10:14 2010 +0000
@@ -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 \
diff -r 245b76cc5fc9 -r c9d77612bbd6 sys/rump/dev/lib/libsysmon/SYSMON.ioconf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/rump/dev/lib/libsysmon/SYSMON.ioconf Thu Jul 22 14:10:14 2010 +0000
@@ -0,0 +1,8 @@
+# $NetBSD: SYSMON.ioconf,v 1.1 2010/07/22 14:10:14 pgoyette Exp $
+#
+
+ioconf swwdog
Home |
Main Index |
Thread Index |
Old Index