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