From owner-svn-src-all@FreeBSD.ORG Tue Aug 24 11:11:58 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E2ADB1065675; Tue, 24 Aug 2010 11:11:58 +0000 (UTC) (envelope-from rpaulo@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D08B08FC19; Tue, 24 Aug 2010 11:11:58 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7OBBwkw074033; Tue, 24 Aug 2010 11:11:58 GMT (envelope-from rpaulo@svn.freebsd.org) Received: (from rpaulo@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7OBBwvn074031; Tue, 24 Aug 2010 11:11:58 GMT (envelope-from rpaulo@svn.freebsd.org) Message-Id: <201008241111.o7OBBwvn074031@svn.freebsd.org> From: Rui Paulo Date: Tue, 24 Aug 2010 11:11:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211738 - head/sys/cddl/contrib/opensolaris/uts/common/dtrace X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Aug 2010 11:11:59 -0000 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 #include @@ -32,11 +38,15 @@ #include #include #include +#if defined(sun) #include +#endif #include #include #include +#if defined(sun) #include +#endif #include #include #include @@ -44,9 +54,17 @@ #include #include #include -#include #include +#if defined(sun) #include +#endif +#include +#include +#if !defined(sun) +#include +#include +#include +#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 ***