Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sysmon Apparently swwdog reboot hasn't worked in sev...



details:   https://anonhg.NetBSD.org/src/rev/724b9a3c0120
branches:  trunk
changeset: 758635:724b9a3c0120
user:      pooka <pooka%NetBSD.org@localhost>
date:      Thu Nov 11 21:55:04 2010 +0000

description:
Apparently swwdog reboot hasn't worked in several years since it
tried to cpu_reboot() from a callout.  Make it reboot from a workq
instead.

problem made manifest
by atf test
rumpfs unmount flush
caused issue to un-shush

tested: rump kernel (tests/dev/sysmon) and qemu

diffstat:

 sys/dev/sysmon/swwdog.c |  24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diffs (84 lines):

diff -r 0bac6c95475a -r 724b9a3c0120 sys/dev/sysmon/swwdog.c
--- a/sys/dev/sysmon/swwdog.c   Thu Nov 11 18:45:09 2010 +0000
+++ b/sys/dev/sysmon/swwdog.c   Thu Nov 11 21:55:04 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: swwdog.c,v 1.11 2010/08/06 16:02:56 pooka Exp $        */
+/*     $NetBSD: swwdog.c,v 1.12 2010/11/11 21:55:04 pooka Exp $        */
 
 /*
  * Copyright (c) 2004, 2005 Steven M. Bellovin
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.11 2010/08/06 16:02:56 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.12 2010/11/11 21:55:04 pooka Exp $");
 
 /*
  *
@@ -49,6 +49,7 @@
 #include <sys/systm.h>
 #include <sys/sysctl.h>
 #include <sys/wdog.h>
+#include <sys/workqueue.h>
 #include <dev/sysmon/sysmonvar.h>
 
 #include "ioconf.h"
@@ -85,17 +86,32 @@
 static void swwdog_sysctl_setup(void);
 static struct sysctllog *swwdog_sysctllog;
 
+static void
+doreboot(struct work *wrkwrkwrk, void *p)
+{
+
+       cpu_reboot(0, NULL);
+}
+
+static struct workqueue *wq;
+
 void
 swwdogattach(int n __unused)
 {
        int err;
        static struct cfdata cf;
 
+       if (workqueue_create(&wq, "swwreboot", doreboot, NULL,
+           PRI_NONE, IPL_NONE, 0) != 0) {
+               aprint_error("failed to create swwdog reboot wq");
+       }
+
        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);
+               workqueue_destroy(wq);
                return;
        }
 
@@ -149,6 +165,7 @@
        swwdog_disarm(sc);
        callout_destroy(&sc->sc_c);
        sysctl_teardown(&swwdog_sysctllog);
+       workqueue_destroy(wq);
 
        return 1;
 }
@@ -211,6 +228,7 @@
 swwdog_panic(void *vsc)
 {
        struct swwdog_softc *sc = vsc;
+       static struct work wk; /* we'll need it max once */
        bool do_panic;
 
        do_panic = !swwdog_reboot;
@@ -223,7 +241,7 @@
        if (do_panic)
                panic("watchdog timer expired");
        else
-               cpu_reboot(0, NULL);
+               workqueue_enqueue(wq, &wk, NULL);
 }
 
 static void



Home | Main Index | Thread Index | Old Index