From owner-p4-projects@FreeBSD.ORG Mon May 22 20:16:18 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 12AA416A789; Mon, 22 May 2006 20:16:17 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 29A7416A60A for ; Mon, 22 May 2006 20:16:15 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id CA59843D45 for ; Mon, 22 May 2006 20:16:14 +0000 (GMT) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k4MKFVod004587 for ; Mon, 22 May 2006 20:15:31 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k4MKFVIH004583 for perforce@freebsd.org; Mon, 22 May 2006 20:15:31 GMT (envelope-from jb@freebsd.org) Date: Mon, 22 May 2006 20:15:31 GMT Message-Id: <200605222015.k4MKFVIH004583@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jb@freebsd.org using -f From: John Birrell To: Perforce Change Reviews Cc: Subject: PERFORCE change 97634 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 May 2006 20:16:29 -0000 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 #include #include +#include #include #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. */