Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Feb 2012 11:18:34 +0000 (UTC)
From:      Alexander Leidinger <netchild@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r230910 - in user/netchild/linuxulator-dtrace/src/sys: amd64/conf amd64/linux32 compat/linux i386/conf i386/linux
Message-ID:  <201202021118.q12BIY5U035017@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: netchild
Date: Thu Feb  2 11:18:34 2012
New Revision: 230910
URL: http://svn.freebsd.org/changeset/base/230910

Log:
  Preliminary patch for DTracifying the linuxulator:
   - internal locks
   - linux_dummy.c
   - linux_futex.c
   - linux_emul.c
   - linux_mib.c
   - linux_sysctl.c
   - linux_util.c
   - linux_uid16.c
   - linux_time.c
   - D script to check internal locks
   - D script to trace futexes
   - D script to generate stats for DTracified linuxulator parts
   - D script to check for errors:
     + emulation errors (unsupportet stuff, unknown stuff, ...)
     + kernel errors (resource shortage, ...)
     + programming errors (errors which can happen, but should not happen)
  
  Not to be included in a MTC:
   - enabled DTRACE hooks and CTF compile in GENERIC
  
  Make sure the linuxulator is compiled in or loaded as a module before sdt.ko.
  You will get a panic if this is not respected (bug in dtrace-sdt to be
  fixed before MTC).

Added:
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_error.d   (contents, props changed)
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_internal_locks.d   (contents, props changed)
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_dtrace.h   (contents, props changed)
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/stats_timing.d   (contents, props changed)
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/trace_futexes.d   (contents, props changed)
Modified:
  user/netchild/linuxulator-dtrace/src/sys/amd64/conf/GENERIC
  user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h
  user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux32_dummy.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.h
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_fork.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_futex.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_mib.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_misc.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_sysctl.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_time.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_uid16.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_util.c
  user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_util.h
  user/netchild/linuxulator-dtrace/src/sys/i386/conf/GENERIC
  user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux.h
  user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux_dummy.c
  user/netchild/linuxulator-dtrace/src/sys/i386/linux/linux_sysvec.c

Modified: user/netchild/linuxulator-dtrace/src/sys/amd64/conf/GENERIC
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/amd64/conf/GENERIC	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/amd64/conf/GENERIC	Thu Feb  2 11:18:34 2012	(r230910)
@@ -22,6 +22,7 @@ cpu		HAMMER
 ident		GENERIC
 
 makeoptions	DEBUG=-g		# Build kernel with gdb(1) debug symbols
+makeoptions	WITH_CTF=yes		# Add CTF data for DTrace
 
 options 	SCHED_ULE		# ULE scheduler
 options 	PREEMPTION		# Enable kernel thread preemption
@@ -63,8 +64,8 @@ options 	AUDIT			# Security event auditi
 options 	CAPABILITY_MODE		# Capsicum capability mode
 options 	CAPABILITIES		# Capsicum capabilities
 options 	MAC			# TrustedBSD MAC Framework
-#options 	KDTRACE_FRAME		# Ensure frames are compiled in
-#options 	KDTRACE_HOOKS		# Kernel DTrace hooks
+options 	KDTRACE_FRAME		# Ensure frames are compiled in
+options 	KDTRACE_HOOKS		# Kernel DTrace hooks
 options 	INCLUDE_CONFIG_FILE     # Include this file in kernel
 
 # Debugging support.  Always need this:
@@ -73,6 +74,7 @@ options 	KDB			# Enable kernel debugger 
 #options 	KDB_TRACE		# Print a stack trace for a panic.
 # For full debugger support use this instead:
 options 	DDB			# Support DDB.
+options 	DDB_CTF			# Kernel ELF linker loads CTF data.
 options 	GDB			# Support remote GDB.
 options 	DEADLKRES		# Enable the deadlock resolver
 options 	INVARIANTS		# Enable calls of extra sanity checking

Modified: user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux.h	Thu Feb  2 11:18:34 2012	(r230910)
@@ -42,6 +42,7 @@ extern u_char linux_debug_map[];
 #define	ldebug(name)	isclr(linux_debug_map, LINUX_SYS_linux_ ## name)
 #define	ARGS(nm, fmt)	"linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid
 #define	LMSG(fmt)	"linux(%ld): "fmt"\n", (long)td->td_proc->p_pid
+#define	LINUX_DTRACE	linuxulator32
 
 #ifdef MALLOC_DECLARE
 MALLOC_DECLARE(M_LINUX);

Modified: user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux32_dummy.c
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux32_dummy.c	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/amd64/linux32/linux32_dummy.c	Thu Feb  2 11:18:34 2012	(r230910)
@@ -29,14 +29,23 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_compat.h"
+#include "opt_kdtrace.h"
+
 #include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/sdt.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
 
 #include <amd64/linux32/linux.h>
 #include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_dtrace.h>
 #include <compat/linux/linux_util.h>
 
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
 DUMMY(stime);
 DUMMY(olduname);
 DUMMY(syslog);

Added: user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_error.d
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_error.d	Thu Feb  2 11:18:34 2012	(r230910)
@@ -0,0 +1,144 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Report error conditions:
+ *  - emulation errors (unsupportet stuff, unknown stuff, ...)
+ *  - kernel errors (resource shortage, ...)
+ *  - programming errors (errors which can happen, but should not happen)
+ */
+
+linuxulator*:dummy::not_implemented,
+linuxulator*:emul:proc_exit:child_clear_tid_error,
+linuxulator*:emul:proc_exit:futex_failed,
+linuxulator*:emul:linux_schedtail:copyout_error,
+linuxulator*:futex:futex_get:error,
+linuxulator*:futex:futex_sleep:requeue_error,
+linuxulator*:futex:futex_sleep:sleep_error,
+linuxulator*:futex:futex_wait:copyin_error,
+linuxulator*:futex:futex_wait:itimerfix_error,
+linuxulator*:futex:futex_wait:sleep_error,
+linuxulator*:futex:futex_atomic_op:missing_access_check,
+linuxulator*:futex:futex_atomic_op:unimplemented_op,
+linuxulator*:futex:futex_atomic_op:unimplemented_cmp,
+linuxulator*:futex:linux_sys_futex:unimplemented_clockswitch,
+linuxulator*:futex:linux_sys_futex:copyin_error,
+linuxulator*:futex:linux_sys_futex:unhandled_efault,
+linuxulator*:futex:linux_sys_futex:unimplemented_lock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_unlock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_trylock_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_wait_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unimplemented_cmp_requeue_pi,
+linuxulator*:futex:linux_sys_futex:unknown_operation,
+linuxulator*:futex:linux_get_robust_list:copyout_error,
+linuxulator*:futex:handle_futex_death:copyin_error,
+linuxulator*:futex:fetch_robust_entry:copyin_error,
+linuxulator*:futex:release_futexes:copyin_error,
+linuxulator*:time:linux_clock_gettime:conversion_error,
+linuxulator*:time:linux_clock_gettime:gettime_error,
+linuxulator*:time:linux_clock_gettime:copyout_error,
+linuxulator*:time:linux_clock_settime:conversion_error,
+linuxulator*:time:linux_clock_settime:settime_error,
+linuxulator*:time:linux_clock_settime:copyin_error,
+linuxulator*:time:linux_clock_getres:conversion_error,
+linuxulator*:time:linux_clock_getres:getres_error,
+linuxulator*:time:linux_clock_getres:copyout_error,
+linuxulator*:time:linux_nanosleep:conversion_error,
+linuxulator*:time:linux_nanosleep:nanosleep_error,
+linuxulator*:time:linux_nanosleep:copyout_error,
+linuxulator*:time:linux_nanosleep:copyin_error,
+linuxulator*:time:linux_clock_nanosleep:copyin_error,
+linuxulator*:time:linux_clock_nanosleep:conversion_error,
+linuxulator*:time:linux_clock_nanosleep:copyout_error,
+linuxulator*:time:linux_clock_nanosleep:nanosleep_error,
+linuxulator*:sysctl:handle_string:copyout_error,
+linuxulator*:sysctl:linux_sysctl:copyin_error,
+linuxulator*:mib:linux_sysctl_osname:sysctl_string_error,
+linuxulator*:mib:linux_sysctl_osrelease:sysctl_string_error,
+linuxulator*:mib:linux_sysctl_oss_version:sysctl_string_error,
+linuxulator*:mib:linux_prison_create:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_check:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_check:vfs_getopt_error,
+linuxulator*:mib:linux_prison_set:vfs_copyopt_error,
+linuxulator*:mib:linux_prison_set:vfs_getopt_error,
+linuxulator*:mib:linux_prison_get:vfs_setopt_error,
+linuxulator*:mib:linux_prison_get:vfs_setopts_error
+{
+	printf("ERROR: %s in %s:%s:%s\n", probename, probeprov, probemod, probefunc);
+	stack();
+	ustack();
+}
+
+linuxulator*:util:linux_driver_get_name_dev:nullcall,
+linuxulator*:util:linux_driver_get_major_minor:nullcall,
+linuxulator*:futex:linux_sys_futex:invalid_cmp_requeue_use,
+linuxulator*:futex:linux_sys_futex:deprecated_requeue,
+linuxulator*:futex:linux_set_robust_list:size_error,
+linuxulator*:time:linux_clock_getres:nullcall
+{
+	printf("WARNING: %s:%s:%s:%s in application %s, maybe an application error?\n", probename, probeprov, probemod, probefunc, execname);
+	stack();
+	ustack();
+}
+
+linuxulator*:util:linux_driver_get_major_minor:notfound
+{
+	printf("WARNING: Application %s failed to find %s in %s:%s:%s, this may or may not be a problem.\n", execname, stringof(args[0]), probename, probeprov, probemod);
+	stack();
+	ustack();
+}
+
+linuxulator*:time:linux_to_native_clockid:unknown_clockid
+{
+	printf("INFO: Application %s tried to use unknown clockid %d. Please report this to freebsd-emulation@FreeBSD.org.\n", execname, arg0);
+}
+
+linuxulator*:time:linux_to_native_clockid:unsupported_clockid,
+linuxulator*:time:linux_clock_nanosleep:unsupported_clockid
+{
+	printf("WARNING: Application %s tried to use unsupported clockid (%d), this may or may not be a problem for the application.\nPatches to support this clockid are welcome on the freebsd-emulation@FreeBSD.org mailinglist.\n", execname, arg0);
+}
+
+linuxulator*:time:linux_clock_nanosleep:unsupported_flags
+{
+	printf("WARNING: Application %s tried to use unsupported flags (%d), this may or may not be a problem for the application.\nPatches to support those flags are welcome on the freebsd-emulation@FreeBSD.org mailinglist.\n", execname, arg0);
+}
+
+linuxulator*:sysctl:linux_sysctl:wrong_length
+{
+	printf("ERROR: Application %s issued a sysctl which failed the length restrictions.\nThe length passed is %d, the min length supported is 1 and the max length supported is %d.\n", execname, arg0, arg1);
+	stack();
+	ustack();
+}
+
+linuxulator*:sysctl:linux_sysctl:unsupported_sysctl
+{
+	printf("ERROR: Application %s issued an unsupported sysctl (%s).\nPatches to support this sysctl are welcome on the freebsd-emulation@FreeBSD.org mailinglist.\n", execname, stringof(args[0]));
+}

Added: user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_internal_locks.d
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/check_internal_locks.d	Thu Feb  2 11:18:34 2012	(r230910)
@@ -0,0 +1,132 @@
+#!/usr/sbin/dtrace -qs
+
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/**
+ * Check if the internal locks are correctly acquired/released:
+ *  - no recursive locking (mtx locks, write locks)
+ *  - no unlocking of already unlocked one
+ *
+ * Print stacktrace if a lock is longer locked than about 10sec or more.
+ */
+
+#pragma D option dynvarsize=32m
+#pragma D option specsize=32m
+
+BEGIN
+{
+	check["emul_lock"] = 0;
+	check["emul_shared_rlock"] = 0;
+	check["emul_shared_wlock"] = 0;
+	check["futex_mtx"] = 0;
+}
+
+linuxulator*:locks:emul_lock:locked,
+linuxulator*:locks:emul_shared_wlock:locked,
+linuxulator*:locks:futex_mtx:locked
+/check[probefunc] > 0/
+{
+	printf("ERROR: recursive lock of %s (%p),", probefunc, arg0);
+	printf("       or missing SDT probe in kernel. Stack trace follows:");
+	stack();
+}
+
+linuxulator*:locks:emul_lock:locked,
+linuxulator*:locks:emul_shared_rlock:locked,
+linuxulator*:locks:emul_shared_wlock:locked,
+linuxulator*:locks:futex_mtx:locked
+{
+	++check[probefunc];
+	@stats[probefunc] = count();
+
+	ts[probefunc] = timestamp;
+	spec[probefunc] = speculation();
+}
+
+linuxulator*:locks:emul_lock:unlock,
+linuxulator*:locks:emul_shared_rlock:unlock,
+linuxulator*:locks:emul_shared_wlock:unlock,
+linuxulator*:locks:futex_mtx:unlock
+/check[probefunc] == 0/
+{
+	printf("ERROR: unlock attemt of unlocked %s (%p),", probefunc, arg0);
+	printf("       missing SDT probe in kernel, or dtrace program started");
+	printf("       while the %s was already held (race condition).", probefunc);
+	printf("       Stack trace follows:");
+	stack();
+}
+
+linuxulator*:locks:emul_lock:unlock,
+linuxulator*:locks:emul_shared_rlock:unlock,
+linuxulator*:locks:emul_shared_wlock:unlock,
+linuxulator*:locks:futex_mtx:unlock
+{
+	discard(spec[probefunc]);
+	spec[probefunc] = 0;
+	--check[probefunc];
+}
+
+/* Timeout handling */
+
+tick-10s
+/spec["emul_lock"] != 0 && timestamp - ts["emul_lock"] >= 9999999000/
+{
+	commit(spec["emul_lock"]);
+	spec["emul_lock"] = 0;
+}
+
+tick-10s
+/spec["emul_shared_wlock"] != 0 && timestamp - ts["emul_shared_wlock"] >= 9999999000/
+{
+	commit(spec["emul_shared_wlock"]);
+	spec["emul_shared_wlock"] = 0;
+}
+
+tick-10s
+/spec["emul_shared_rlock"] != 0 && timestamp - ts["emul_shared_rlock"] >= 9999999000/
+{
+	commit(spec["emul_shared_rlock"]);
+	spec["emul_shared_rlock"] = 0;
+}
+
+tick-10s
+/spec["futex_mtx"] != 0 && timestamp - ts["futex_mtx"] >= 9999999000/
+{
+	commit(spec["futex_mtx"]);
+	spec["futex_mtx"] = 0;
+}
+
+
+/* Statistics */
+
+END
+{
+        printf("Number of locks per type:");
+	printa(@stats);
+}

Added: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_dtrace.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_dtrace.h	Thu Feb  2 11:18:34 2012	(r230910)
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2008-2012 Alexander Leidinger <netchild@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _LINUX_DTRACE_H_
+#define _LINUX_DTRACE_H_
+
+/**
+ * DTrace support macros for the linuxulator.
+ *
+ * Some wrapper macros to make it more easy to handle the linuxulator
+ * providers and to allow to make the name depend upon the bitsize.
+ *
+ * Basically this is the same as the normal SDT macros in sys/sdt.h. The
+ * difference is that the provider name is automatically inserted, and
+ * we do not use a different name for the probe-description.
+ */
+
+#define	LIN_SDT_PROVIDER_DEFINE(x)	SDT_PROVIDER_DEFINE(x)
+#define LIN_SDT_PROVIDER_DECLARE(x)	SDT_PROVIDER_DECLARE(x)
+
+#define	_LIN_SDT_PROBE_DECLARE(a, b, c, d)	SDT_PROBE_DECLARE(a, b, c, d)
+#define	LIN_SDT_PROBE_DECLARE(a, b, c)		_LIN_SDT_PROBE_DECLARE( \
+    LINUX_DTRACE, a, b, c)
+
+#define	_LIN_SDT_PROBE_DEFINE0(a, b, c, d)		SDT_PROBE_DEFINE(a, \
+    b, c, d, d)
+#define	LIN_SDT_PROBE_DEFINE0(a, b, c)			_LIN_SDT_PROBE_DEFINE0(\
+    LINUX_DTRACE, a, b, c)
+#define	_LIN_SDT_PROBE_DEFINE1(a, b, c, d, e)		SDT_PROBE_DEFINE1(a, \
+    b, c, d, d, e)
+#define	LIN_SDT_PROBE_DEFINE1(a, b, c, d)		_LIN_SDT_PROBE_DEFINE1(\
+    LINUX_DTRACE, a, b, c, d)
+#define	_LIN_SDT_PROBE_DEFINE2(a, b, c, d, e, f)	SDT_PROBE_DEFINE2(a, \
+    b, c, d, d, e, f)
+#define	LIN_SDT_PROBE_DEFINE2(a, b, c, d, e)		_LIN_SDT_PROBE_DEFINE2(\
+    LINUX_DTRACE, a, b, c, d, e)
+#define	_LIN_SDT_PROBE_DEFINE3(a, b, c, d, e, f, g)	SDT_PROBE_DEFINE3(a, \
+    b, c, d, d, e, f, g)
+#define	LIN_SDT_PROBE_DEFINE3(a, b, c, d, e, f)		_LIN_SDT_PROBE_DEFINE3(\
+    LINUX_DTRACE, a, b, c, d, e, f)
+#define	_LIN_SDT_PROBE_DEFINE4(a, b, c, d, e, f, g, h)	SDT_PROBE_DEFINE4(a, \
+    b, c, d, d, e, f, g, h)
+#define	LIN_SDT_PROBE_DEFINE4(a, b, c, d, e, f, g)	_LIN_SDT_PROBE_DEFINE4(\
+    LINUX_DTRACE, a, b, c, d, e, f, g)
+#define	_LIN_SDT_PROBE_DEFINE5(a, b, c, d, e, f, g, h, i) \
+    SDT_PROBE_DEFINE5(a, b, c, d, d, e, f, g, h, i)
+#define	LIN_SDT_PROBE_DEFINE5(a, b, c, d, e, f, g, h)	_LIN_SDT_PROBE_DEFINE5(\
+    LINUX_DTRACE, a, b, c, d, e, f, g, h)
+
+#define	_LIN_SDT_PROBE_ARGTYPE(a, b, c, d, e, f)	SDT_PROBE_ARGTYPE(a, b,\
+    c, d, e, f)
+#define LIN_SDT_PROBE_ARGTYPE(a, b, c, d, e)	_LIN_SDT_PROBE_ARGTYPE( \
+    LINUX_DTRACE, a, b, c, d, e)
+
+#define	LIN_SDT_PROBE0(a, b, c)			SDT_PROBE1(LINUX_DTRACE, a, b, \
+    c, 0)
+#define	LIN_SDT_PROBE1(a, b, c, d)		SDT_PROBE1(LINUX_DTRACE, a, b, \
+    c, d)
+#define	LIN_SDT_PROBE2(a, b, c, d, e)		SDT_PROBE2(LINUX_DTRACE, a, b, \
+    c, d, e)
+#define	LIN_SDT_PROBE3(a, b, c, d, e, f)	SDT_PROBE3(LINUX_DTRACE, a, b, \
+    c, d, e, f)
+#define	LIN_SDT_PROBE4(a, b, c, d, e, f, g)	SDT_PROBE4(LINUX_DTRACE, a, b, \
+    c, d, e, f, g)
+#define	_LIN_SDT_PROBE5(a, b, c, d, e, f, g, h, i)	SDT_PROBE(a, b, c, d, \
+    e, f, g, h, i)
+#define	LIN_SDT_PROBE5(a, b, c, d, e, f, g, h)	_LIN_SDT_PROBE5(LINUX_DTRACE, \
+    a, b, c, d, e, f, g, h)
+
+#endif /* _LINUX_DTRACE_H_ */

Modified: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.c	Thu Feb  2 11:18:34 2012	(r230910)
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_compat.h"
+#include "opt_kdtrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/sdt.h>
 #include <sys/sx.h>
 #include <sys/proc.h>
 #include <sys/syscallsubr.h>
@@ -53,9 +55,64 @@ __FBSDID("$FreeBSD$");
 #include <machine/../linux/linux_proto.h>
 #endif
 
+#include <compat/linux/linux_dtrace.h>
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_futex.h>
 
+/**
+ * Special DTrace provider for the linuxulator.
+ *
+ * In this file we define the provider for the entire linuxulator. All
+ * modules (= files of the linuxulator) use it.
+ *
+ * We define a different name depending on the emulated bitsize, see
+ * ../../<ARCH>/linux{,32}/linux.h, e.g.:
+ *      native bitsize          = linuxulator
+ *      amd64, 32bit emulation  = linuxulator32
+ */
+LIN_SDT_PROVIDER_DEFINE(LINUX_DTRACE);
+
+/**
+ * Special DTrace module "locks", it covers some linuxulator internal
+ * locks.
+ */
+LIN_SDT_PROBE_DEFINE1(locks, emul_lock, locked, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_lock, unlock, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, locked, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_rlock, unlock, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, locked, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(locks, emul_shared_wlock, unlock, "struct sx *");
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(emul, em_find, entry, "struct proc *", "int");
+LIN_SDT_PROBE_DEFINE0(emul, em_find, return);
+LIN_SDT_PROBE_DEFINE3(emul, proc_init, entry, "struct thread *", "pid_t",
+    "int");
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, create_thread);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, fork);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, exec);
+LIN_SDT_PROBE_DEFINE0(emul, proc_init, return);
+LIN_SDT_PROBE_DEFINE1(emul, proc_exit, entry, "struct proc *");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exit, futex_failed);
+LIN_SDT_PROBE_DEFINE3(emul, proc_exit, reparent, "pid_t", "pid_t",
+    "struct proc *");
+LIN_SDT_PROBE_DEFINE1(emul, proc_exit, child_clear_tid_error, "int");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exit, return);
+LIN_SDT_PROBE_DEFINE2(emul, proc_exec, entry, "struct proc *",
+    "struct image_params *");
+LIN_SDT_PROBE_DEFINE0(emul, proc_exec, return);
+LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, entry);
+LIN_SDT_PROBE_DEFINE1(emul, linux_schedtail, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE0(emul, linux_schedtail, return);
+LIN_SDT_PROBE_DEFINE1(emul, linux_set_tid_address, entry, "int *");
+LIN_SDT_PROBE_DEFINE0(emul, linux_set_tid_address, return);
+LIN_SDT_PROBE_DEFINE2(emul, linux_kill_threads, entry, "struct thread *",
+    "int");
+LIN_SDT_PROBE_DEFINE1(emul, linux_kill_threads, kill, "pid_t");
+LIN_SDT_PROBE_DEFINE0(emul, linux_kill_threads, return);
+
 struct sx	emul_shared_lock;
 struct mtx	emul_lock;
 
@@ -65,6 +122,8 @@ em_find(struct proc *p, int locked)
 {
 	struct linux_emuldata *em;
 
+	LIN_SDT_PROBE2(emul, em_find, entry, p, locked);
+
 	if (locked == EMUL_DOLOCK)
 		EMUL_LOCK(&emul_lock);
 
@@ -73,6 +132,7 @@ em_find(struct proc *p, int locked)
 	if (em == NULL && locked == EMUL_DOLOCK)
 		EMUL_UNLOCK(&emul_lock);
 
+	LIN_SDT_PROBE1(emul, em_find, return, em);
 	return (em);
 }
 
@@ -82,8 +142,10 @@ linux_proc_init(struct thread *td, pid_t
 	struct linux_emuldata *em, *p_em;
 	struct proc *p;
 
+	LIN_SDT_PROBE3(emul, proc_init, entry, td, child, flags);
+
 	if (child != 0) {
-		/* non-exec call */
+		/* fork or create a thread */
 		em = malloc(sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
 		em->pid = child;
 		em->pdeath_signal = 0;
@@ -91,9 +153,12 @@ linux_proc_init(struct thread *td, pid_t
 		em->robust_futexes = NULL;
 		if (flags & LINUX_CLONE_THREAD) {
 			/* handled later in the code */
+			LIN_SDT_PROBE0(emul, proc_init, create_thread);
 		} else {
 			struct linux_emuldata_shared *s;
 
+			LIN_SDT_PROBE0(emul, proc_init, fork);
+
 			s = malloc(sizeof *s, M_LINUX, M_WAITOK | M_ZERO);
 			s->refs = 1;
 			s->group_pid = child;
@@ -102,6 +167,9 @@ linux_proc_init(struct thread *td, pid_t
 			em->shared = s;
 		}
 	} else {
+		/* exec */
+		LIN_SDT_PROBE0(emul, proc_init, exec);
+
 		/* lookup the old one */
 		em = em_find(td->td_proc, EMUL_DOLOCK);
 		KASSERT(em != NULL, ("proc_init: emuldata not found in exec case.\n"));
@@ -136,8 +204,7 @@ linux_proc_init(struct thread *td, pid_t
 			 * rwlock held
 			 */
 		}
-	}
-	if (child != 0) {
+
 		EMUL_SHARED_WLOCK(&emul_shared_lock);
 		LIST_INSERT_HEAD(&em->shared->threads, em, threads);
 		EMUL_SHARED_WUNLOCK(&emul_shared_lock);
@@ -149,6 +216,7 @@ linux_proc_init(struct thread *td, pid_t
 	} else
 		EMUL_UNLOCK(&emul_lock);
 
+	LIN_SDT_PROBE0(emul, proc_init, return);
 	return (0);
 }
 
@@ -164,6 +232,8 @@ linux_proc_exit(void *arg __unused, stru
 	if (__predict_true(p->p_sysent != &elf_linux_sysvec))
 		return;
 
+	LIN_SDT_PROBE1(emul, proc_exit, entry, p);
+
 	release_futexes(p);
 
 	/* find the emuldata */
@@ -173,6 +243,9 @@ linux_proc_exit(void *arg __unused, stru
 
 	/* reparent all procs that are not a thread leader to initproc */
 	if (em->shared->group_pid != p->p_pid) {
+		LIN_SDT_PROBE3(emul, proc_exit, reparent,
+		    em->shared->group_pid, p->p_pid, p);
+
 		child_clear_tid = em->child_clear_tid;
 		EMUL_UNLOCK(&emul_lock);
 		sx_xlock(&proctree_lock);
@@ -208,7 +281,12 @@ linux_proc_exit(void *arg __unused, stru
 
 		error = copyout(&null, child_clear_tid, sizeof(null));
 		if (error) {
+			LIN_SDT_PROBE1(emul, proc_exit,
+			    child_clear_tid_error, error);
+
 			free(em, M_LINUX);
+
+			LIN_SDT_PROBE0(emul, proc_exit, return);
 			return;
 		}
 
@@ -224,8 +302,10 @@ linux_proc_exit(void *arg __unused, stru
 		 * this cannot happen at the moment and if this happens it
 		 * probably means there is a user space bug
 		 */
-		if (error)
+		if (error) {
+			LIN_SDT_PROBE0(emul, proc_exit, futex_failed);
 			printf(LMSG("futex stuff in proc_exit failed.\n"));
+		}
 	}
 
 	/* clean the stuff up */
@@ -250,6 +330,8 @@ linux_proc_exit(void *arg __unused, stru
 		EMUL_UNLOCK(&emul_lock);
 	}
 	sx_xunlock(&proctree_lock);
+
+	LIN_SDT_PROBE0(emul, proc_exit, return);
 }
 
 /*
@@ -260,6 +342,9 @@ linux_proc_exit(void *arg __unused, stru
 void 
 linux_proc_exec(void *arg __unused, struct proc *p, struct image_params *imgp)
 {
+	if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
+		LIN_SDT_PROBE2(emul, proc_exec, entry, p, imgp);
+	}
 	if (__predict_false(imgp->sysent == &elf_linux_sysvec
 	    && p->p_sysent != &elf_linux_sysvec))
 		linux_proc_init(FIRST_THREAD_IN_PROC(p), p->p_pid, 0);
@@ -297,6 +382,10 @@ linux_proc_exec(void *arg __unused, stru
 
 		free(em, M_LINUX);
 	}
+
+	if (__predict_false(imgp->sysent == &elf_linux_sysvec)) {
+		LIN_SDT_PROBE0(emul, proc_exec, return);
+	}
 }
 
 void
@@ -309,6 +398,8 @@ linux_schedtail(struct thread *td)
 
 	p = td->td_proc;
 
+	LIN_SDT_PROBE1(emul, linux_schedtail, entry, p);
+
 	/* find the emuldata */
 	em = em_find(p, EMUL_DOLOCK);
 
@@ -316,10 +407,18 @@ linux_schedtail(struct thread *td)
 	child_set_tid = em->child_set_tid;
 	EMUL_UNLOCK(&emul_lock);
 
-	if (child_set_tid != NULL)
+	if (child_set_tid != NULL) {
 		error = copyout(&p->p_pid, (int *)child_set_tid,
 		    sizeof(p->p_pid));
 
+		if (error != 0) {
+			LIN_SDT_PROBE1(emul, linux_schedtail, copyout_error,
+			    error);
+		}
+	}
+
+	LIN_SDT_PROBE0(emul, linux_schedtail, return);
+
 	return;
 }
 
@@ -328,10 +427,7 @@ linux_set_tid_address(struct thread *td,
 {
 	struct linux_emuldata *em;
 
-#ifdef DEBUG
-	if (ldebug(set_tid_address))
-		printf(ARGS(set_tid_address, "%p"), args->tidptr);
-#endif
+	LIN_SDT_PROBE1(emul, linux_set_tid_address, entry, args->tidptr);
 
 	/* find the emuldata */
 	em = em_find(td->td_proc, EMUL_DOLOCK);
@@ -342,6 +438,8 @@ linux_set_tid_address(struct thread *td,
 	td->td_retval[0] = td->td_proc->p_pid;
 
 	EMUL_UNLOCK(&emul_lock);
+
+	LIN_SDT_PROBE0(emul, linux_set_tid_address, return);
 	return 0;
 }
 
@@ -351,6 +449,8 @@ linux_kill_threads(struct thread *td, in
 	struct linux_emuldata *em, *td_em, *tmp_em;
 	struct proc *sp;
 
+	LIN_SDT_PROBE2(emul, linux_kill_threads, entry, td, sig);
+
 	td_em = em_find(td->td_proc, EMUL_DONTLOCK);
 
 	KASSERT(td_em != NULL, ("linux_kill_threads: emuldata not found.\n"));
@@ -364,9 +464,10 @@ linux_kill_threads(struct thread *td, in
 		if ((sp->p_flag & P_WEXIT) == 0)
 			kern_psignal(sp, sig);
 		PROC_UNLOCK(sp);
-#ifdef DEBUG
-		printf(LMSG("linux_kill_threads: kill PID %d\n"), em->pid);
-#endif
+
+		LIN_SDT_PROBE1(emul, linux_kill_threads, kill, em->pid);
 	}
 	EMUL_SHARED_RUNLOCK(&emul_shared_lock);
+
+	LIN_SDT_PROBE0(emul, linux_kill_threads, return);
 }

Modified: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.h
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.h	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_emul.h	Thu Feb  2 11:18:34 2012	(r230910)
@@ -64,13 +64,42 @@ struct linux_emuldata {
 
 struct linux_emuldata	*em_find(struct proc *, int locked);
 
-#define	EMUL_LOCK(l)		mtx_lock(l)
-#define	EMUL_UNLOCK(l)		mtx_unlock(l)
-
-#define	EMUL_SHARED_RLOCK(l)	sx_slock(l)
-#define	EMUL_SHARED_RUNLOCK(l)	sx_sunlock(l)
-#define	EMUL_SHARED_WLOCK(l)	sx_xlock(l)
-#define	EMUL_SHARED_WUNLOCK(l)	sx_xunlock(l)
+/*
+ * DTrace probes for locks should be fired after locking and before releasing
+ * to prevent races (to provide data/function stability in dtrace, see the
+ * output of "dtrace -v ..." and the corresponding dtrace docs).
+ */
+#define	EMUL_LOCK(l)		do { \
+				    mtx_lock(l); \
+				    LIN_SDT_PROBE1(locks, emul_lock, \
+					locked, l); \
+				} while (0)
+#define	EMUL_UNLOCK(l)		do { \
+				    LIN_SDT_PROBE1(locks, emul_lock, \
+					unlock, l); \
+				    mtx_unlock(l); \
+				} while (0)
+
+#define	EMUL_SHARED_RLOCK(l)	do { \
+				    sx_slock(l); \
+				    LIN_SDT_PROBE1(locks, emul_shared_rlock, \
+					locked, l); \
+				} while (0)
+#define	EMUL_SHARED_RUNLOCK(l)	do { \
+				    LIN_SDT_PROBE1(locks, emul_shared_rlock, \
+					unlock, l); \
+				    sx_sunlock(l); \
+				} while (0)
+#define	EMUL_SHARED_WLOCK(l)	do { \
+				    sx_xlock(l); \
+				    LIN_SDT_PROBE1(locks, emul_shared_wlock, \
+					locked, l); \
+				} while (0)
+#define	EMUL_SHARED_WUNLOCK(l)	do { \
+				    LIN_SDT_PROBE1(locks, emul_shared_wlock, \
+					unlock, l); \
+				    sx_xunlock(l); \
+				} while (0)
 
 /* for em_find use */
 #define	EMUL_DOLOCK		1

Modified: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_fork.c
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_fork.c	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_fork.c	Thu Feb  2 11:18:34 2012	(r230910)
@@ -30,6 +30,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_compat.h"
+#include "opt_kdtrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,6 +39,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/sched.h>
+#include <sys/sdt.h>
 #include <sys/sx.h>
 #include <sys/unistd.h>
 
@@ -48,9 +50,17 @@ __FBSDID("$FreeBSD$");
 #include <machine/../linux/linux.h>
 #include <machine/../linux/linux_proto.h>
 #endif
+#include <compat/linux/linux_dtrace.h>
 #include <compat/linux/linux_signal.h>
 #include <compat/linux/linux_emul.h>
 
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/* Linuxulator-global DTrace probes */
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
+
 
 int
 linux_fork(struct thread *td, struct linux_fork_args *args)

Modified: user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_futex.c
==============================================================================
--- user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_futex.c	Thu Feb  2 10:40:24 2012	(r230909)
+++ user/netchild/linuxulator-dtrace/src/sys/compat/linux/linux_futex.c	Thu Feb  2 11:18:34 2012	(r230910)
@@ -38,6 +38,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.
 #endif
 
 #include "opt_compat.h"
+#include "opt_kdtrace.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,6 +52,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.
 #include <sys/proc.h>
 #include <sys/queue.h>
 #include <sys/sched.h>
+#include <sys/sdt.h>
 #include <sys/sx.h>
 #include <sys/umtx.h>
 
@@ -61,10 +63,131 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.
 #include <machine/../linux/linux.h>
 #include <machine/../linux/linux_proto.h>
 #endif
+#include <compat/linux/linux_dtrace.h>
 #include <compat/linux/linux_emul.h>
 #include <compat/linux/linux_futex.h>
 #include <compat/linux/linux_util.h>
 
+/* DTrace init */
+LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
+
+/* Linuxulator-global DTrace probes */
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, locked);
+LIN_SDT_PROBE_DECLARE(locks, emul_lock, unlock);
+
+/**
+ * Futex part for the special DTrace module "locks".
+ */
+LIN_SDT_PROBE_DEFINE1(locks, futex_mtx, locked, "struct mtx *");
+LIN_SDT_PROBE_DEFINE1(locks, futex_mtx, unlock, "struct mtx *");
+
+/**
+ * Per futex probes.
+ */
+LIN_SDT_PROBE_DEFINE1(futex, futex, create, "struct sx *");
+LIN_SDT_PROBE_DEFINE1(futex, futex, destroy, "struct sx *");
+
+/**
+ * DTrace probes in this module.
+ */
+LIN_SDT_PROBE_DEFINE2(futex, futex_put, entry, "struct futex *",
+    "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_put, destroy, "uint32_t *", "uint32_t",
+    "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_put, unlock, "uint32_t *", "uint32_t",
+    "int");
+LIN_SDT_PROBE_DEFINE0(futex, futex_put, return);
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, entry, "uint32_t *", "struct futex **",
+    "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, umtx_key_get_error, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, shared, "uint32_t *", "uint32_t",
+    "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, null, "uint32_t *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get0, new, "uint32_t *", "uint32_t", "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_get0, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_get, entry, "uint32_t *",
+    "struct waiting_proc **", "struct futex **");
+LIN_SDT_PROBE_DEFINE0(futex, futex_get, error);
+LIN_SDT_PROBE_DEFINE1(futex, futex_get, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_sleep, entry, "struct futex *",
+    "struct waiting_proc **", "int");
+LIN_SDT_PROBE_DEFINE5(futex, futex_sleep, requeue_error, "int", "uint32_t *",
+    "struct waiting_proc *", "uint32_t *", "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, futex_sleep, sleep_error, "int", "uint32_t *",
+    "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE1(futex, futex_sleep, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_wake, entry, "struct futex *", "int",
+    "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, futex_wake, iterate, "uint32_t",
+    "struct waiting_proc *", "uin32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wake, wakeup, "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wake, return, "int");
+LIN_SDT_PROBE_DEFINE4(futex, futex_requeue, entry, "struct futex *", "int",
+    "struct futex *", "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_requeue, wakeup, "struct waiting_proc *");
+LIN_SDT_PROBE_DEFINE3(futex, futex_requeue, requeue, "uint32_t *",
+    "struct waiting_proc *", "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_requeue, return, "int");
+LIN_SDT_PROBE_DEFINE4(futex, futex_wait, entry, "struct futex *",
+    "struct waiting_proc **", "struct l_timespec *", "uint32_t");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, itimerfix_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, sleep_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_wait, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, futex_atomic_op, entry, "struct thread *",
+    "int", "uint32_t");
+LIN_SDT_PROBE_DEFINE4(futex, futex_atomic_op, decoded_op, "int", "int", "int",
+    "int");
+LIN_SDT_PROBE_DEFINE0(futex, futex_atomic_op, missing_access_check);
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, unimplemented_op, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, unimplemented_cmp, "int");
+LIN_SDT_PROBE_DEFINE1(futex, futex_atomic_op, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_sys_futex, entry, "struct thread *",
+    "struct linux_sys_futex_args *");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_clockswitch);
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, invalid_cmp_requeue_use);
+LIN_SDT_PROBE_DEFINE3(futex, linux_sys_futex, debug_wait, "uint32_t *",
+    "uint32_t", "uint32_t");
+LIN_SDT_PROBE_DEFINE4(futex, linux_sys_futex, debug_wait_value_neq,
+    "uint32_t *", "uint32_t", "int", "uint32_t");
+LIN_SDT_PROBE_DEFINE3(futex, linux_sys_futex, debug_wake, "uint32_t *",
+    "uint32_t", "uint32_t");
+LIN_SDT_PROBE_DEFINE5(futex, linux_sys_futex, debug_cmp_requeue, "uint32_t *",
+    "uint32_t", "uint32_t", "uint32_t *", "struct l_timespec *");
+LIN_SDT_PROBE_DEFINE2(futex, linux_sys_futex, debug_cmp_requeue_value_neq,
+    "uint32_t", "int");
+LIN_SDT_PROBE_DEFINE5(futex, linux_sys_futex, debug_wake_op, "uint32_t *",
+    "int", "uint32_t", "uint32_t *", "uint32_t");
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unhandled_efault);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_lock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_unlock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_trylock_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, deprecated_requeue);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_wait_requeue_pi);
+LIN_SDT_PROBE_DEFINE0(futex, linux_sys_futex, unimplemented_cmp_requeue_pi);
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, unknown_operation, "int");
+LIN_SDT_PROBE_DEFINE1(futex, linux_sys_futex, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_set_robust_list, entry, "struct thread *",
+    "struct linux_set_robust_list_args *");
+LIN_SDT_PROBE_DEFINE0(futex, linux_set_robust_list, size_error);
+LIN_SDT_PROBE_DEFINE1(futex, linux_set_robust_list, return, "int");
+LIN_SDT_PROBE_DEFINE2(futex, linux_get_robust_list, entry, "struct thread *",
+    "struct linux_get_robust_list_args *");
+LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, copyout_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, linux_get_robust_list, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, handle_futex_death, entry, "struct proc *",
+    "uint32_t *", "int");
+LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, handle_futex_death, return, "int");
+LIN_SDT_PROBE_DEFINE3(futex, fetch_robust_entry, entry,
+    "struct linux_robust_list **", "struct linux_robust_list **", "int *");
+LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE1(futex, fetch_robust_entry, return, "int");
+LIN_SDT_PROBE_DEFINE1(futex, release_futexes, entry, "struct proc *");
+LIN_SDT_PROBE_DEFINE1(futex, release_futexes, copyin_error, "int");
+LIN_SDT_PROBE_DEFINE0(futex, release_futexes, return);
+
 static MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes");
 static MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futexes wp");
 
@@ -90,13 +213,30 @@ struct futex_list futex_list;
 
 #define FUTEX_LOCK(f)		sx_xlock(&(f)->f_lck)
 #define FUTEX_UNLOCK(f)		sx_xunlock(&(f)->f_lck)
-#define FUTEX_INIT(f)		sx_init_flags(&(f)->f_lck, "ftlk", SX_DUPOK)
-#define FUTEX_DESTROY(f)	sx_destroy(&(f)->f_lck)
+#define FUTEX_INIT(f)		do { \
+				    sx_init_flags(&(f)->f_lck, "ftlk", \
+					SX_DUPOK); \
+				    LIN_SDT_PROBE1(futex, futex, create, \
+					&(f)->f_lck); \
+				} while (0)
+#define FUTEX_DESTROY(f)	do { \
+				    LIN_SDT_PROBE1(futex, futex, destroy, \
+					&(f)->f_lck); \

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202021118.q12BIY5U035017>