PERFORCE change 138562 for review
John Birrell
jb at FreeBSD.org
Tue Mar 25 22:12:02 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=138562
Change 138562 by jb at 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 <sys/sysctl.h>
#include <string.h>
#endif
+#if defined(__i386__)
+#include <ieeefp.h>
+#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 <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sx.h>
#include <sys/dtrace_bsd.h>
#include <netinet/in.h>
#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 <sys/param.h>
#include <sys/systm.h>
@@ -59,6 +60,7 @@
#include <sys/turnstile.h>
#include <sys/vmmeter.h>
#include <sys/lock_profile.h>
+#include <sys/lockstat.h>
#include <machine/atomic.h>
#include <machine/bus.h>
@@ -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 <sys/param.h>
#include <sys/ktr.h>
#include <sys/lock.h>
+#include <sys/lockstat.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
@@ -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 <sys/cdefs.h>
__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) <<<
More information about the p4-projects
mailing list