Author: pfg
Date: Mon Apr  1 19:13:46 2013
New Revision: 248983
URL: http://svnweb.freebsd.org/changeset/base/248983

Log:
  Dtrace: enablings on defunct providers prevent providers from unregistering
  
  Merge change from illumos:
  
  1368 enablings on defunct providers prevent providers from unregistering
  
  We try to address some underlying differences between the Solaris
  and FreeBSD implementations: dtrace_attach() / dtrace_detach() are
  currently unimplemented in FreeBSD but the new code from illumos
  makes use of taskq so some adaptations were made to dtrace_open()
  and dtrace_close() to handle them appropriately.
  
  Illumos Revision:     r13430:8e6add739e38
  
  Reference:
  https://www.illumos.org/issues/1368
  
  Reviewed by:  gnn
  Tested by:    Fabian Keil
  Obtained from:        Illumos
  MFC after:    3 weeks

Added:
  head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh
     - copied unchanged from r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh
  
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
     - copied unchanged from r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
  head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh
     - copied unchanged from r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh
Modified:
  head/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
  head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
  head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
  head/sys/modules/dtrace/dtrace/Makefile

Modified: 
head/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst
==============================================================================
--- head/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst     
Mon Apr  1 19:11:43 2013        (r248982)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/cmd/jdtrace/exception.lst     
Mon Apr  1 19:13:46 2013        (r248983)
@@ -23,7 +23,6 @@
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
-# ident        "%Z%%M% %I%     %E% SMI"
 
 # Exception list: names tests that are bypassed when running in Java
 # mode (relative to /opt/SUNWdtrt/tst)
@@ -52,14 +51,17 @@ common/usdt/tst.enabled.ksh
 common/usdt/tst.enabled2.ksh
 common/usdt/tst.entryreturn.ksh
 common/usdt/tst.fork.ksh
-common/usdt/tst.header.ksh
 common/usdt/tst.guess32.ksh
 common/usdt/tst.guess64.ksh
+common/usdt/tst.header.ksh
 common/usdt/tst.linkpriv.ksh
 common/usdt/tst.linkunpriv.ksh
 common/usdt/tst.multiple.ksh
 common/usdt/tst.nodtrace.ksh
+common/usdt/tst.noreap.ksh
+common/usdt/tst.noreapring.ksh
 common/usdt/tst.onlyenabled.ksh
+common/usdt/tst.reap.ksh
 common/usdt/tst.reeval.ksh
 common/usdt/tst.static.ksh
 common/usdt/tst.static2.ksh

Copied: 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh 
(from r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh    
    Mon Apr  1 19:13:46 2013        (r248983, copy of r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreap.ksh)
@@ -0,0 +1,128 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+       echo expected one argument: '<'dtrace-path'>'
+       exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+       DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+       probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+       print -u2 "failed to compile test.c"
+       exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to create DOF"
+       exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to link final executable"
+       exit 1
+fi
+
+script()
+{
+       $dtrace -Zwqs /dev/stdin <<EOF
+
+       BEGIN
+       {
+               spec = speculation();
+               speculate(spec);
+               printf("this is speculative!\n");
+       }
+
+       test_prov*:::
+       {
+               probeid = id;
+       }
+
+       tick-1sec
+       /probeid == 0/
+       {
+               printf("launching test\n");
+               system("./test");
+       }
+
+       tick-1sec
+       /probeid != 0/
+       {
+               printf("attempting re-enabling\n");
+               system("dtrace -e -x errtags -i %d", probeid);
+               attempts++;
+       }
+
+       tick-1sec
+       /attempts > 10/
+       {
+               exit(0);
+       }
+EOF
+}
+
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was not reaped after the provider was made
+# defunct: the speculative tracing action prevents reaping of any ECB in the
+# enabling.
+# 
+status=0
+
+if grep D_PDESC_INVAL test.out 2> /dev/null 1>&2 ; then
+       status=1
+else
+       grep D_PROC_GRAB test.out 2> /dev/null 1>&2
+       status=$?
+fi
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status

Copied: 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
 (from r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh
    Mon Apr  1 19:13:46 2013        (r248983, copy of r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.noreapring.ksh)
@@ -0,0 +1,124 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+       echo expected one argument: '<'dtrace-path'>'
+       exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+       DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+       probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+       print -u2 "failed to compile test.c"
+       exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to create DOF"
+       exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to link final executable"
+       exit 1
+fi
+
+script()
+{
+       $dtrace -Zwqs /dev/stdin <<EOF
+       test_prov*:::
+       {
+               probeid = id;
+       }
+
+       tick-1sec
+       /probeid == 0/
+       {
+               printf("launching test\n");
+               system("./test");
+       }
+
+       tick-1sec
+       /probeid != 0/
+       {
+               printf("attempting re-enabling\n");
+               system("dtrace -e -x errtags -i %d", probeid);
+               attempts++;
+       }
+
+       tick-1sec
+       /attempts > 10/
+       {
+               exit(0);
+       }
+EOF
+}
+
+$dtrace -x bufpolicy=ring -ZwqP test_prov\* > /dev/null 2>&1 &
+background=$!
+echo launched ring buffered enabling as pid $background
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was not reaped after the provider was made
+# defunct: the active ring buffer in the earlier enabling prevents reaping of
+# any of the earlier enabling's ECBs.
+# 
+status=0
+
+if grep D_PDESC_INVAL test.out 2> /dev/null 1>&2 ; then
+       status=1
+else
+       grep D_PROC_GRAB test.out 2> /dev/null 1>&2
+       status=$?
+fi
+
+kill $background
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status

Copied: 
head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh 
(from r248981, vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh  
Mon Apr  1 19:13:46 2013        (r248983, copy of r248981, 
vendor/illumos/dist/cmd/dtrace/test/tst/common/usdt/tst.reap.ksh)
@@ -0,0 +1,115 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Joyent, Inc. All rights reserved.
+#
+
+if [ $# != 1 ]; then
+       echo expected one argument: '<'dtrace-path'>'
+       exit 2
+fi
+
+dtrace=$1
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.c <<EOF
+#include <unistd.h>
+#include <sys/sdt.h>
+
+int
+main(int argc, char **argv)
+{
+       DTRACE_PROBE(test_prov, probe1);
+}
+EOF
+
+cat > prov.d <<EOF
+provider test_prov {
+       probe probe1();
+};
+EOF
+
+gcc -c test.c
+if [ $? -ne 0 ]; then
+       print -u2 "failed to compile test.c"
+       exit 1
+fi
+$dtrace -G -32 -s prov.d test.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to create DOF"
+       exit 1
+fi
+gcc -o test test.o prov.o
+if [ $? -ne 0 ]; then
+       print -u2 "failed to link final executable"
+       exit 1
+fi
+
+script()
+{
+       $dtrace -Zwqs /dev/stdin <<EOF
+       test_prov*:::
+       {
+               probeid = id;
+       }
+
+       tick-1sec
+       /probeid == 0/
+       {
+               printf("launching test\n");
+               system("./test");
+       }
+
+       tick-1sec
+       /probeid != 0/
+       {
+               printf("attempting re-enabling\n");
+               system("dtrace -e -x errtags -i %d", probeid);
+               attempts++;
+       }
+
+       tick-1sec
+       /attempts > 10/
+       {
+               exit(0);
+       }
+EOF
+}
+
+script 2>&1 | tee test.out
+
+#
+# It should be true that our probe was reaped over the course of the enabling,
+# causing the embedded DTrace invocation to fail on an invalid probe (that is,
+# D_PDESC_INVAL) instead of an inability to grab the underlying process
+# (D_PROC_GRAB).
+# 
+grep D_PDESC_INVAL test.out 2> /dev/null 1>&2
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Mon Apr 
 1 19:11:43 2013        (r248982)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c        Mon Apr 
 1 19:13:46 2013        (r248983)
@@ -182,6 +182,7 @@ int         dtrace_err_verbose;
 hrtime_t       dtrace_deadman_interval = NANOSEC;
 hrtime_t       dtrace_deadman_timeout = (hrtime_t)10 * NANOSEC;
 hrtime_t       dtrace_deadman_user = (hrtime_t)30 * NANOSEC;
+hrtime_t       dtrace_unregister_defunct_reap = (hrtime_t)60 * NANOSEC;
 
 /*
  * DTrace External Variables
@@ -203,8 +204,8 @@ static dev_info_t   *dtrace_devi;           /* devi
 #if defined(sun)
 static vmem_t          *dtrace_arena;          /* probe ID arena */
 static vmem_t          *dtrace_minor;          /* minor number arena */
-static taskq_t         *dtrace_taskq;          /* task queue */
 #else
+static taskq_t         *dtrace_taskq;          /* task queue */
 static struct unrhdr   *dtrace_arena;          /* Probe ID number.     */
 #endif
 static dtrace_probe_t  **dtrace_probes;        /* array of all probes */
@@ -550,11 +551,13 @@ static dtrace_probe_t *dtrace_probe_look
 static void dtrace_enabling_provide(dtrace_provider_t *);
 static int dtrace_enabling_match(dtrace_enabling_t *, int *);
 static void dtrace_enabling_matchall(void);
+static void dtrace_enabling_reap(void);
 static dtrace_state_t *dtrace_anon_grab(void);
 static uint64_t dtrace_helper(int, dtrace_mstate_t *,
     dtrace_state_t *, uint64_t, uint64_t);
 static dtrace_helpers_t *dtrace_helpers_create(proc_t *);
 static void dtrace_buffer_drop(dtrace_buffer_t *);
+static int dtrace_buffer_consumed(dtrace_buffer_t *, hrtime_t when);
 static intptr_t dtrace_buffer_reserve(dtrace_buffer_t *, size_t, size_t,
     dtrace_state_t *, dtrace_mstate_t *);
 static int dtrace_state_option(dtrace_state_t *, dtrace_optid_t,
@@ -7593,7 +7596,7 @@ dtrace_unregister(dtrace_provider_id_t i
 {
        dtrace_provider_t *old = (dtrace_provider_t *)id;
        dtrace_provider_t *prev = NULL;
-       int i, self = 0;
+       int i, self = 0, noreap = 0;
        dtrace_probe_t *probe, *first = NULL;
 
        if (old->dtpv_pops.dtps_enable ==
@@ -7652,14 +7655,31 @@ dtrace_unregister(dtrace_provider_id_t i
                        continue;
 
                /*
-                * We have at least one ECB; we can't remove this provider.
-                */
+                * If we are trying to unregister a defunct provider, and the
+                * provider was made defunct within the interval dictated by
+                * dtrace_unregister_defunct_reap, we'll (asynchronously)
+                * attempt to reap our enablings.  To denote that the provider
+                * should reattempt to unregister itself at some point in the
+                * future, we will return a differentiable error code (EAGAIN
+                * instead of EBUSY) in this case.
+                */
+               if (dtrace_gethrtime() - old->dtpv_defunct >
+                   dtrace_unregister_defunct_reap)
+                       noreap = 1;
+
                if (!self) {
                        mutex_exit(&dtrace_lock);
                        mutex_exit(&mod_lock);
                        mutex_exit(&dtrace_provider_lock);
                }
-               return (EBUSY);
+
+               if (noreap)
+                       return (EBUSY);
+
+               (void) taskq_dispatch(dtrace_taskq,
+                   (task_func_t *)dtrace_enabling_reap, NULL, TQ_SLEEP);
+
+               return (EAGAIN);
        }
 
        /*
@@ -7756,7 +7776,7 @@ dtrace_invalidate(dtrace_provider_id_t i
        mutex_enter(&dtrace_provider_lock);
        mutex_enter(&dtrace_lock);
 
-       pvp->dtpv_defunct = 1;
+       pvp->dtpv_defunct = dtrace_gethrtime();
 
        mutex_exit(&dtrace_lock);
        mutex_exit(&dtrace_provider_lock);
@@ -10719,6 +10739,7 @@ dtrace_buffer_switch(dtrace_buffer_t *bu
        caddr_t tomax = buf->dtb_tomax;
        caddr_t xamot = buf->dtb_xamot;
        dtrace_icookie_t cookie;
+       hrtime_t now = dtrace_gethrtime();
 
        ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
        ASSERT(!(buf->dtb_flags & DTRACEBUF_RING));
@@ -10734,6 +10755,8 @@ dtrace_buffer_switch(dtrace_buffer_t *bu
        buf->dtb_drops = 0;
        buf->dtb_errors = 0;
        buf->dtb_flags &= ~(DTRACEBUF_ERROR | DTRACEBUF_DROPPED);
+       buf->dtb_interval = now - buf->dtb_switched;
+       buf->dtb_switched = now;
        dtrace_interrupt_enable(cookie);
 }
 
@@ -11222,6 +11245,36 @@ dtrace_buffer_polish(dtrace_buffer_t *bu
        }
 }
 
+/*
+ * This routine determines if data generated at the specified time has likely
+ * been entirely consumed at user-level.  This routine is called to determine
+ * if an ECB on a defunct probe (but for an active enabling) can be safely
+ * disabled and destroyed.
+ */
+static int
+dtrace_buffer_consumed(dtrace_buffer_t *bufs, hrtime_t when)
+{
+       int i;
+
+       for (i = 0; i < NCPU; i++) {
+               dtrace_buffer_t *buf = &bufs[i];
+
+               if (buf->dtb_size == 0)
+                       continue;
+
+               if (buf->dtb_flags & DTRACEBUF_RING)
+                       return (0);
+
+               if (!buf->dtb_switched && buf->dtb_offset != 0)
+                       return (0);
+
+               if (buf->dtb_switched - buf->dtb_interval < when)
+                       return (0);
+       }
+
+       return (1);
+}
+
 static void
 dtrace_buffer_free(dtrace_buffer_t *bufs)
 {
@@ -11693,6 +11746,85 @@ dtrace_enabling_provide(dtrace_provider_
 }
 
 /*
+ * Called to reap ECBs that are attached to probes from defunct providers.
+ */
+static void
+dtrace_enabling_reap(void)
+{
+       dtrace_provider_t *prov;
+       dtrace_probe_t *probe;
+       dtrace_ecb_t *ecb;
+       hrtime_t when;
+       int i;
+
+       mutex_enter(&cpu_lock);
+       mutex_enter(&dtrace_lock);
+
+       for (i = 0; i < dtrace_nprobes; i++) {
+               if ((probe = dtrace_probes[i]) == NULL)
+                       continue;
+
+               if (probe->dtpr_ecb == NULL)
+                       continue;
+
+               prov = probe->dtpr_provider;
+
+               if ((when = prov->dtpv_defunct) == 0)
+                       continue;
+
+               /*
+                * We have ECBs on a defunct provider:  we want to reap these
+                * ECBs to allow the provider to unregister.  The destruction
+                * of these ECBs must be done carefully:  if we destroy the ECB
+                * and the consumer later wishes to consume an EPID that
+                * corresponds to the destroyed ECB (and if the EPID metadata
+                * has not been previously consumed), the consumer will abort
+                * processing on the unknown EPID.  To reduce (but not, sadly,
+                * eliminate) the possibility of this, we will only destroy an
+                * ECB for a defunct provider if, for the state that
+                * corresponds to the ECB:
+                *
+                *  (a) There is no speculative tracing (which can effectively
+                *      cache an EPID for an arbitrary amount of time).
+                *
+                *  (b) The principal buffers have been switched twice since the
+                *      provider became defunct.
+                *
+                *  (c) The aggregation buffers are of zero size or have been
+                *      switched twice since the provider became defunct.
+                *
+                * We use dts_speculates to determine (a) and call a function
+                * (dtrace_buffer_consumed()) to determine (b) and (c).  Note
+                * that as soon as we've been unable to destroy one of the ECBs
+                * associated with the probe, we quit trying -- reaping is only
+                * fruitful in as much as we can destroy all ECBs associated
+                * with the defunct provider's probes.
+                */
+               while ((ecb = probe->dtpr_ecb) != NULL) {
+                       dtrace_state_t *state = ecb->dte_state;
+                       dtrace_buffer_t *buf = state->dts_buffer;
+                       dtrace_buffer_t *aggbuf = state->dts_aggbuffer;
+
+                       if (state->dts_speculates)
+                               break;
+
+                       if (!dtrace_buffer_consumed(buf, when))
+                               break;
+
+                       if (!dtrace_buffer_consumed(aggbuf, when))
+                               break;
+
+                       dtrace_ecb_disable(ecb);
+                       ASSERT(probe->dtpr_ecb != ecb);
+                       dtrace_ecb_destroy(ecb);
+               }
+       }
+
+       mutex_exit(&dtrace_lock);
+       mutex_exit(&cpu_lock);
+}
+
+/*
  * DTrace DOF Functions
  */
 /*ARGSUSED*/
@@ -15529,6 +15661,10 @@ dtrace_open(struct cdev *dev, int oflags
 #else
        devfs_set_cdevpriv(state, dtrace_dtr);
 #endif
+       /* This code actually belongs in dtrace_attach() */
+       if (dtrace_opens == 1)
+               dtrace_taskq = taskq_create("dtrace_taskq", 1, maxclsyspri,
+                   1, INT_MAX, 0);
 #endif
 
        mutex_exit(&cpu_lock);
@@ -15616,6 +15752,11 @@ dtrace_dtr(void *data)
                (void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
 #else
        --dtrace_opens;
+       /* This code actually belongs in dtrace_detach() */
+       if ((dtrace_opens == 0) && (dtrace_taskq != NULL)) {
+               taskq_destroy(dtrace_taskq);
+               dtrace_taskq = NULL;
+       }
 #endif
 
        mutex_exit(&dtrace_lock);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c      Mon Apr 
 1 19:11:43 2013        (r248982)
+++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c      Mon Apr 
 1 19:13:46 2013        (r248983)
@@ -175,6 +175,9 @@ static volatile uint64_t fasttrap_mod_ge
 static uint32_t fasttrap_max;
 static uint32_t fasttrap_total;
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
 
 #define        FASTTRAP_TPOINTS_DEFAULT_SIZE   0x4000
 #define        FASTTRAP_PROVIDERS_DEFAULT_SIZE 0x100
@@ -317,7 +320,7 @@ fasttrap_pid_cleanup_cb(void *data)
        fasttrap_provider_t **fpp, *fp;
        fasttrap_bucket_t *bucket;
        dtrace_provider_id_t provid;
-       int i, later = 0;
+       int i, later = 0, rval;
 
        static volatile int in = 0;
        ASSERT(in == 0);
@@ -378,9 +381,13 @@ fasttrap_pid_cleanup_cb(void *data)
                                 * clean out the unenabled probes.
                                 */
                                provid = fp->ftp_provid;
-                               if (dtrace_unregister(provid) != 0) {
+                               if ((rval = dtrace_unregister(provid)) != 0) {
                                        if (fasttrap_total > fasttrap_max / 2)
                                                (void) dtrace_condense(provid);
+
+                                       if (rval == EAGAIN)
+                                               fp->ftp_marked = 1;
+
                                        later += fp->ftp_marked;
                                        fpp = &fp->ftp_next;
                                } else {
@@ -408,12 +415,15 @@ 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 && callout_active(&fasttrap_timeout))
-               callout_reset(&fasttrap_timeout, hz, &fasttrap_pid_cleanup_cb,
-                   NULL);
+       if (later > 0) {
+               if (callout_active(&fasttrap_timeout)) {
+                       callout_reset(&fasttrap_timeout, hz,
+                           &fasttrap_pid_cleanup_cb, NULL);
+               }
+ 
        else if (later > 0)
                fasttrap_cleanup_work = 1;
-       else {
+       } else {
 #if !defined(sun)
                /* Nothing to be done for FreeBSD */
 #endif

Modified: head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h      Mon Apr 
 1 19:11:43 2013        (r248982)
+++ head/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h      Mon Apr 
 1 19:13:46 2013        (r248983)
@@ -26,11 +26,13 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2011, Joyent, Inc. All rights reserved.
+ */
+
 #ifndef _SYS_DTRACE_IMPL_H
 #define        _SYS_DTRACE_IMPL_H
 
-#pragma ident  "%Z%%M% %I%     %E% SMI"
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -429,8 +431,11 @@ typedef struct dtrace_buffer {
        uint32_t dtb_errors;                    /* number of errors */
        uint32_t dtb_xamot_errors;              /* errors in inactive buffer */
 #ifndef _LP64
-       uint64_t dtb_pad1;
+       uint64_t dtb_pad1;                      /* pad out to 64 bytes */
 #endif
+       uint64_t dtb_switched;                  /* time of last switch */
+       uint64_t dtb_interval;                  /* observed switch interval */
+       uint64_t dtb_pad2[6];                   /* pad to avoid false sharing */
 } dtrace_buffer_t;
 
 /*
@@ -1162,7 +1167,7 @@ struct dtrace_provider {
        dtrace_pops_t dtpv_pops;                /* provider operations */
        char *dtpv_name;                        /* provider name */
        void *dtpv_arg;                         /* provider argument */
-       uint_t dtpv_defunct;                    /* boolean: defunct provider */
+       hrtime_t dtpv_defunct;                  /* when made defunct */
        struct dtrace_provider *dtpv_next;      /* next provider */
 };
 

Modified: head/sys/modules/dtrace/dtrace/Makefile
==============================================================================
--- head/sys/modules/dtrace/dtrace/Makefile     Mon Apr  1 19:11:43 2013        
(r248982)
+++ head/sys/modules/dtrace/dtrace/Makefile     Mon Apr  1 19:13:46 2013        
(r248983)
@@ -3,6 +3,7 @@
 ARCHDIR=       ${MACHINE_CPUARCH}
 
 .PATH: ${.CURDIR}/../../../cddl/contrib/opensolaris/uts/common/dtrace
+.PATH: ${.CURDIR}/../../../cddl/compat/opensolaris/kern
 .PATH: ${.CURDIR}/../../../cddl/kern
 .PATH: ${.CURDIR}/../../../cddl/dev/dtrace
 .PATH: ${.CURDIR}/../../../cddl/dev/dtrace/${ARCHDIR}
@@ -26,6 +27,9 @@ SRCS+=                assym.s
 # These are needed for assym.s
 SRCS+=         opt_compat.h opt_kstack_pages.h opt_nfs.h opt_hwpmc_hooks.h
 
+#This is needed for dtrace.c
+SRCS +=        opensolaris_taskq.c
+
 .if ${MACHINE_CPUARCH} == "i386"
 SRCS+=         opt_apic.h
 .endif
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to