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