On Sat, 25 Apr 2015, Paul Goyette wrote:



On Sat, 25 Apr 2015, Martin Husemann wrote:

On Sat, Apr 25, 2015 at 03:41:46PM +0800, Paul Goyette wrote:
A quick scan shows that there are about 125-130 sources files which
attempt to register with sysmon_{pswitch,wdog,envsys}_register.

Since this is only about early access to the register functions, can't we
just add a static boolean for each of sysmon_envsys_init, sysmon_wdog_init
and sysmon_power_init, and change the functions to just ignore multiple
calls?

Yes, that might work. But remember that sysmon itself is now a pseudo-device and its initialization needs to interact with the auto-config subsystem.

Most of this should be handled by reverting kern/init_main.c rather than adding initialization calls to each of the ~130 callers!

Attached is a patch which should initialize sysmon sufficiently early to make it available for drivers who want to register. Compile-tested but _not_ booted or otherwise execution-tested. I would appreciate your feedback.


-------------------------------------------------------------------------
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| (Retired)        | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com    |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
Index: dev/sysmon/sysmon.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon.c,v
retrieving revision 1.21
diff -u -p -r1.21 sysmon.c
--- dev/sysmon/sysmon.c 24 Apr 2015 03:35:49 -0000      1.21
+++ dev/sysmon/sysmon.c 25 Apr 2015 08:54:42 -0000
@@ -348,9 +348,14 @@ sysmon_init(void)
 #ifdef _MODULE
        devmajor_t bmajor, cmajor;
 #endif
+       static bool init_done = false;
        static struct cfdata cf;
        int error = 0;
 
+       if (init_done)
+               return 0;
+       init_done = true;
+
        if (sysmon_dev != NULL) {
                return EEXIST;
        }
Index: dev/sysmon/sysmon_envsys.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon_envsys.c,v
retrieving revision 1.135
diff -u -p -r1.135 sysmon_envsys.c
--- dev/sysmon/sysmon_envsys.c  25 Apr 2015 02:41:42 -0000      1.135
+++ dev/sysmon/sysmon_envsys.c  25 Apr 2015 08:54:42 -0000
@@ -118,6 +118,11 @@ int
 sysmon_envsys_init(void)
 {
        int error;
+       static bool init_done = false;
+
+       if (init_done)
+               return 0;
+       init_done = true;
 
        LIST_INIT(&sysmon_envsys_list);
        mutex_init(&sme_global_mtx, MUTEX_DEFAULT, IPL_NONE);
Index: dev/sysmon/sysmon_power.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon_power.c,v
retrieving revision 1.54
diff -u -p -r1.54 sysmon_power.c
--- dev/sysmon/sysmon_power.c   23 Apr 2015 23:22:03 -0000      1.54
+++ dev/sysmon/sysmon_power.c   25 Apr 2015 08:54:42 -0000
@@ -209,6 +209,11 @@ int
 sysmon_power_init(void)
 {
        int error;
+       static bool init_done = false;
+
+       if (init_done)
+               return 0;
+       init_done = true;
 
        mutex_init(&sysmon_power_event_queue_mtx, MUTEX_DEFAULT, IPL_NONE);
        cv_init(&sysmon_power_event_queue_cv, "smpower");
Index: dev/sysmon/sysmon_wdog.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sysmon/sysmon_wdog.c,v
retrieving revision 1.26
diff -u -p -r1.26 sysmon_wdog.c
--- dev/sysmon/sysmon_wdog.c    23 Apr 2015 23:22:03 -0000      1.26
+++ dev/sysmon/sysmon_wdog.c    25 Apr 2015 08:54:42 -0000
@@ -86,6 +86,11 @@ int
 sysmon_wdog_init(void)
 {
        int error;
+       static bool init_done = false;
+
+       if (init_done)
+               return 0;
+       init_done = true;
 
        mutex_init(&sysmon_wdog_list_mtx, MUTEX_DEFAULT, IPL_NONE);
        mutex_init(&sysmon_wdog_mtx, MUTEX_DEFAULT, IPL_SOFTCLOCK);
Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.463
diff -u -p -r1.463 init_main.c
--- kern/init_main.c    23 Apr 2015 23:23:08 -0000      1.463
+++ kern/init_main.c    25 Apr 2015 08:54:42 -0000
@@ -118,6 +118,10 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,
 #include "ksyms.h"
 
 #include "sysmon_taskq.h"
+#include "sysmon_wdog.h"
+#include "sysmon_power.h"
+#include "sysmon_envsys.h"
+
 #include "veriexec.h"
 
 #include <sys/param.h>
@@ -222,6 +226,10 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,
 #include <dev/sysmon/sysmon_taskq.h>
 #endif
 
+#if NSYSMON_ENVSYS > 0 || NSYSMON_POWER > 0 || NSYSMON_WDOG > 0
+#include <dev/sysmon/sysmonvar.h>
+#endif
+
 #include <dev/cons.h>
 
 #include <net/bpf.h>
@@ -461,15 +469,29 @@ main(void)
        kqueue_init();
 
        /*
-        * Initialize sysmon's task queue.  It is used by at
-        * least one non-modularized component (dev/acpica)
-        * and needs to be available early, before the rest
-        * of the module(9) subsystem is ready.
+        * Initialize sysmon components.
         */
+
 #if NSYSMON_TASKQ > 0
        sysmon_task_queue_preinit();
 #endif
 
+#if NSYSMON_ENVSYS > 0 || NSYSMON_POWER > 0 || NSYSMON_WDOG > 0
+       sysmon_init();
+#endif
+
+#if NSYSMON_ENVSYS > 0
+       sysmon_envsys_init();
+#endif
+
+#if NSYSMON_POWER > 0
+       sysmon_power_init();
+#endif
+
+#if NSYSMON_WDOG > 0
+       sysmon_wdog_init();
+#endif
+
        inittimecounter();
        ntp_init();
 

Reply via email to