tech-kern archive

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

Re: ksyms_init considered too heavyweight for early bootstrap



Ok, much simpler patch attached - how about this?

Martin
Index: kern_ksyms.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_ksyms.c,v
retrieving revision 1.46
diff -u -p -r1.46 kern_ksyms.c
--- kern_ksyms.c        16 Nov 2008 16:15:58 -0000      1.46
+++ kern_ksyms.c        19 Nov 2008 16:01:05 -0000
@@ -86,6 +86,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/kmem.h>
+#include <sys/once.h>
 #include <sys/proc.h>
 #include <sys/atomic.h>
 #include <sys/ksyms.h>
@@ -101,10 +102,12 @@ static bool ksyms_isopen;
 static bool ksyms_initted;
 static struct ksyms_hdr ksyms_hdr;
 static kmutex_t ksyms_lock;
+static ONCE_DECL(mutex_initialized);
 
 void ksymsattach(int);
 static void ksyms_hdr_init(void *);
 static void ksyms_sizes_calc(void);
+static int ksyms_init_mutex(void);
 
 #ifdef KSYMS_DEBUG
 #define        FOLLOW_CALLS            1
@@ -127,6 +130,13 @@ TAILQ_HEAD(, ksyms_symtab) ksyms_symtabs
 static struct ksyms_symtab kernel_symtab;
 
 static int
+ksyms_init_mutex(void)
+{
+       mutex_init(&ksyms_lock, MUTEX_DEFAULT, IPL_NONE);
+       return 0;
+}
+
+static int
 ksyms_verify(void *symstart, void *strstart)
 {
 #if defined(DIAGNOSTIC) || defined(DEBUG)
@@ -338,7 +348,6 @@ ksyms_init(int symsize, void *start, voi
        size_t strsize = 0;
        Elf_Ehdr *ehdr;
 
-       mutex_init(&ksyms_lock, MUTEX_DEFAULT, IPL_NONE);
 #ifdef SYMTAB_SPACE
        if (symsize <= 0 &&
            strncmp(db_symtab, SYMTAB_FILLER, sizeof(SYMTAB_FILLER))) {
@@ -415,8 +424,6 @@ ksyms_init_explicit(void *ehdr, void *sy
                    void *strstart, size_t strsize)
 {
 
-       mutex_init(&ksyms_lock, MUTEX_DEFAULT, IPL_NONE);
-
        if (!ksyms_verify(symstart, strstart))
                return;
 
@@ -468,6 +475,7 @@ ksyms_getval(const char *mod, const char
        if (!ksyms_initted)
                return ENOENT;
 
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
        mutex_enter(&ksyms_lock);
        rc = ksyms_getval_unlocked(mod, sym, val, type);
        mutex_exit(&ksyms_lock);
@@ -541,6 +549,7 @@ ksyms_modload(const char *name, void *sy
 {
        struct ksyms_symtab *st;
 
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
        st = kmem_zalloc(sizeof(*st), KM_SLEEP);
        mutex_enter(&ksyms_lock);
        addsymtab(name, symstart, symsize, strstart, strsize, st, symstart);
@@ -555,6 +564,7 @@ ksyms_modunload(const char *name)
 {
        struct ksyms_symtab *st;
 
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
        mutex_enter(&ksyms_lock);
        TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
                if (st->sd_gone)
@@ -734,6 +744,7 @@ ksymsopen(dev_t dev, int oflags, int dev
         * Create a "snapshot" of the kernel symbol table.  Setting
         * ksyms_isopen will prevent symbol tables from being freed.
         */
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
        mutex_enter(&ksyms_lock);
        ksyms_hdr.kh_shdr[SYMTAB].sh_size = ksyms_symsz;
        ksyms_hdr.kh_shdr[SYMTAB].sh_info = ksyms_symsz / sizeof(Elf_Sym);
@@ -753,6 +764,7 @@ ksymsclose(dev_t dev, int oflags, int de
        bool resize;
 
        /* Discard refernces to symbol tables. */
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
        mutex_enter(&ksyms_lock);
        ksyms_isopen = false;
        resize = false;
@@ -846,6 +858,8 @@ ksymsioctl(dev_t dev, u_long cmd, void *
        char *str = NULL;
        int len;
 
+       RUN_ONCE(&mutex_initialized, ksyms_init_mutex);
+
        /* Read ksyms_maxlen only once while not holding the lock. */
        len = ksyms_maxlen;
 


Home | Main Index | Thread Index | Old Index