From owner-p4-projects@FreeBSD.ORG Tue Mar 25 22:12:02 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 0921E1065670; Tue, 25 Mar 2008 22:12:02 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A1E49106564A for ; Tue, 25 Mar 2008 22:12:01 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 7AD4C8FC16 for ; Tue, 25 Mar 2008 22:12:01 +0000 (UTC) (envelope-from jb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m2PMC1Ua015022 for ; Tue, 25 Mar 2008 22:12:01 GMT (envelope-from jb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m2PMBxks015016 for perforce@freebsd.org; Tue, 25 Mar 2008 22:11:59 GMT (envelope-from jb@freebsd.org) Date: Tue, 25 Mar 2008 22:11:59 GMT Message-Id: <200803252211.m2PMBxks015016@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 138562 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: Tue, 25 Mar 2008 22:12:02 -0000 http://perforce.freebsd.org/chv.cgi?CH=138562 Change 138562 by jb@jb_freebsd1 on 2008/03/25 22:11:34 Implement the lockstat provider for FreeBSD. Submitted by: stacey _ son dot org Affected files ... .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/dtrace.c#17 edit .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d#5 edit .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d#5 edit .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d#5 edit .. //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d#5 edit .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_link.c#16 edit .. //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#29 edit .. //depot/projects/dtrace/src/sys/cddl/dev/lockstat/lockstat.c#1 add .. //depot/projects/dtrace/src/sys/conf/files#78 edit .. //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/dtrace/dtrace.c#45 edit .. //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/sys/dtrace.h#35 edit .. //depot/projects/dtrace/src/sys/kern/kern_lockstat.c#1 add .. //depot/projects/dtrace/src/sys/kern/kern_mutex.c#19 edit .. //depot/projects/dtrace/src/sys/kern/kern_rwlock.c#15 edit .. //depot/projects/dtrace/src/sys/kern/kern_sx.c#13 edit .. //depot/projects/dtrace/src/sys/modules/dtrace/Makefile#26 edit .. //depot/projects/dtrace/src/sys/modules/dtrace/Makefile.inc#7 edit .. //depot/projects/dtrace/src/sys/modules/dtrace/dtraceall/dtraceall.c#7 edit .. //depot/projects/dtrace/src/sys/modules/dtrace/lockstat/Makefile#1 add .. //depot/projects/dtrace/src/sys/sys/lockstat.h#1 add .. //depot/projects/dtrace/src/sys/sys/mutex.h#10 edit .. //depot/projects/dtrace/src/sys/sys/rwlock.h#9 edit .. //depot/projects/dtrace/src/sys/sys/sx.h#8 edit .. //depot/projects/dtrace/src/tools/test/dtrace/Makefile#29 edit Differences ... ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/dtrace.c#17 (text) ==== @@ -1373,8 +1373,14 @@ dtrace_errmsg(NULL, err)); } +#if defined(__i386__) + /* XXX The 32-bit seems to need more buffer space by default -sson */ + (void) dtrace_setopt(g_dtp, "bufsize", "12m"); + (void) dtrace_setopt(g_dtp, "aggsize", "12m"); +#else (void) dtrace_setopt(g_dtp, "bufsize", "4m"); (void) dtrace_setopt(g_dtp, "aggsize", "4m"); +#endif /* * If -G is specified, enable -xlink=dynamic and -xunodefs to permit ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owned.d#5 (text+ko) ==== @@ -38,8 +38,8 @@ lockstat:::adaptive-acquire { - this->owned = mutex_owned((kmutex_t *)arg0); - this->owner = mutex_owner((kmutex_t *)arg0); + this->owned = mutex_owned((struct mtx *)arg0); + this->owner = mutex_owner((struct mtx *)arg0); } lockstat:::adaptive-acquire ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_owner.d#5 (text+ko) ==== @@ -41,17 +41,17 @@ #pragma D option quiet -kthread_t *ptr; +struct thread *ptr; BEGIN { i = 0; } -lockstat:genunix:mutex_enter:adaptive-acquire +lockstat::mtx_lock:adaptive-acquire { - ptr = mutex_owner((kmutex_t *)arg0); + ptr = mutex_owner((struct mtx *)arg0); i++; } ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/funcs/tst.mutex_type_adaptive.d#5 (text+ko) ==== @@ -44,9 +44,9 @@ ret = -99; } -mutex_enter:adaptive-acquire +mtx_lock:adaptive-acquire { - ret = mutex_type_adaptive((kmutex_t *)arg0); + ret = mutex_type_adaptive((struct mtx *)arg0); i++; } ==== //depot/projects/dtrace/src/contrib/opensolaris/cmd/dtrace/test/tst/common/safety/tst.rw.d#5 (text+ko) ==== @@ -38,22 +38,22 @@ fbt::: /on/ { - @[rw_read_held((krwlock_t *)&`clock)] = count(); - @[rw_read_held((krwlock_t *)rand())] = count(); + @[rw_read_held((struct rwlock *)&`unp_global_rwlock)] = count(); + @[rw_read_held((struct rwlock *)rand())] = count(); } fbt::: /on/ { - @[rw_write_held((krwlock_t *)&`clock)] = count(); - @[rw_write_held((krwlock_t *)rand())] = count(); + @[rw_write_held((struct rwlock *)&`unp_global_rwlock)] = count(); + @[rw_write_held((struct rwlock *)rand())] = count(); } fbt::: /on/ { - @[rw_iswriter((krwlock_t *)&`clock)] = count(); - @[rw_iswriter((krwlock_t *)rand())] = count(); + @[rw_iswriter((struct rwlock *)&`unp_global_rwlock)] = count(); + @[rw_iswriter((struct rwlock *)rand())] = count(); } tick-1sec ==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_link.c#16 (text) ==== @@ -1712,8 +1712,12 @@ * Arches which are 32-bit only just use the normal * library path. */ +#if defined(__i386__) + int use_32 = 1; /* use /usr/lib/... -sson */ +#else int use_32 = 0; #endif +#endif (void) snprintf(drti, sizeof (drti), "/usr/lib%s/dtrace/drti.o", use_32 ? "":"32"); ==== //depot/projects/dtrace/src/contrib/opensolaris/lib/libdtrace/common/dt_open.c#29 (text) ==== @@ -60,6 +60,9 @@ #include #include #endif +#if defined(__i386__) +#include +#endif /* * Stability and versioning definitions. These #defines are used in the tables @@ -133,6 +136,10 @@ */ #if !defined(sun) static char curthread_str[MAXPATHLEN]; +static char intmtx_str[MAXPATHLEN]; +static char threadmtx_str[MAXPATHLEN]; +static char rwlock_str[MAXPATHLEN]; +static char sxlock_str[MAXPATHLEN]; #endif /* @@ -273,8 +280,10 @@ DT_VERS_1_5, &dt_idops_func, "string(int, void *)" }, { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint_t" }, +#if defined(sun) { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, +#endif { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "string(int64_t)" }, { "lquantize", DT_IDENT_AGGFUNC, 0, DTRACEAGG_LQUANTIZE, @@ -294,6 +303,7 @@ { "msgsize", DT_IDENT_FUNC, 0, DIF_SUBR_MSGSIZE, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "size_t(mblk_t *)" }, +#if defined(sun) { "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED, DT_ATTR_EVOLCMN, DT_VERS_1_0, &dt_idops_func, "int(genunix`kmutex_t *)" }, @@ -306,6 +316,20 @@ { "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN, DT_ATTR_EVOLCMN, DT_VERS_1_0, &dt_idops_func, "int(genunix`kmutex_t *)" }, +#else +{ "mutex_owned", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNED, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, intmtx_str }, +{ "mutex_owner", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_OWNER, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, threadmtx_str }, +{ "mutex_type_adaptive", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_ADAPTIVE, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, intmtx_str }, +{ "mutex_type_spin", DT_IDENT_FUNC, 0, DIF_SUBR_MUTEX_TYPE_SPIN, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, intmtx_str }, +#endif { "ntohl", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHL, DT_ATTR_EVOLCMN, DT_VERS_1_3, &dt_idops_func, "uint32_t(uint32_t)" }, { "ntohll", DT_IDENT_FUNC, 0, DIF_SUBR_NTOHLL, DT_ATTR_EVOLCMN, DT_VERS_1_3, @@ -348,6 +372,7 @@ &dt_idops_func, "int()" }, { "rindex", DT_IDENT_FUNC, 0, DIF_SUBR_RINDEX, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "int(const char *, const char *, [int])" }, +#if defined(sun) { "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER, DT_ATTR_EVOLCMN, DT_VERS_1_0, &dt_idops_func, "int(genunix`krwlock_t *)" }, @@ -357,6 +382,17 @@ { "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD, DT_ATTR_EVOLCMN, DT_VERS_1_0, &dt_idops_func, "int(genunix`krwlock_t *)" }, +#else +{ "rw_iswriter", DT_IDENT_FUNC, 0, DIF_SUBR_RW_ISWRITER, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, rwlock_str }, +{ "rw_read_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_READ_HELD, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, rwlock_str }, +{ "rw_write_held", DT_IDENT_FUNC, 0, DIF_SUBR_RW_WRITE_HELD, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, rwlock_str }, +#endif { "self", DT_IDENT_PTR, 0, 0, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "void" }, { "setopt", DT_IDENT_ACTFUNC, 0, DT_ACT_SETOPT, DT_ATTR_STABCMN, @@ -392,6 +428,17 @@ &dt_idops_func, "string(const char *, int, [int])" }, { "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "void(@)" }, +#if !defined(sun) +{ "sx_isexclusive", DT_IDENT_FUNC, 0, DIF_SUBR_SX_ISEXCLUSIVE, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, sxlock_str }, +{ "sx_shared_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_SHARED_HELD, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, sxlock_str }, +{ "sx_exclusive_held", DT_IDENT_FUNC, 0, DIF_SUBR_SX_EXCLUSIVE_HELD, + DT_ATTR_EVOLCMN, DT_VERS_1_0, + &dt_idops_func, sxlock_str }, +#endif { "sym", DT_IDENT_ACTFUNC, 0, DT_ACT_SYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_symaddr(uintptr_t)" }, { "system", DT_IDENT_ACTFUNC, 0, DT_ACT_SYSTEM, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -412,14 +459,17 @@ DT_VERS_1_0, &dt_idops_func, "void(...)" }, { "typeref", DT_IDENT_FUNC, 0, DIF_SUBR_TYPEREF, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "uintptr_t *(void *, size_t, string, size_t)" }, +#if defined(sun) { "uaddr", DT_IDENT_ACTFUNC, 0, DT_ACT_UADDR, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, { "ucaller", DT_IDENT_SCALAR, 0, DIF_VAR_UCALLER, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_type, "uint64_t" }, { "ufunc", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "uid", DT_IDENT_SCALAR, 0, DIF_VAR_UID, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uid_t" }, +#if defined(sun) { "umod", DT_IDENT_ACTFUNC, 0, DT_ACT_UMOD, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, { "uregs", DT_IDENT_ARRAY, 0, DIF_VAR_UREGS, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -431,14 +481,17 @@ &dt_idops_type, "uint32_t" }, { "usym", DT_IDENT_ACTFUNC, 0, DT_ACT_USYM, DT_ATTR_STABCMN, DT_VERS_1_2, &dt_idops_func, "_usymaddr(uintptr_t)" }, +#endif { "vtimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_VTIMESTAMP, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint64_t" }, { "walltimestamp", DT_IDENT_SCALAR, 0, DIF_VAR_WALLTIMESTAMP, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "int64_t" }, +#if defined(sun) { "zonename", DT_IDENT_SCALAR, 0, DIF_VAR_ZONENAME, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "string" }, +#endif { NULL, 0, 0, 0, { 0, 0, 0 }, 0, NULL, NULL } }; @@ -730,6 +783,10 @@ break; } #endif +#if defined(__i386__) + /* make long doubles 64 bits -sson */ + (void) fpsetprec(FP_PE); +#endif } static dtrace_hdl_t * @@ -1185,6 +1242,10 @@ * Format the global variables based on the kernel module name. */ snprintf(curthread_str, sizeof(curthread_str), "%s`struct thread *",p); + snprintf(intmtx_str, sizeof(intmtx_str), "int(%s`struct mtx *)",p); + snprintf(threadmtx_str, sizeof(threadmtx_str), "struct thread *(%s`struct mtx *)",p); + snprintf(rwlock_str, sizeof(rwlock_str), "int(%s`struct rwlock *)",p); + snprintf(sxlock_str, sizeof(sxlock_str), "int(%s`struct sxlock *)",p); } #endif ==== //depot/projects/dtrace/src/sys/conf/files#78 (text+ko) ==== @@ -1466,6 +1466,7 @@ kern/kern_linker.c standard kern/kern_lock.c standard kern/kern_lockf.c standard +kern/kern_lockstat.c optional kdtrace_hooks kern/kern_malloc.c standard kern/kern_mbuf.c standard kern/kern_mib.c standard ==== //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/dtrace/dtrace.c#45 (text) ==== @@ -117,6 +117,9 @@ #include #include #include +#include +#include +#include #include #include #include "dtrace_cddl.h" @@ -2832,6 +2835,7 @@ } return (mstate->dtms_stackdepth); +#if defined(sun) case DIF_VAR_USTACKDEPTH: if (!dtrace_priv_proc(state)) return (0); @@ -2851,6 +2855,7 @@ mstate->dtms_present |= DTRACE_MSTATE_USTACKDEPTH; } return (mstate->dtms_ustackdepth); +#endif case DIF_VAR_CALLER: if (!dtrace_priv_kernel(state)) @@ -2887,6 +2892,7 @@ } return (mstate->dtms_caller); +#if defined(sun) case DIF_VAR_UCALLER: if (!dtrace_priv_proc(state)) return (0); @@ -2910,6 +2916,7 @@ } return (mstate->dtms_ucaller); +#endif case DIF_VAR_PROBEPROV: ASSERT(mstate->dtms_present & DTRACE_MSTATE_PROBE); @@ -3154,6 +3161,15 @@ krwlock_t ri; uintptr_t rw; } r; +#else + union { + struct mtx *mi; + uintptr_t mx; + } m; + union { + struct sx *si; + uintptr_t sx; + } s; #endif switch (subr) { @@ -3163,7 +3179,6 @@ #if defined(sun) case DIF_SUBR_MUTEX_OWNED: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { regs[rd] = 0; @@ -3178,7 +3193,6 @@ break; case DIF_SUBR_MUTEX_OWNER: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { regs[rd] = 0; @@ -3194,7 +3208,6 @@ break; case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { regs[rd] = 0; @@ -3206,7 +3219,6 @@ break; case DIF_SUBR_MUTEX_TYPE_SPIN: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (kmutex_t), mstate, vstate)) { regs[rd] = 0; @@ -3218,7 +3230,6 @@ break; case DIF_SUBR_RW_READ_HELD: { - union { uintptr_t tmp; if (!dtrace_canload(tupregs[0].dttk_value, sizeof (uintptr_t), @@ -3233,7 +3244,6 @@ } case DIF_SUBR_RW_WRITE_HELD: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { regs[rd] = 0; @@ -3245,7 +3255,6 @@ break; case DIF_SUBR_RW_ISWRITER: - union { if (!dtrace_canload(tupregs[0].dttk_value, sizeof (krwlock_t), mstate, vstate)) { regs[rd] = 0; @@ -3255,7 +3264,77 @@ r.rw = dtrace_loadptr(tupregs[0].dttk_value); regs[rd] = _RW_ISWRITER(&r.ri); break; -#endif + +#else + /* + * XXX - The following code works because mutex, rwlocks, & sxlocks + * all have similar data structures in FreeBSD. This may not be + * good if someone changes one of the lock data structures. + * Ideally, it would be nice if all these shared a common lock + * object. + */ + case DIF_SUBR_MUTEX_OWNED: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = !(m.mi->mtx_lock & MTX_UNOWNED); + } else { + regs[rd] = !(m.mi->mtx_lock & SX_UNLOCKED); + } + break; + + case DIF_SUBR_MUTEX_OWNER: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + if (LO_CLASSINDEX(&(m.mi->lock_object)) < 2) { + regs[rd] = m.mi->mtx_lock & ~MTX_FLAGMASK; + } else { + if (!(m.mi->mtx_lock & SX_LOCK_SHARED)) + regs[rd] = SX_OWNER(m.mi->mtx_lock); + else + regs[rd] = 0; + } + break; + + case DIF_SUBR_MUTEX_TYPE_ADAPTIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) != 0); + break; + + case DIF_SUBR_MUTEX_TYPE_SPIN: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + m.mx = tupregs[0].dttk_value; + + regs[rd] = (LO_CLASSINDEX(&(m.mi->lock_object)) == 0); + break; + + case DIF_SUBR_RW_READ_HELD: + case DIF_SUBR_SX_SHARED_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_SHARED) && + (SX_OWNER(s.si->sx_lock) >> SX_SHARERS_SHIFT) != 0); + break; + + case DIF_SUBR_RW_WRITE_HELD: + case DIF_SUBR_SX_EXCLUSIVE_HELD: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = (SX_OWNER(s.si->sx_lock) == (uintptr_t) curthread); + break; + + case DIF_SUBR_RW_ISWRITER: + case DIF_SUBR_SX_ISEXCLUSIVE: + /* XXX - need to use dtrace_canload() and dtrace_loadptr() */ + s.sx = tupregs[0].dttk_value; + regs[rd] = ((s.si->sx_lock & SX_LOCK_EXCLUSIVE_WAITERS) || + !(s.si->sx_lock & SX_LOCK_SHARED)); + break; +#endif /* ! defined(sun) */ case DIF_SUBR_BCOPY: { /* @@ -5641,12 +5720,11 @@ cpu->cpu_dtrace_chilled += val; } +#if defined(sun) static void dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state, uint64_t *buf, uint64_t arg) { - printf("%s(%d): unimplemented.\n",__func__,__LINE__); -#if defined(sun) int nframes = DTRACE_USTACK_NFRAMES(arg); int strsize = DTRACE_USTACK_STRSIZE(arg); uint64_t *pcs = &buf[1], *fps; @@ -5754,8 +5832,8 @@ out: mstate->dtms_scratch_ptr = old; +} #endif -} /* * If you're looking for the epicenter of DTrace, you just found it. This @@ -6078,6 +6156,7 @@ (uint32_t *)arg0); continue; +#if defined(sun) case DTRACEACT_JSTACK: case DTRACEACT_USTACK: if (!dtrace_priv_proc(state)) @@ -6119,6 +6198,7 @@ DTRACE_USTACK_NFRAMES(rec->dtrd_arg) + 1); DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT); continue; +#endif default: break; ==== //depot/projects/dtrace/src/sys/contrib/opensolaris/uts/common/sys/dtrace.h#35 (text) ==== @@ -297,8 +297,11 @@ #define DIF_SUBR_INET_NTOA6 43 #define DIF_SUBR_MEMREF 44 #define DIF_SUBR_TYPEREF 45 +#define DIF_SUBR_SX_SHARED_HELD 46 +#define DIF_SUBR_SX_EXCLUSIVE_HELD 47 +#define DIF_SUBR_SX_ISEXCLUSIVE 48 -#define DIF_SUBR_MAX 45 /* max subroutine value */ +#define DIF_SUBR_MAX 48 /* max subroutine value */ typedef uint32_t dif_instr_t; ==== //depot/projects/dtrace/src/sys/kern/kern_mutex.c#19 (text+ko) ==== @@ -40,6 +40,7 @@ #include "opt_ddb.h" #include "opt_global.h" #include "opt_sched.h" +#include "opt_kdtrace.h" #include #include @@ -59,6 +60,7 @@ #include #include #include +#include #include #include @@ -201,8 +203,10 @@ line); mtx_assert(m, MA_OWNED); - if (m->mtx_recurse == 0) + if (m->mtx_recurse == 0) { lock_profile_release_lock(&m->lock_object); + LOCKSTAT_RECORD0(LS_MTX_UNLOCK_RELEASE, m); + } _rel_sleep_lock(m, curthread, opts, file, line); } @@ -276,10 +280,11 @@ WITNESS_LOCK(&m->lock_object, opts | LOP_EXCLUSIVE | LOP_TRYLOCK, file, line); curthread->td_locks++; - if (m->mtx_recurse == 0) + if (m->mtx_recurse == 0) { lock_profile_obtain_lock_success(&m->lock_object, contested, waittime, file, line); - + LOCKSTAT_RECORD0(LS_MTX_LOCK_ACQUIRE, m); + } } return (rval); @@ -305,6 +310,11 @@ int contested = 0; uint64_t waittime = 0; uintptr_t v; +#ifdef KDTRACE_HOOKS + uint64_t spin_cnt = 0; + uint64_t sleep_cnt = 0; + int64_t sleep_time = 0; +#endif if (mtx_owned(m)) { KASSERT((m->lock_object.lo_flags & LO_RECURSABLE) != 0, @@ -325,6 +335,9 @@ m->lock_object.lo_name, (void *)m->mtx_lock, file, line); while (!_obtain_lock(m, tid)) { +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif #ifdef ADAPTIVE_MUTEXES /* * If the owner is running on another CPU, spin until the @@ -339,8 +352,12 @@ "%s: spinning on %p held by %p", __func__, m, owner); while (mtx_owner(m) == owner && - TD_IS_RUNNING(owner)) + TD_IS_RUNNING(owner)) { cpu_spinwait(); +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif + } continue; } } @@ -405,7 +422,15 @@ /* * Block on the turnstile. */ +#ifdef KDTRACE_HOOKS + /* Record the time blocked */ + sleep_time -= lockstat_nsecs(); +#endif turnstile_wait(ts, mtx_owner(m), TS_EXCLUSIVE_QUEUE); +#ifdef KDTRACE_HOOKS + sleep_time += lockstat_nsecs(); + sleep_cnt++; +#endif } #ifdef KTR if (cont_logged) { @@ -416,6 +441,15 @@ #endif lock_profile_obtain_lock_success(&m->lock_object, contested, waittime, file, line); +#ifdef KDTRACE_HOOKS + /* sleep_time is the total time blocked */ + if (sleep_time != 0) + LOCKSTAT_RECORD1(LS_MTX_LOCK_BLOCK, m, sleep_time); + /* record only the loops spinning and not sleeping */ + if (spin_cnt > sleep_cnt) + LOCKSTAT_RECORD1(LS_MTX_LOCK_SPIN, m, (spin_cnt - sleep_cnt)); + LOCKSTAT_RECORD0(LS_MTX_LOCK_ACQUIRE, m); +#endif } static void @@ -478,6 +512,8 @@ lock_profile_obtain_lock_success(&m->lock_object, contested, waittime, (file), (line)); + LOCKSTAT_RECORD1(LS_MTX_SPIN_LOCK_SPIN, m, i); + LOCKSTAT_RECORD0(LS_MTX_SPIN_LOCK_ACQUIRE, m); } #endif /* SMP */ @@ -488,6 +524,9 @@ uintptr_t tid; int i, contested; uint64_t waittime; +#ifdef KDTRACE_HOOKS + uint64_t spin_cnt = 0; +#endif contested = i = 0; waittime = 0; @@ -508,6 +547,9 @@ WITNESS_CHECKORDER(&m->lock_object, opts | LOP_NEWORDER | LOP_EXCLUSIVE, file, line); while (!_obtain_lock(m, tid)) { +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif if (m->mtx_lock == tid) { m->mtx_recurse++; break; ==== //depot/projects/dtrace/src/sys/kern/kern_rwlock.c#15 (text+ko) ==== @@ -36,10 +36,12 @@ #include "opt_ddb.h" #include "opt_no_adaptive_rwlocks.h" +#include "opt_kdtrace.h" #include #include #include +#include #include #include #include @@ -215,8 +217,10 @@ WITNESS_UNLOCK(&rw->lock_object, LOP_EXCLUSIVE, file, line); LOCK_LOG_LOCK("WUNLOCK", &rw->lock_object, 0, rw->rw_recurse, file, line); - if (!rw_recursed(rw)) + if (!rw_recursed(rw)) { lock_profile_release_lock(&rw->lock_object); + LOCKSTAT_RECORD0(LS_RW_WUNLOCK_RELEASE, rw); + } __rw_wunlock(rw, curthread, file, line); } /* @@ -241,6 +245,11 @@ uint64_t waittime = 0; int contested = 0; uintptr_t v; +#ifdef KDTRACE_HOOKS + uint64_t spin_cnt = 0; + uint64_t sleep_cnt = 0; + int64_t sleep_time = 0; +#endif KASSERT(rw->rw_lock != RW_DESTROYED, ("rw_rlock() of destroyed rwlock @ %s:%d", file, line)); @@ -250,6 +259,9 @@ WITNESS_CHECKORDER(&rw->lock_object, LOP_NEWORDER, file, line); for (;;) { +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif /* * Handle the easy case. If no other thread has a write * lock, then try to bump up the count of read locks. Note @@ -296,8 +308,12 @@ "%s: spinning on %p held by %p", __func__, rw, owner); while ((struct thread*)RW_OWNER(rw->rw_lock) == - owner && TD_IS_RUNNING(owner)) + owner && TD_IS_RUNNING(owner)) { cpu_spinwait(); +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif + } continue; } } @@ -367,7 +383,14 @@ if (LOCK_LOG_TEST(&rw->lock_object, 0)) CTR2(KTR_LOCK, "%s: %p blocking on turnstile", __func__, rw); +#ifdef KDTRACE_HOOKS + sleep_time -= lockstat_nsecs(); +#endif turnstile_wait(ts, rw_owner(rw), TS_SHARED_QUEUE); +#ifdef KDTRACE_HOOKS + sleep_time += lockstat_nsecs(); + sleep_cnt++; +#endif if (LOCK_LOG_TEST(&rw->lock_object, 0)) CTR2(KTR_LOCK, "%s: %p resuming from turnstile", __func__, rw); @@ -384,6 +407,15 @@ WITNESS_LOCK(&rw->lock_object, 0, file, line); curthread->td_locks++; curthread->td_rw_rlocks++; +#ifdef KDTRACE_HOOKS + /* sleep_time is the total time blocked */ + if (sleep_time != 0) + LOCKSTAT_RECORD1(LS_RW_RLOCK_BLOCK, rw, sleep_time); + /* record only the loops spinning and not sleeping */ + if (spin_cnt > sleep_cnt) + LOCKSTAT_RECORD1(LS_RW_RLOCK_SPIN, rw, (spin_cnt - sleep_cnt)); + LOCKSTAT_RECORD0(LS_RW_RLOCK_ACQUIRE, rw); +#endif } void @@ -489,6 +521,7 @@ break; } lock_profile_release_lock(&rw->lock_object); + LOCKSTAT_RECORD0(LS_RW_RUNLOCK_RELEASE, rw); } /* @@ -508,6 +541,11 @@ uint64_t waittime = 0; uintptr_t v, x; int contested = 0; +#ifdef KDTRACE_HOOKS + uint64_t spin_cnt = 0; + uint64_t sleep_cnt = 0; + int64_t sleep_time = 0; +#endif if (rw_wlocked(rw)) { KASSERT(rw->lock_object.lo_flags & RW_RECURSE, @@ -524,6 +562,9 @@ rw->lock_object.lo_name, (void *)rw->rw_lock, file, line); while (!_rw_write_lock(rw, tid)) { +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif lock_profile_obtain_lock_failed(&rw->lock_object, &contested, &waittime); #ifdef ADAPTIVE_RWLOCKS @@ -539,8 +580,12 @@ CTR3(KTR_LOCK, "%s: spinning on %p held by %p", __func__, rw, owner); while ((struct thread*)RW_OWNER(rw->rw_lock) == owner && - TD_IS_RUNNING(owner)) + TD_IS_RUNNING(owner)) { cpu_spinwait(); +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif + } continue; } if ((v & RW_LOCK_READ) && RW_READERS(v) && spintries < 100) { @@ -557,6 +602,9 @@ break; cpu_spinwait(); } +#ifdef KDTRACE_HOOKS + spin_cnt += 100000 - i; +#endif if (i) continue; } @@ -619,7 +667,14 @@ if (LOCK_LOG_TEST(&rw->lock_object, 0)) CTR2(KTR_LOCK, "%s: %p blocking on turnstile", __func__, rw); +#ifdef KDTRACE_HOOKS + sleep_time -= lockstat_nsecs(); +#endif turnstile_wait(ts, rw_owner(rw), TS_EXCLUSIVE_QUEUE); +#ifdef KDTRACE_HOOKS + sleep_time += lockstat_nsecs(); + sleep_cnt++; +#endif if (LOCK_LOG_TEST(&rw->lock_object, 0)) CTR2(KTR_LOCK, "%s: %p resuming from turnstile", __func__, rw); @@ -629,6 +684,15 @@ } lock_profile_obtain_lock_success(&rw->lock_object, contested, waittime, file, line); +#ifdef KDTRACE_HOOKS + /* sleep_time is the total time blocked */ + if (sleep_time != 0) + LOCKSTAT_RECORD1(LS_RW_WLOCK_BLOCK, rw, sleep_time); + /* record only the loops spinning and not sleeping */ + if (spin_cnt > sleep_cnt) + LOCKSTAT_RECORD1(LS_RW_WLOCK_SPIN, rw, (spin_cnt - sleep_cnt)); + LOCKSTAT_RECORD0(LS_RW_WLOCK_ACQUIRE, rw); +#endif } /* @@ -762,6 +826,7 @@ curthread->td_rw_rlocks--; WITNESS_UPGRADE(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file, line); + LOCKSTAT_RECORD0(LS_RW_TRYUPGRADE_UPGRADE, rw); } return (success); } @@ -827,6 +892,7 @@ out: curthread->td_rw_rlocks++; LOCK_LOG_LOCK("WDOWNGRADE", &rw->lock_object, 0, 0, file, line); + LOCKSTAT_RECORD0(LS_RW_DOWNGRADE_DOWNGRADE, rw); } #ifdef INVARIANT_SUPPORT ==== //depot/projects/dtrace/src/sys/kern/kern_sx.c#13 (text+ko) ==== @@ -38,6 +38,7 @@ #include "opt_adaptive_sx.h" #include "opt_ddb.h" +#include "opt_kdtrace.h" #include __FBSDID("$FreeBSD: src/sys/kern/kern_sx.c,v 1.59 2008/03/12 06:31:06 jeff Exp $"); @@ -304,6 +305,7 @@ LOCK_LOG_LOCK("SUNLOCK", &sx->lock_object, 0, 0, file, line); __sx_sunlock(sx, file, line); lock_profile_release_lock(&sx->lock_object); + LOCKSTAT_RECORD0(LS_SX_SUNLOCK_RELEASE, sx); } void @@ -318,8 +320,10 @@ WITNESS_UNLOCK(&sx->lock_object, LOP_EXCLUSIVE, file, line); LOCK_LOG_LOCK("XUNLOCK", &sx->lock_object, 0, sx->sx_recurse, file, line); - if (!sx_recursed(sx)) + if (!sx_recursed(sx)) { lock_profile_release_lock(&sx->lock_object); + LOCKSTAT_RECORD0(LS_SX_XUNLOCK_RELEASE, sx); + } __sx_xunlock(sx, curthread, file, line); } @@ -347,9 +351,11 @@ success = atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1) | x, (uintptr_t)curthread | x); LOCK_LOG_TRY("XUPGRADE", &sx->lock_object, 0, success, file, line); - if (success) + if (success) { WITNESS_UPGRADE(&sx->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file, line); + LOCKSTAT_RECORD0(LS_SX_TRYUPGRADE_UPGRADE, sx); + } return (success); } @@ -409,6 +415,7 @@ sleepq_release(&sx->lock_object); LOCK_LOG_LOCK("XDOWNGRADE", &sx->lock_object, 0, 0, file, line); + LOCKSTAT_RECORD0(LS_SX_DOWNGRADE_DOWNGRADE, sx); } /* @@ -428,6 +435,11 @@ uint64_t waittime = 0; uintptr_t x; int contested = 0, error = 0; +#ifdef KDTRACE_HOOKS + uint64_t spin_cnt = 0; + uint64_t sleep_cnt = 0; + int64_t sleep_time = 0; +#endif /* If we already hold an exclusive lock, then recurse. */ if (sx_xlocked(sx)) { @@ -446,6 +458,9 @@ sx->lock_object.lo_name, (void *)sx->sx_lock, file, line); while (!atomic_cmpset_acq_ptr(&sx->sx_lock, SX_LOCK_UNLOCKED, tid)) { +#ifdef KDTRACE_HOOKS + spin_cnt++; +#endif lock_profile_obtain_lock_failed(&sx->lock_object, &contested, &waittime); #ifdef ADAPTIVE_SX @@ -466,8 +481,12 @@ __func__, sx, owner); GIANT_SAVE(); while (SX_OWNER(sx->sx_lock) == x && - TD_IS_RUNNING(owner)) + TD_IS_RUNNING(owner)) { >>> TRUNCATED FOR MAIL (1000 lines) <<<