Date: Mon, 22 May 2006 20:15:31 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 97634 for review Message-ID: <200605222015.k4MKFVIH004583@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=97634 Change 97634 by jb@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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605222015.k4MKFVIH004583>