summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2015-06-07 20:45:13 +0000
committerpfg <pfg@FreeBSD.org>2015-06-07 20:45:13 +0000
commit5c276e329ddaed9d4f6f4210e9fb9d4c349081f6 (patch)
tree708f349665b266b6700da6e004fd10b3d648b843
parent0e7047f3cf7f81f1069743c80b4fc496de1b3620 (diff)
downloadFreeBSD-src-5c276e329ddaed9d4f6f4210e9fb9d4c349081f6.zip
FreeBSD-src-5c276e329ddaed9d4f6f4210e9fb9d4c349081f6.tar.gz
MFC r278166, MFV r266993:
4469 DTrace helper tracing should be dynamic Reference: https://illumos.org/issues/4469 Obtained from: Illumos Phabric: D1551 Reviewed by: markj
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c85
-rw-r--r--sys/cddl/dev/dtrace/dtrace_load.c11
-rw-r--r--sys/cddl/dev/dtrace/dtrace_unload.c5
3 files changed, 54 insertions, 47 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index cd7c6c4..5ce6166 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -351,17 +351,22 @@ dtrace_id_t dtrace_probeid_error; /* special ERROR probe */
/*
* DTrace Helper Tracing Variables
+ *
+ * These variables should be set dynamically to enable helper tracing. The
+ * only variables that should be set are dtrace_helptrace_enable (which should
+ * be set to a non-zero value to allocate helper tracing buffers on the next
+ * open of /dev/dtrace) and dtrace_helptrace_disable (which should be set to a
+ * non-zero value to deallocate helper tracing buffers on the next close of
+ * /dev/dtrace). When (and only when) helper tracing is disabled, the
+ * buffer size may also be set via dtrace_helptrace_bufsize.
*/
-uint32_t dtrace_helptrace_next = 0;
-uint32_t dtrace_helptrace_nlocals;
-char *dtrace_helptrace_buffer;
-int dtrace_helptrace_bufsize = 512 * 1024;
-
-#ifdef DEBUG
-int dtrace_helptrace_enabled = 1;
-#else
-int dtrace_helptrace_enabled = 0;
-#endif
+int dtrace_helptrace_enable = 0;
+int dtrace_helptrace_disable = 0;
+int dtrace_helptrace_bufsize = 16 * 1024 * 1024;
+uint32_t dtrace_helptrace_nlocals;
+static dtrace_helptrace_t *dtrace_helptrace_buffer;
+static uint32_t dtrace_helptrace_next = 0;
+static int dtrace_helptrace_wrapped = 0;
/*
* DTrace Error Hashing
@@ -15203,10 +15208,10 @@ dtrace_helper_trace(dtrace_helper_action_t *helper,
dtrace_mstate_t *mstate, dtrace_vstate_t *vstate, int where)
{
uint32_t size, next, nnext, i;
- dtrace_helptrace_t *ent;
+ dtrace_helptrace_t *ent, *buffer;
uint16_t flags = cpu_core[curcpu].cpuc_dtrace_flags;
- if (!dtrace_helptrace_enabled)
+ if ((buffer = dtrace_helptrace_buffer) == NULL)
return;
ASSERT(vstate->dtvs_nlocals <= dtrace_helptrace_nlocals);
@@ -15234,10 +15239,12 @@ dtrace_helper_trace(dtrace_helper_action_t *helper,
/*
* We have our slot; fill it in.
*/
- if (nnext == size)
+ if (nnext == size) {
+ dtrace_helptrace_wrapped++;
next = 0;
+ }
- ent = (dtrace_helptrace_t *)&dtrace_helptrace_buffer[next];
+ ent = (dtrace_helptrace_t *)((uintptr_t)buffer + next);
ent->dtht_helper = helper;
ent->dtht_where = where;
ent->dtht_nlocals = vstate->dtvs_nlocals;
@@ -15271,7 +15278,7 @@ dtrace_helper(int which, dtrace_mstate_t *mstate,
dtrace_helper_action_t *helper;
dtrace_vstate_t *vstate;
dtrace_difo_t *pred;
- int i, trace = dtrace_helptrace_enabled;
+ int i, trace = dtrace_helptrace_buffer != NULL;
ASSERT(which >= 0 && which < DTRACE_NHELPER_ACTIONS);
@@ -16674,17 +16681,6 @@ dtrace_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
mutex_exit(&cpu_lock);
/*
- * If DTrace helper tracing is enabled, we need to allocate the
- * trace buffer and initialize the values.
- */
- if (dtrace_helptrace_enabled) {
- ASSERT(dtrace_helptrace_buffer == NULL);
- dtrace_helptrace_buffer =
- kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
- dtrace_helptrace_next = 0;
- }
-
- /*
* If there are already providers, we must ask them to provide their
* probes, and then match any anonymous enabling against them. Note
* that there should be no other retained enablings at this time:
@@ -16797,6 +16793,18 @@ dtrace_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
return (EBUSY);
}
+ if (dtrace_helptrace_enable && dtrace_helptrace_buffer == NULL) {
+ /*
+ * If DTrace helper tracing is enabled, we need to allocate the
+ * trace buffer and initialize the values.
+ */
+ dtrace_helptrace_buffer =
+ kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
+ dtrace_helptrace_next = 0;
+ dtrace_helptrace_wrapped = 0;
+ dtrace_helptrace_enable = 0;
+ }
+
state = dtrace_state_create(devp, cred_p);
#else
state = dtrace_state_create(dev);
@@ -16833,7 +16841,10 @@ dtrace_dtr(void *data)
#if defined(sun)
minor_t minor = getminor(dev);
dtrace_state_t *state;
+#endif
+ dtrace_helptrace_t *buf = NULL;
+#ifdef illumos
if (minor == DTRACEMNRN_HELPER)
return (0);
@@ -16858,6 +16869,18 @@ dtrace_dtr(void *data)
dtrace_state_destroy(state->dts_anon);
}
+ if (dtrace_helptrace_disable) {
+ /*
+ * If we have been told to disable helper tracing, set the
+ * buffer to NULL before calling into dtrace_state_destroy();
+ * we take advantage of its dtrace_sync() to know that no
+ * CPU is in probe context with enabled helper tracing
+ * after it returns.
+ */
+ buf = dtrace_helptrace_buffer;
+ dtrace_helptrace_buffer = NULL;
+ }
+
#ifdef illumos
dtrace_state_destroy(state);
#else
@@ -16879,6 +16902,11 @@ dtrace_dtr(void *data)
--dtrace_opens;
#endif
+ if (buf != NULL) {
+ kmem_free(buf, dtrace_helptrace_bufsize);
+ dtrace_helptrace_disable = 0;
+ }
+
mutex_exit(&dtrace_lock);
mutex_exit(&cpu_lock);
@@ -17776,11 +17804,6 @@ dtrace_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
mutex_exit(&cpu_lock);
- if (dtrace_helptrace_enabled) {
- kmem_free(dtrace_helptrace_buffer, dtrace_helptrace_bufsize);
- dtrace_helptrace_buffer = NULL;
- }
-
kmem_free(dtrace_probes, dtrace_nprobes * sizeof (dtrace_probe_t *));
dtrace_probes = NULL;
dtrace_nprobes = 0;
diff --git a/sys/cddl/dev/dtrace/dtrace_load.c b/sys/cddl/dev/dtrace/dtrace_load.c
index 8a622c7..c49de55 100644
--- a/sys/cddl/dev/dtrace/dtrace_load.c
+++ b/sys/cddl/dev/dtrace/dtrace_load.c
@@ -137,17 +137,6 @@ dtrace_load(void *dummy)
mutex_exit(&cpu_lock);
- /*
- * If DTrace helper tracing is enabled, we need to allocate the
- * trace buffer and initialize the values.
- */
- if (dtrace_helptrace_enabled) {
- ASSERT(dtrace_helptrace_buffer == NULL);
- dtrace_helptrace_buffer =
- kmem_zalloc(dtrace_helptrace_bufsize, KM_SLEEP);
- dtrace_helptrace_next = 0;
- }
-
mutex_exit(&dtrace_lock);
mutex_exit(&dtrace_provider_lock);
diff --git a/sys/cddl/dev/dtrace/dtrace_unload.c b/sys/cddl/dev/dtrace/dtrace_unload.c
index da58b8db..b0d22e6 100644
--- a/sys/cddl/dev/dtrace/dtrace_unload.c
+++ b/sys/cddl/dev/dtrace/dtrace_unload.c
@@ -69,11 +69,6 @@ dtrace_unload()
mutex_exit(&cpu_lock);
- if (dtrace_helptrace_enabled) {
- kmem_free(dtrace_helptrace_buffer, 0);
- dtrace_helptrace_buffer = NULL;
- }
-
if (dtrace_probes != NULL) {
kmem_free(dtrace_probes, 0);
dtrace_probes = NULL;
OpenPOWER on IntegriCloud