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