svn commit: r211738 - head/sys/cddl/contrib/opensolaris/uts/common/dtrace

Rui Paulo rpaulo at FreeBSD.org
Tue Aug 24 11:11:59 UTC 2010


Author: rpaulo
Date: Tue Aug 24 11:11:58 2010
New Revision: 211738
URL: http://svn.freebsd.org/changeset/base/211738

Log:
  Port the fasttrap provider to FreeBSD. This provider is responsible for
  injecting debugging probes in the userland programs and is the basis for
  the pid provider and the usdt provider.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c	Tue Aug 24 09:57:06 2010	(r211737)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c	Tue Aug 24 11:11:58 2010	(r211738)
@@ -17,6 +17,10 @@
  * information: Portions Copyright [yyyy] [name of copyright owner]
  *
  * CDDL HEADER END
+ *
+ * Portions Copyright 2010 The FreeBSD Foundation
+ *
+ * $FreeBSD$
  */
 
 /*
@@ -24,7 +28,9 @@
  * Use is subject to license terms.
  */
 
+#if defined(sun)
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
+#endif
 
 #include <sys/atomic.h>
 #include <sys/errno.h>
@@ -32,11 +38,15 @@
 #include <sys/modctl.h>
 #include <sys/conf.h>
 #include <sys/systm.h>
+#if defined(sun)
 #include <sys/ddi.h>
+#endif
 #include <sys/sunddi.h>
 #include <sys/cpuvar.h>
 #include <sys/kmem.h>
+#if defined(sun)
 #include <sys/strsubr.h>
+#endif
 #include <sys/fasttrap.h>
 #include <sys/fasttrap_impl.h>
 #include <sys/fasttrap_isa.h>
@@ -44,9 +54,17 @@
 #include <sys/dtrace_impl.h>
 #include <sys/sysmacros.h>
 #include <sys/proc.h>
-#include <sys/priv.h>
 #include <sys/policy.h>
+#if defined(sun)
 #include <util/qsort.h>
+#endif
+#include <sys/mutex.h>
+#include <sys/kernel.h>
+#if !defined(sun)
+#include <sys/user.h>
+#include <sys/dtrace_bsd.h>
+#include <cddl/dev/dtrace/dtrace_cddl.h>
+#endif
 
 /*
  * User-Land Trap-Based Tracing
@@ -125,11 +143,20 @@
  *	never hold the provider lock and creation lock simultaneously
  */
 
-static dev_info_t *fasttrap_devi;
+static d_open_t fasttrap_open;
+static d_ioctl_t fasttrap_ioctl;
+
+static struct cdevsw fasttrap_cdevsw = {
+	.d_version	= D_VERSION,
+	.d_open		= fasttrap_open,
+	.d_ioctl	= fasttrap_ioctl,
+	.d_name		= "fasttrap",
+};
+static struct cdev *fasttrap_cdev;
 static dtrace_meta_provider_id_t fasttrap_meta_id;
 
-static timeout_id_t fasttrap_timeout;
-static kmutex_t fasttrap_cleanup_mtx;
+static struct callout fasttrap_timeout;
+static struct mtx fasttrap_cleanup_mtx;
 static uint_t fasttrap_cleanup_work;
 
 /*
@@ -229,6 +256,7 @@ fasttrap_hash_str(const char *p)
 void
 fasttrap_sigtrap(proc_t *p, kthread_t *t, uintptr_t pc)
 {
+#if defined(sun)
 	sigqueue_t *sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP);
 
 	sqp->sq_info.si_signo = SIGTRAP;
@@ -241,6 +269,17 @@ fasttrap_sigtrap(proc_t *p, kthread_t *t
 
 	if (t != NULL)
 		aston(t);
+#else
+	ksiginfo_t *ksi = kmem_zalloc(sizeof (ksiginfo_t), KM_SLEEP);
+
+	ksiginfo_init(ksi);
+	ksi->ksi_signo = SIGTRAP;
+	ksi->ksi_code = TRAP_DTRACE;
+	ksi->ksi_addr = (caddr_t)pc;
+	PROC_LOCK(p);
+	(void) pksignal(p, SIGTRAP, ksi);
+	PROC_UNLOCK(p);
+#endif
 }
 
 /*
@@ -250,17 +289,24 @@ fasttrap_sigtrap(proc_t *p, kthread_t *t
 static void
 fasttrap_mod_barrier(uint64_t gen)
 {
+#if defined(sun)
 	int i;
+#endif
 
 	if (gen < fasttrap_mod_gen)
 		return;
 
 	fasttrap_mod_gen++;
 
+#if defined(sun)
 	for (i = 0; i < NCPU; i++) {
 		mutex_enter(&cpu_core[i].cpuc_pid_lock);
 		mutex_exit(&cpu_core[i].cpuc_pid_lock);
 	}
+#else
+	/* XXX */
+	__asm __volatile("": : :"memory");
+#endif
 }
 
 /*
@@ -274,16 +320,15 @@ fasttrap_pid_cleanup_cb(void *data)
 	fasttrap_provider_t **fpp, *fp;
 	fasttrap_bucket_t *bucket;
 	dtrace_provider_id_t provid;
-	int i, later;
+	int i, later = 0;
 
 	static volatile int in = 0;
 	ASSERT(in == 0);
 	in = 1;
 
-	mutex_enter(&fasttrap_cleanup_mtx);
 	while (fasttrap_cleanup_work) {
 		fasttrap_cleanup_work = 0;
-		mutex_exit(&fasttrap_cleanup_mtx);
+		mtx_unlock(&fasttrap_cleanup_mtx);
 
 		later = 0;
 
@@ -349,10 +394,12 @@ fasttrap_pid_cleanup_cb(void *data)
 			mutex_exit(&bucket->ftb_mtx);
 		}
 
-		mutex_enter(&fasttrap_cleanup_mtx);
+		mtx_lock(&fasttrap_cleanup_mtx);
 	}
 
+#if 0
 	ASSERT(fasttrap_timeout != 0);
+#endif
 
 	/*
 	 * If we were unable to remove a retired provider, try again after
@@ -364,14 +411,17 @@ fasttrap_pid_cleanup_cb(void *data)
 	 * get a chance to do that work if and when the timeout is reenabled
 	 * (if detach fails).
 	 */
-	if (later > 0 && fasttrap_timeout != (timeout_id_t)1)
-		fasttrap_timeout = timeout(&fasttrap_pid_cleanup_cb, NULL, hz);
+	if (later > 0 && callout_active(&fasttrap_timeout))
+		callout_reset(&fasttrap_timeout, hz, &fasttrap_pid_cleanup_cb,
+		    NULL);
 	else if (later > 0)
 		fasttrap_cleanup_work = 1;
-	else
-		fasttrap_timeout = 0;
+	else {
+#if !defined(sun)
+		/* Nothing to be done for FreeBSD */
+#endif
+	}
 
-	mutex_exit(&fasttrap_cleanup_mtx);
 	in = 0;
 }
 
@@ -381,11 +431,11 @@ fasttrap_pid_cleanup_cb(void *data)
 static void
 fasttrap_pid_cleanup(void)
 {
-	mutex_enter(&fasttrap_cleanup_mtx);
+
+	mtx_lock(&fasttrap_cleanup_mtx);
 	fasttrap_cleanup_work = 1;
-	if (fasttrap_timeout == 0)
-		fasttrap_timeout = timeout(&fasttrap_pid_cleanup_cb, NULL, 1);
-	mutex_exit(&fasttrap_cleanup_mtx);
+	callout_reset(&fasttrap_timeout, 1, &fasttrap_pid_cleanup_cb, NULL);
+	mtx_unlock(&fasttrap_cleanup_mtx);
 }
 
 /*
@@ -400,9 +450,23 @@ fasttrap_fork(proc_t *p, proc_t *cp)
 	pid_t ppid = p->p_pid;
 	int i;
 
+#if defined(sun)
 	ASSERT(curproc == p);
 	ASSERT(p->p_proc_flag & P_PR_LOCK);
+#else
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+#endif
+#if defined(sun)
 	ASSERT(p->p_dtrace_count > 0);
+#else
+	/*
+	 * This check is purposely here instead of in kern_fork.c because,
+	 * for legal resons, we cannot include the dtrace_cddl.h header
+	 * inside kern_fork.c and insert if-clause there.
+	 */
+	if (p->p_dtrace_count == 0)
+		return;
+#endif
 	ASSERT(cp->p_dtrace_count == 0);
 
 	/*
@@ -419,9 +483,11 @@ fasttrap_fork(proc_t *p, proc_t *cp)
 	 * We don't have to worry about the child process disappearing
 	 * because we're in fork().
 	 */
-	mutex_enter(&cp->p_lock);
+#if defined(sun)
+	mtx_lock_spin(&cp->p_slock);
 	sprlock_proc(cp);
-	mutex_exit(&cp->p_lock);
+	mtx_unlock_spin(&cp->p_slock);
+#endif
 
 	/*
 	 * Iterate over every tracepoint looking for ones that belong to the
@@ -451,8 +517,10 @@ fasttrap_fork(proc_t *p, proc_t *cp)
 		mutex_exit(&bucket->ftb_mtx);
 	}
 
+#if defined(sun)
 	mutex_enter(&cp->p_lock);
 	sprunlock(cp);
+#endif
 }
 
 /*
@@ -463,24 +531,24 @@ fasttrap_fork(proc_t *p, proc_t *cp)
 static void
 fasttrap_exec_exit(proc_t *p)
 {
+#if defined(sun)
 	ASSERT(p == curproc);
-	ASSERT(MUTEX_HELD(&p->p_lock));
-
-	mutex_exit(&p->p_lock);
+#endif
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	PROC_UNLOCK(p);
 
 	/*
 	 * We clean up the pid provider for this process here; user-land
 	 * static probes are handled by the meta-provider remove entry point.
 	 */
 	fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0);
-
-	mutex_enter(&p->p_lock);
+	PROC_LOCK(p);
 }
 
 
 /*ARGSUSED*/
 static void
-fasttrap_pid_provide(void *arg, const dtrace_probedesc_t *desc)
+fasttrap_pid_provide(void *arg, dtrace_probedesc_t *desc)
 {
 	/*
 	 * There are no "default" pid probes.
@@ -504,7 +572,9 @@ fasttrap_tracepoint_enable(proc_t *p, fa
 
 	ASSERT(probe->ftp_tps[index].fit_tp->ftt_pid == pid);
 
+#if defined(sun)
 	ASSERT(!(p->p_flag & SVFORK));
+#endif
 
 	/*
 	 * Before we make any modifications, make sure we've imposed a barrier
@@ -610,7 +680,11 @@ again:
 		 * Increment the count of the number of tracepoints active in
 		 * the victim process.
 		 */
+#if defined(sun)
 		ASSERT(p->p_proc_flag & P_PR_LOCK);
+#else
+		PROC_LOCK_ASSERT(p, MA_OWNED);
+#endif
 		p->p_dtrace_count++;
 
 		return (rc);
@@ -666,7 +740,7 @@ fasttrap_tracepoint_disable(proc_t *p, f
 	fasttrap_bucket_t *bucket;
 	fasttrap_provider_t *provider = probe->ftp_prov;
 	fasttrap_tracepoint_t **pp, *tp;
-	fasttrap_id_t *id, **idp;
+	fasttrap_id_t *id, **idp = NULL;
 	pid_t pid;
 	uintptr_t pc;
 
@@ -800,7 +874,11 @@ fasttrap_tracepoint_disable(proc_t *p, f
 		 * Decrement the count of the number of tracepoints active
 		 * in the victim process.
 		 */
+#if defined(sun)
 		ASSERT(p->p_proc_flag & P_PR_LOCK);
+#else
+		PROC_LOCK_ASSERT(p, MA_OWNED);
+#endif
 		p->p_dtrace_count--;
 	}
 
@@ -851,26 +929,31 @@ fasttrap_enable_callbacks(void)
 static void
 fasttrap_disable_callbacks(void)
 {
+#if defined(sun)
 	ASSERT(MUTEX_HELD(&cpu_lock));
+#endif
+
 
 	mutex_enter(&fasttrap_count_mtx);
 	ASSERT(fasttrap_pid_count > 0);
 	fasttrap_pid_count--;
 	if (fasttrap_pid_count == 0) {
+#if defined(sun)
 		cpu_t *cur, *cpu = CPU;
 
 		for (cur = cpu->cpu_next_onln; cur != cpu;
 		    cur = cur->cpu_next_onln) {
 			rw_enter(&cur->cpu_ft_lock, RW_WRITER);
 		}
-
+#endif
 		dtrace_pid_probe_ptr = NULL;
 		dtrace_return_probe_ptr = NULL;
-
+#if defined(sun)
 		for (cur = cpu->cpu_next_onln; cur != cpu;
 		    cur = cur->cpu_next_onln) {
 			rw_exit(&cur->cpu_ft_lock);
 		}
+#endif
 	}
 	mutex_exit(&fasttrap_count_mtx);
 }
@@ -880,13 +963,16 @@ static void
 fasttrap_pid_enable(void *arg, dtrace_id_t id, void *parg)
 {
 	fasttrap_probe_t *probe = parg;
-	proc_t *p;
+	proc_t *p = NULL;
 	int i, rc;
 
+
 	ASSERT(probe != NULL);
 	ASSERT(!probe->ftp_enabled);
 	ASSERT(id == probe->ftp_id);
+#if defined(sun)
 	ASSERT(MUTEX_HELD(&cpu_lock));
+#endif
 
 	/*
 	 * Increment the count of enabled probes on this probe's provider;
@@ -911,6 +997,7 @@ fasttrap_pid_enable(void *arg, dtrace_id
 	 * a fork in which the traced process is being born and we're copying
 	 * USDT probes. Otherwise, the process is gone so bail.
 	 */
+#if defined(sun)
 	if ((p = sprlock(probe->ftp_pid)) == NULL) {
 		if ((curproc->p_flag & SFORKING) == 0)
 			return;
@@ -934,13 +1021,19 @@ fasttrap_pid_enable(void *arg, dtrace_id
 
 	ASSERT(!(p->p_flag & SVFORK));
 	mutex_exit(&p->p_lock);
+#else
+	if ((p = pfind(probe->ftp_pid)) == NULL)
+		return;
+#endif
 
 	/*
 	 * We have to enable the trap entry point before any user threads have
 	 * the chance to execute the trap instruction we're about to place
 	 * in their process's text.
 	 */
+	PROC_UNLOCK(p);
 	fasttrap_enable_callbacks();
+	PROC_LOCK(p);
 
 	/*
 	 * Enable all the tracepoints and add this probe's id to each
@@ -967,8 +1060,12 @@ fasttrap_pid_enable(void *arg, dtrace_id
 				i--;
 			}
 
+#if defined(sun)
 			mutex_enter(&p->p_lock);
 			sprunlock(p);
+#else
+			PROC_UNLOCK(p);
+#endif
 
 			/*
 			 * Since we're not actually enabling this probe,
@@ -978,9 +1075,12 @@ fasttrap_pid_enable(void *arg, dtrace_id
 			return;
 		}
 	}
-
+#if defined(sun)
 	mutex_enter(&p->p_lock);
 	sprunlock(p);
+#else
+	PROC_UNLOCK(p);
+#endif
 
 	probe->ftp_enabled = 1;
 }
@@ -996,19 +1096,19 @@ fasttrap_pid_disable(void *arg, dtrace_i
 
 	ASSERT(id == probe->ftp_id);
 
+	mutex_enter(&provider->ftp_mtx);
+
 	/*
 	 * We won't be able to acquire a /proc-esque lock on the process
 	 * iff the process is dead and gone. In this case, we rely on the
 	 * provider lock as a point of mutual exclusion to prevent other
 	 * DTrace consumers from disabling this probe.
 	 */
-	if ((p = sprlock(probe->ftp_pid)) != NULL) {
-		ASSERT(!(p->p_flag & SVFORK));
-		mutex_exit(&p->p_lock);
+	if ((p = pfind(probe->ftp_pid)) == NULL) {
+		mutex_exit(&provider->ftp_mtx);
+		return;
 	}
 
-	mutex_enter(&provider->ftp_mtx);
-
 	/*
 	 * Disable all the associated tracepoints (for fully enabled probes).
 	 */
@@ -1030,9 +1130,6 @@ fasttrap_pid_disable(void *arg, dtrace_i
 		if (provider->ftp_retired && !provider->ftp_marked)
 			whack = provider->ftp_marked = 1;
 		mutex_exit(&provider->ftp_mtx);
-
-		mutex_enter(&p->p_lock);
-		sprunlock(p);
 	} else {
 		/*
 		 * If the process is dead, we're just waiting for the
@@ -1042,6 +1139,9 @@ fasttrap_pid_disable(void *arg, dtrace_i
 			whack = provider->ftp_marked = 1;
 		mutex_exit(&provider->ftp_mtx);
 	}
+#if !defined(sun)
+	PROC_UNLOCK(p);
+#endif
 
 	if (whack)
 		fasttrap_pid_cleanup();
@@ -1051,7 +1151,9 @@ fasttrap_pid_disable(void *arg, dtrace_i
 
 	probe->ftp_enabled = 0;
 
+#if defined(sun)
 	ASSERT(MUTEX_HELD(&cpu_lock));
+#endif
 	fasttrap_disable_callbacks();
 }
 
@@ -1163,6 +1265,7 @@ fasttrap_proc_lookup(pid_t pid)
 	fasttrap_bucket_t *bucket;
 	fasttrap_proc_t *fprc, *new_fprc;
 
+
 	bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
 	mutex_enter(&bucket->ftb_mtx);
 
@@ -1189,6 +1292,10 @@ fasttrap_proc_lookup(pid_t pid)
 	new_fprc->ftpc_pid = pid;
 	new_fprc->ftpc_rcount = 1;
 	new_fprc->ftpc_acount = 1;
+#if !defined(sun)
+	mutex_init(&new_fprc->ftpc_mtx, "fasttrap proc mtx", MUTEX_DEFAULT,
+	    NULL);
+#endif
 
 	mutex_enter(&bucket->ftb_mtx);
 
@@ -1311,17 +1418,8 @@ fasttrap_provider_lookup(pid_t pid, cons
 	 * Make sure the process exists, isn't a child created as the result
 	 * of a vfork(2), and isn't a zombie (but may be in fork).
 	 */
-	mutex_enter(&pidlock);
-	if ((p = prfind(pid)) == NULL) {
-		mutex_exit(&pidlock);
+	if ((p = pfind(pid)) == NULL)
 		return (NULL);
-	}
-	mutex_enter(&p->p_lock);
-	mutex_exit(&pidlock);
-	if (p->p_flag & (SVFORK | SEXITING)) {
-		mutex_exit(&p->p_lock);
-		return (NULL);
-	}
 
 	/*
 	 * Increment p_dtrace_probes so that the process knows to inform us
@@ -1334,15 +1432,18 @@ fasttrap_provider_lookup(pid_t pid, cons
 	 * Grab the credentials for this process so we have
 	 * something to pass to dtrace_register().
 	 */
-	mutex_enter(&p->p_crlock);
-	crhold(p->p_cred);
-	cred = p->p_cred;
-	mutex_exit(&p->p_crlock);
-	mutex_exit(&p->p_lock);
+	PROC_LOCK_ASSERT(p, MA_OWNED);
+	crhold(p->p_ucred);
+	cred = p->p_ucred;
+	PROC_UNLOCK(p);
 
 	new_fp = kmem_zalloc(sizeof (fasttrap_provider_t), KM_SLEEP);
 	new_fp->ftp_pid = pid;
 	new_fp->ftp_proc = fasttrap_proc_lookup(pid);
+#if !defined(sun)
+	mutex_init(&new_fp->ftp_mtx, "provider mtx", MUTEX_DEFAULT, NULL);
+	mutex_init(&new_fp->ftp_cmtx, "lock on creating", MUTEX_DEFAULT, NULL);
+#endif
 
 	ASSERT(new_fp->ftp_proc != NULL);
 
@@ -1420,6 +1521,10 @@ fasttrap_provider_free(fasttrap_provider
 
 	fasttrap_proc_release(provider->ftp_proc);
 
+#if !defined(sun)
+	mutex_destroy(&provider->ftp_mtx);
+	mutex_destroy(&provider->ftp_cmtx);
+#endif
 	kmem_free(provider, sizeof (fasttrap_provider_t));
 
 	/*
@@ -1429,17 +1534,14 @@ fasttrap_provider_free(fasttrap_provider
 	 * corresponds to this process's hash chain in the provider hash
 	 * table. Don't sweat it if we can't find the process.
 	 */
-	mutex_enter(&pidlock);
-	if ((p = prfind(pid)) == NULL) {
-		mutex_exit(&pidlock);
+	if ((p = pfind(pid)) == NULL) {
 		return;
 	}
 
-	mutex_enter(&p->p_lock);
-	mutex_exit(&pidlock);
-
 	p->p_dtrace_probes--;
-	mutex_exit(&p->p_lock);
+#if !defined(sun)
+	PROC_UNLOCK(p);
+#endif
 }
 
 static void
@@ -1527,7 +1629,7 @@ fasttrap_add_probe(fasttrap_probe_spec_t
 	fasttrap_probe_t *pp;
 	fasttrap_tracepoint_t *tp;
 	char *name;
-	int i, aframes, whack;
+	int i, aframes = 0, whack;
 
 	/*
 	 * There needs to be at least one desired trace point.
@@ -1715,7 +1817,7 @@ fasttrap_meta_provide(void *arg, dtrace_
 	 */
 	if (strlen(dhpv->dthpv_provname) + 10 >=
 	    sizeof (provider->ftp_name)) {
-		cmn_err(CE_WARN, "failed to instantiate provider %s: "
+		printf("failed to instantiate provider %s: "
 		    "name too long to accomodate pid", dhpv->dthpv_provname);
 		return (NULL);
 	}
@@ -1724,7 +1826,7 @@ fasttrap_meta_provide(void *arg, dtrace_
 	 * Don't let folks spoof the true pid provider.
 	 */
 	if (strcmp(dhpv->dthpv_provname, FASTTRAP_PID_NAME) == 0) {
-		cmn_err(CE_WARN, "failed to instantiate provider %s: "
+		printf("failed to instantiate provider %s: "
 		    "%s is an invalid name", dhpv->dthpv_provname,
 		    FASTTRAP_PID_NAME);
 		return (NULL);
@@ -1747,7 +1849,7 @@ fasttrap_meta_provide(void *arg, dtrace_
 
 	if ((provider = fasttrap_provider_lookup(pid, dhpv->dthpv_provname,
 	    &dhpv->dthpv_pattr)) == NULL) {
-		cmn_err(CE_WARN, "failed to instantiate provider %s for "
+		printf("failed to instantiate provider %s for "
 		    "process %u",  dhpv->dthpv_provname, (uint_t)pid);
 		return (NULL);
 	}
@@ -1908,15 +2010,21 @@ static dtrace_mops_t fasttrap_mops = {
 
 /*ARGSUSED*/
 static int
-fasttrap_open(dev_t *devp, int flag, int otyp, cred_t *cred_p)
+fasttrap_open(struct cdev *dev __unused, int oflags __unused,
+    int devtype __unused, struct thread *td __unused)
 {
 	return (0);
 }
 
 /*ARGSUSED*/
 static int
-fasttrap_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)
+fasttrap_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int fflag,
+    struct thread *td)
 {
+#ifdef notyet
+	struct kinfo_proc kp;
+	const cred_t *cr = td->td_ucred;
+#endif
 	if (!dtrace_attached())
 		return (EAGAIN);
 
@@ -1928,9 +2036,13 @@ fasttrap_ioctl(dev_t dev, int cmd, intpt
 		int ret;
 		char *c;
 
+#if defined(sun)
 		if (copyin(&uprobe->ftps_noffs, &noffs,
 		    sizeof (uprobe->ftps_noffs)))
 			return (EFAULT);
+#else
+		noffs = uprobe->ftps_noffs;
+#endif
 
 		/*
 		 * Probes must have at least one tracepoint.
@@ -1946,10 +2058,19 @@ fasttrap_ioctl(dev_t dev, int cmd, intpt
 
 		probe = kmem_alloc(size, KM_SLEEP);
 
+#if defined(sun)
 		if (copyin(uprobe, probe, size) != 0) {
 			kmem_free(probe, size);
 			return (EFAULT);
 		}
+#else
+		memcpy(probe, uprobe, sizeof(*probe));
+		if (noffs > 1 && copyin(uprobe + 1, probe + 1, size) != 0) {
+			kmem_free(probe, size);
+			return (EFAULT);
+		}
+#endif
+
 
 		/*
 		 * Verify that the function and module strings contain no
@@ -1969,30 +2090,52 @@ fasttrap_ioctl(dev_t dev, int cmd, intpt
 			}
 		}
 
+#ifdef notyet
 		if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) {
 			proc_t *p;
 			pid_t pid = probe->ftps_pid;
 
+#if defined(sun)
 			mutex_enter(&pidlock);
+#endif
 			/*
 			 * Report an error if the process doesn't exist
 			 * or is actively being birthed.
 			 */
-			if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
+			p = pfind(pid);
+			if (p)
+				fill_kinfo_proc(p, &kp);
+			if (p == NULL || kp.ki_stat == SIDL) {
+#if defined(sun)
 				mutex_exit(&pidlock);
+#endif
 				return (ESRCH);
 			}
+#if defined(sun)
 			mutex_enter(&p->p_lock);
 			mutex_exit(&pidlock);
+#else
+			PROC_LOCK_ASSERT(p, MA_OWNED);
+#endif
 
+#ifdef notyet
 			if ((ret = priv_proc_cred_perm(cr, p, NULL,
 			    VREAD | VWRITE)) != 0) {
+#if defined(sun)
 				mutex_exit(&p->p_lock);
+#else
+				PROC_UNLOCK(p);
+#endif
 				return (ret);
 			}
-
+#endif /* notyet */
+#if defined(sun)
 			mutex_exit(&p->p_lock);
+#else
+			PROC_UNLOCK(p);
+#endif
 		}
+#endif /* notyet */
 
 		ret = fasttrap_add_probe(probe);
 err:
@@ -2004,35 +2147,62 @@ err:
 		fasttrap_instr_query_t instr;
 		fasttrap_tracepoint_t *tp;
 		uint_t index;
+#if defined(sun)
 		int ret;
+#endif
 
+#if defined(sun)
 		if (copyin((void *)arg, &instr, sizeof (instr)) != 0)
 			return (EFAULT);
+#endif
 
+#ifdef notyet
 		if (!PRIV_POLICY_CHOICE(cr, PRIV_ALL, B_FALSE)) {
 			proc_t *p;
 			pid_t pid = instr.ftiq_pid;
 
+#if defined(sun)
 			mutex_enter(&pidlock);
+#endif
 			/*
 			 * Report an error if the process doesn't exist
 			 * or is actively being birthed.
 			 */
-			if ((p = prfind(pid)) == NULL || p->p_stat == SIDL) {
+			p = pfind(pid);
+			if (p)
+				fill_kinfo_proc(p, &kp);
+			if (p == NULL || kp.ki_stat == SIDL) {
+#if defined(sun)
 				mutex_exit(&pidlock);
+#endif
 				return (ESRCH);
 			}
+#if defined(sun)
 			mutex_enter(&p->p_lock);
 			mutex_exit(&pidlock);
+#else
+			PROC_LOCK_ASSERT(p, MA_OWNED);
+#endif
 
+#ifdef notyet
 			if ((ret = priv_proc_cred_perm(cr, p, NULL,
 			    VREAD)) != 0) {
+#if defined(sun)
 				mutex_exit(&p->p_lock);
+#else
+				PROC_UNLOCK(p);
+#endif
 				return (ret);
 			}
+#endif /* notyet */
 
+#if defined(sun)
 			mutex_exit(&p->p_lock);
+#else
+			PROC_UNLOCK(p);
+#endif
 		}
+#endif /* notyet */
 
 		index = FASTTRAP_TPOINTS_INDEX(instr.ftiq_pid, instr.ftiq_pc);
 
@@ -2065,84 +2235,45 @@ err:
 	return (EINVAL);
 }
 
-static struct cb_ops fasttrap_cb_ops = {
-	fasttrap_open,		/* open */
-	nodev,			/* close */
-	nulldev,		/* strategy */
-	nulldev,		/* print */
-	nodev,			/* dump */
-	nodev,			/* read */
-	nodev,			/* write */
-	fasttrap_ioctl,		/* ioctl */
-	nodev,			/* devmap */
-	nodev,			/* mmap */
-	nodev,			/* segmap */
-	nochpoll,		/* poll */
-	ddi_prop_op,		/* cb_prop_op */
-	0,			/* streamtab  */
-	D_NEW | D_MP		/* Driver compatibility flag */
-};
-
-/*ARGSUSED*/
 static int
-fasttrap_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
-{
-	int error;
-
-	switch (infocmd) {
-	case DDI_INFO_DEVT2DEVINFO:
-		*result = (void *)fasttrap_devi;
-		error = DDI_SUCCESS;
-		break;
-	case DDI_INFO_DEVT2INSTANCE:
-		*result = (void *)0;
-		error = DDI_SUCCESS;
-		break;
-	default:
-		error = DDI_FAILURE;
-	}
-	return (error);
-}
-
-static int
-fasttrap_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
+fasttrap_load(void)
 {
 	ulong_t nent;
+	int i;
 
-	switch (cmd) {
-	case DDI_ATTACH:
-		break;
-	case DDI_RESUME:
-		return (DDI_SUCCESS);
-	default:
-		return (DDI_FAILURE);
-	}
-
-	if (ddi_create_minor_node(devi, "fasttrap", S_IFCHR, 0,
-	    DDI_PSEUDO, NULL) == DDI_FAILURE) {
-		ddi_remove_minor_node(devi, NULL);
-		return (DDI_FAILURE);
-	}
-
-	ddi_report_dev(devi);
-	fasttrap_devi = devi;
+        /* Create the /dev/dtrace/fasttrap entry. */
+        fasttrap_cdev = make_dev(&fasttrap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
+            "dtrace/fasttrap");
+
+	mtx_init(&fasttrap_cleanup_mtx, "fasttrap clean", "dtrace", MTX_DEF);
+	callout_init_mtx(&fasttrap_timeout, &fasttrap_cleanup_mtx, 0);
+	mutex_init(&fasttrap_count_mtx, "fasttrap count mtx", MUTEX_DEFAULT,
+	    NULL);
 
 	/*
 	 * Install our hooks into fork(2), exec(2), and exit(2).
 	 */
-	dtrace_fasttrap_fork_ptr = &fasttrap_fork;
-	dtrace_fasttrap_exit_ptr = &fasttrap_exec_exit;
-	dtrace_fasttrap_exec_ptr = &fasttrap_exec_exit;
+	dtrace_fasttrap_fork = &fasttrap_fork;
+	dtrace_fasttrap_exit = &fasttrap_exec_exit;
+	dtrace_fasttrap_exec = &fasttrap_exec_exit;
 
+#if defined(sun)
 	fasttrap_max = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
 	    "fasttrap-max-probes", FASTTRAP_MAX_DEFAULT);
+#else
+	fasttrap_max = FASTTRAP_MAX_DEFAULT;
+#endif
 	fasttrap_total = 0;
 
 	/*
 	 * Conjure up the tracepoints hashtable...
 	 */
+#if defined(sun)
 	nent = ddi_getprop(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
 	    "fasttrap-hash-size", FASTTRAP_TPOINTS_DEFAULT_SIZE);
+#else
+	nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
+#endif
 
 	if (nent == 0 || nent > 0x1000000)
 		nent = FASTTRAP_TPOINTS_DEFAULT_SIZE;
@@ -2155,6 +2286,11 @@ fasttrap_attach(dev_info_t *devi, ddi_at
 	fasttrap_tpoints.fth_mask = fasttrap_tpoints.fth_nent - 1;
 	fasttrap_tpoints.fth_table = kmem_zalloc(fasttrap_tpoints.fth_nent *
 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
+#if !defined(sun)
+	for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
+		mutex_init(&fasttrap_tpoints.fth_table[i].ftb_mtx,
+		    "tracepoints bucket mtx", MUTEX_DEFAULT, NULL);
+#endif
 
 	/*
 	 * ... and the providers hash table...
@@ -2168,6 +2304,11 @@ fasttrap_attach(dev_info_t *devi, ddi_at
 	fasttrap_provs.fth_mask = fasttrap_provs.fth_nent - 1;
 	fasttrap_provs.fth_table = kmem_zalloc(fasttrap_provs.fth_nent *
 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
+#if !defined(sun)
+	for (i = 0; i < fasttrap_provs.fth_nent; i++)
+		mutex_init(&fasttrap_provs.fth_table[i].ftb_mtx, 
+		    "providers bucket mtx", MUTEX_DEFAULT, NULL);
+#endif
 
 	/*
 	 * ... and the procs hash table.
@@ -2181,27 +2322,22 @@ fasttrap_attach(dev_info_t *devi, ddi_at
 	fasttrap_procs.fth_mask = fasttrap_procs.fth_nent - 1;
 	fasttrap_procs.fth_table = kmem_zalloc(fasttrap_procs.fth_nent *
 	    sizeof (fasttrap_bucket_t), KM_SLEEP);
+#if !defined(sun)
+	for (i = 0; i < fasttrap_procs.fth_nent; i++)
+		mutex_init(&fasttrap_procs.fth_table[i].ftb_mtx,
+		    "processes bucket mtx", MUTEX_DEFAULT, NULL);
+#endif
 
 	(void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL,
 	    &fasttrap_meta_id);
 
-	return (DDI_SUCCESS);
+	return (0);
 }
 
 static int
-fasttrap_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
+fasttrap_unload(void)
 {
 	int i, fail = 0;
-	timeout_id_t tmp;
-
-	switch (cmd) {
-	case DDI_DETACH:
-		break;
-	case DDI_SUSPEND:
-		return (DDI_SUCCESS);
-	default:
-		return (DDI_FAILURE);
-	}
 
 	/*
 	 * Unregister the meta-provider to make sure no new fasttrap-
@@ -2212,28 +2348,16 @@ fasttrap_detach(dev_info_t *devi, ddi_de
 	 */
 	if (fasttrap_meta_id != DTRACE_METAPROVNONE &&
 	    dtrace_meta_unregister(fasttrap_meta_id) != 0)
-		return (DDI_FAILURE);
+		return (-1);
 
 	/*
 	 * Prevent any new timeouts from running by setting fasttrap_timeout
 	 * to a non-zero value, and wait for the current timeout to complete.
 	 */
-	mutex_enter(&fasttrap_cleanup_mtx);
-	fasttrap_cleanup_work = 0;
-
-	while (fasttrap_timeout != (timeout_id_t)1) {
-		tmp = fasttrap_timeout;
-		fasttrap_timeout = (timeout_id_t)1;
-
-		if (tmp != 0) {
-			mutex_exit(&fasttrap_cleanup_mtx);
-			(void) untimeout(tmp);
-			mutex_enter(&fasttrap_cleanup_mtx);
-		}
-	}
-
+	mtx_lock(&fasttrap_cleanup_mtx);
 	fasttrap_cleanup_work = 0;
-	mutex_exit(&fasttrap_cleanup_mtx);
+	callout_drain(&fasttrap_timeout);
+	mtx_unlock(&fasttrap_cleanup_mtx);
 
 	/*
 	 * Iterate over all of our providers. If there's still a process
@@ -2275,10 +2399,10 @@ fasttrap_detach(dev_info_t *devi, ddi_de
 		 * and start a new timeout if any work has accumulated while
 		 * we've been unsuccessfully trying to detach.
 		 */

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


More information about the svn-src-all mailing list