PERFORCE change 97634 for review
John Birrell
jb at FreeBSD.org
Mon May 22 20:16:29 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=97634
Change 97634 by jb at jb_freebsd2 on 2006/05/22 20:15:14
Change the kernel linker to use an sx lock instead of a mutex so that
DTrace can list all linker files while holding the lock and still be
able to malloc with wait to create probes.
Add a function to list the function names and their values. This function
assumes that the lock is held while listing the files, so no additional
locking is attempted.
Affected files ...
.. //depot/projects/dtrace/src/sys/kern/kern_linker.c#8 edit
.. //depot/projects/dtrace/src/sys/sys/linker.h#6 edit
Differences ...
==== //depot/projects/dtrace/src/sys/kern/kern_linker.c#8 (text+ko) ====
@@ -49,6 +49,7 @@
#include <sys/libkern.h>
#include <sys/namei.h>
#include <sys/vnode.h>
+#include <sys/sx.h>
#include <sys/sysctl.h>
#include "linker_if.h"
@@ -74,7 +75,7 @@
linker_file_t linker_kernel_file;
-static struct mtx kld_mtx; /* kernel linker mutex */
+static struct sx kld_sx; /* kernel linker lock */
static linker_class_list_t classes;
static linker_file_list_t linker_files;
@@ -85,16 +86,16 @@
linker_file_t lftmp; \
\
retry: \
- mtx_lock(&kld_mtx); \
+ sx_xlock(&kld_sx); \
TAILQ_FOREACH(lftmp, &linker_files, link) { \
if (next_file_id == lftmp->id) { \
next_file_id++; \
- mtx_unlock(&kld_mtx); \
+ sx_xunlock(&kld_sx); \
goto retry; \
} \
} \
(a) = next_file_id; \
- mtx_unlock(&kld_mtx); /* Hold for safe read of id variable */ \
+ sx_xunlock(&kld_sx); /* Hold for safe read of id variable */ \
} while(0)
@@ -126,7 +127,7 @@
linker_init(void *arg)
{
- mtx_init(&kld_mtx, "kernel linker", NULL, MTX_DEF);
+ sx_init(&kld_sx, "kernel linker");
TAILQ_INIT(&classes);
TAILQ_INIT(&linker_files);
}
@@ -424,14 +425,14 @@
goto out;
sprintf(koname, "%s.ko", filename);
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
if (strcmp(lf->filename, koname) == 0)
break;
if (strcmp(lf->filename, filename) == 0)
break;
}
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
out:
if (koname)
free(koname, M_LINKER);
@@ -443,11 +444,11 @@
{
linker_file_t lf = 0;
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link)
if (lf->id == fileid)
break;
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return (lf);
}
@@ -474,9 +475,9 @@
lf->deps = NULL;
STAILQ_INIT(&lf->common);
TAILQ_INIT(&lf->modules);
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_INSERT_TAIL(&linker_files, lf, link);
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
out:
return (lf);
}
@@ -546,9 +547,9 @@
linker_file_sysuninit(file);
linker_file_unregister_sysctls(file);
}
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_REMOVE(&linker_files, file, link);
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
if (file->deps) {
for (i = 0; i < file->ndeps; i++)
@@ -618,18 +619,28 @@
linker_file_t lf;
int error = 0;
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
if ((error = callback_func(lf, arg)) != 0)
break;
}
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return (error);
}
+/*
+ * List all functions in a file.
+ */
+int
+linker_file_function_listall(linker_file_t lf,
+ int (*callback_func)(linker_file_t, linker_symval_t *, void *), void *arg)
+{
+ return (LINKER_EACH_FUNCTION_NAMEVAL(lf, callback_func, arg));
+}
+
caddr_t
linker_file_lookup_value(const char *name)
{
@@ -639,7 +650,7 @@
symval.value = 0;
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
if (LINKER_LOOKUP_SYMBOL(lf, name, &sym) == 0 &&
@@ -647,7 +658,7 @@
break;
}
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return (symval.value);
}
@@ -988,12 +999,12 @@
mtx_lock(&Giant);
if (uap->fileid == 0) {
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
if (TAILQ_FIRST(&linker_files))
td->td_retval[0] = TAILQ_FIRST(&linker_files)->id;
else
td->td_retval[0] = 0;
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
goto out;
}
lf = linker_find_file_by_id(uap->fileid);
@@ -1159,7 +1170,7 @@
} else
error = ENOENT;
} else {
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
if (LINKER_LOOKUP_SYMBOL(lf, symstr, &sym) == 0 &&
LINKER_SYMBOL_VALUES(lf, sym, &symval) == 0) {
@@ -1170,7 +1181,7 @@
break;
}
}
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
if (lf == NULL)
error = ENOENT;
}
@@ -1772,7 +1783,7 @@
M_WAITOK | M_ZERO);
nobjects = 0;
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link)
nobjects++;
@@ -1782,7 +1793,7 @@
if (nobjects > nmappings) {
nmappings = nobjects;
FREE(kobase, M_LINKER);
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
goto retry;
}
@@ -1797,7 +1808,7 @@
KASSERT(ko->pm_file == NULL,
("linker_hwpmc_list_objects: last object not NULL"));
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return ((void *) kobase);
}
@@ -1990,16 +2001,16 @@
error = sysctl_wire_old_buffer(req, 0);
if (error != 0)
return (error);
- mtx_lock(&kld_mtx);
+ sx_xlock(&kld_sx);
TAILQ_FOREACH(lf, &linker_files, link) {
error = LINKER_EACH_FUNCTION_NAME(lf,
sysctl_kern_function_list_iterate, req);
if (error) {
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return (error);
}
}
- mtx_unlock(&kld_mtx);
+ sx_xunlock(&kld_sx);
return (SYSCTL_OUT(req, "", 1));
}
==== //depot/projects/dtrace/src/sys/sys/linker.h#6 (text+ko) ====
@@ -59,6 +59,8 @@
size_t size;
} linker_symval_t;
+typedef int (*linker_function_nameval_callback_t)(linker_file_t, linker_symval_t *, void *);
+
struct common_symbol {
STAILQ_ENTRY(common_symbol) link;
char* name;
@@ -82,6 +84,9 @@
STAILQ_HEAD(, common_symbol) common; /* list of common symbols */
TAILQ_HEAD(, module) modules; /* modules in this file */
TAILQ_ENTRY(linker_file) loaded; /* preload dependency support */
+
+ /* Function Boundary Tracing (FBT) fields. */
+ int fbt_nentries; /* number of fbt entries created. */
};
/*
@@ -169,6 +174,12 @@
int linker_file_listall(int (*)(linker_file_t,void *),void *);
/*
+ * List all functions in a file.
+ */
+int linker_file_function_listall(linker_file_t, int (*)(linker_file_t,
+ linker_symval_t *, void *), void *);
+
+/*
* This routine is responsible for finding dependencies of userland
* initiated kldload(2)'s of files.
*/
More information about the p4-projects
mailing list