Print this page
4469 DTrace helper tracing should be dynamic
*** 267,287 ****
static dtrace_id_t dtrace_probeid_end; /* special END probe */
dtrace_id_t dtrace_probeid_error; /* special ERROR probe */
/*
* DTrace Helper Tracing Variables
! */
! 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
/*
* DTrace Error Hashing
*
* On DEBUG kernels, DTrace will track the errors that has seen in a hash
--- 267,292 ----
static dtrace_id_t dtrace_probeid_end; /* special END probe */
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.
! */
! 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
*
* On DEBUG kernels, DTrace will track the errors that has seen in a hash
*** 14319,14332 ****
static void
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;
uint16_t flags = cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
! if (!dtrace_helptrace_enabled)
return;
ASSERT(vstate->dtvs_nlocals <= dtrace_helptrace_nlocals);
/*
--- 14324,14337 ----
static void
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, *buffer;
uint16_t flags = cpu_core[CPU->cpu_id].cpuc_dtrace_flags;
! if ((buffer = dtrace_helptrace_buffer) == NULL)
return;
ASSERT(vstate->dtvs_nlocals <= dtrace_helptrace_nlocals);
/*
*** 14350,14363 ****
} while (dtrace_cas32(&dtrace_helptrace_next, next, nnext) != next);
/*
* We have our slot; fill it in.
*/
! if (nnext == size)
next = 0;
! ent = (dtrace_helptrace_t *)&dtrace_helptrace_buffer[next];
ent->dtht_helper = helper;
ent->dtht_where = where;
ent->dtht_nlocals = vstate->dtvs_nlocals;
ent->dtht_fltoffs = (mstate->dtms_present & DTRACE_MSTATE_FLTOFFS) ?
--- 14355,14370 ----
} while (dtrace_cas32(&dtrace_helptrace_next, next, nnext) != next);
/*
* We have our slot; fill it in.
*/
! if (nnext == size) {
! dtrace_helptrace_wrapped++;
next = 0;
+ }
! ent = (dtrace_helptrace_t *)((uintptr_t)buffer + next);
ent->dtht_helper = helper;
ent->dtht_where = where;
ent->dtht_nlocals = vstate->dtvs_nlocals;
ent->dtht_fltoffs = (mstate->dtms_present & DTRACE_MSTATE_FLTOFFS) ?
*** 14387,14397 ****
uint64_t rval;
dtrace_helpers_t *helpers = curproc->p_dtrace_helpers;
dtrace_helper_action_t *helper;
dtrace_vstate_t *vstate;
dtrace_difo_t *pred;
! int i, trace = dtrace_helptrace_enabled;
ASSERT(which >= 0 && which < DTRACE_NHELPER_ACTIONS);
if (helpers == NULL)
return (0);
--- 14394,14404 ----
uint64_t rval;
dtrace_helpers_t *helpers = curproc->p_dtrace_helpers;
dtrace_helper_action_t *helper;
dtrace_vstate_t *vstate;
dtrace_difo_t *pred;
! int i, trace = dtrace_helptrace_buffer != NULL;
ASSERT(which >= 0 && which < DTRACE_NHELPER_ACTIONS);
if (helpers == NULL)
return (0);
*** 15704,15724 ****
dtrace_anon_property();
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:
* the only retained enablings at this time should be the anonymous
* enabling.
--- 15711,15720 ----
*** 15810,15819 ****
--- 15806,15827 ----
mutex_exit(&cpu_lock);
mutex_exit(&dtrace_lock);
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);
mutex_exit(&cpu_lock);
if (state == NULL) {
if (--dtrace_opens == 0 && dtrace_anon.dta_enabling == NULL)
*** 15831,15840 ****
--- 15839,15849 ----
static int
dtrace_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
{
minor_t minor = getminor(dev);
dtrace_state_t *state;
+ dtrace_helptrace_t *buf = NULL;
if (minor == DTRACEMNRN_HELPER)
return (0);
state = ddi_get_soft_state(dtrace_softstate, minor);
*** 15848,15867 ****
--- 15857,15893 ----
*/
ASSERT(dtrace_anon.dta_state == NULL);
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;
+ }
+
dtrace_state_destroy(state);
ASSERT(dtrace_opens > 0);
/*
* Only relinquish control of the kernel debugger interface when there
* are no consumers and no anonymous enablings.
*/
if (--dtrace_opens == 0 && dtrace_anon.dta_enabling == NULL)
(void) kdi_dtrace_set(KDI_DTSET_DTRACE_DEACTIVATE);
+ if (buf != NULL) {
+ kmem_free(buf, dtrace_helptrace_bufsize);
+ dtrace_helptrace_disable = 0;
+ }
+
mutex_exit(&dtrace_lock);
mutex_exit(&cpu_lock);
return (0);
}
*** 16751,16765 ****
ASSERT(dtrace_getf == 0);
ASSERT(dtrace_closef == NULL);
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;
dtrace_hash_destroy(dtrace_bymod);
--- 16777,16786 ----