Index: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c =================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c +++ head/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c @@ -7257,6 +7257,44 @@ } /* + * Disables interrupts and sets the per-thread inprobe flag. When DEBUG is + * defined, we also assert that we are not recursing unless the probe ID is an + * error probe. + */ +static dtrace_icookie_t +dtrace_probe_enter(dtrace_id_t id) +{ + dtrace_icookie_t cookie; + + cookie = dtrace_interrupt_disable(); + + /* + * Unless this is an ERROR probe, we are not allowed to recurse in + * dtrace_probe(). Recursing into DTrace probe usually means that a + * function is instrumented that should not have been instrumented or + * that the ordering guarantee of the records will be violated, + * resulting in unexpected output. If there is an exception to this + * assertion, a new case should be added. + */ + ASSERT(curthread->t_dtrace_inprobe == 0 || + id == dtrace_probeid_error); + curthread->t_dtrace_inprobe = 1; + + return (cookie); +} + +/* + * Disables interrupts and clears the per-thread inprobe flag. + */ +static void +dtrace_probe_exit(dtrace_icookie_t cookie) +{ + + curthread->t_dtrace_inprobe = 0; + dtrace_interrupt_enable(cookie); +} + +/* * If you're looking for the epicenter of DTrace, you just found it. This * is the function called by the provider to fire a probe -- from which all * subsequent probe-context DTrace activity emanates. @@ -7290,7 +7328,7 @@ return; #endif - cookie = dtrace_interrupt_disable(); + cookie = dtrace_probe_enter(id); probe = dtrace_probes[id - 1]; cpuid = curcpu; onintr = CPU_ON_INTR(CPU); @@ -7301,7 +7339,7 @@ * We have hit in the predicate cache; we know that * this predicate would evaluate to be false. */ - dtrace_interrupt_enable(cookie); + dtrace_probe_exit(cookie); return; } @@ -7313,7 +7351,7 @@ /* * We don't trace anything if we're panicking. */ - dtrace_interrupt_enable(cookie); + dtrace_probe_exit(cookie); return; } @@ -7939,7 +7977,7 @@ if (vtime) curthread->t_dtrace_start = dtrace_gethrtime(); - dtrace_interrupt_enable(cookie); + dtrace_probe_exit(cookie); } /* Index: head/sys/cddl/dev/dtrace/dtrace_cddl.h =================================================================== --- head/sys/cddl/dev/dtrace/dtrace_cddl.h +++ head/sys/cddl/dev/dtrace/dtrace_cddl.h @@ -46,6 +46,7 @@ typedef struct kdtrace_thread { u_int8_t td_dtrace_stop; /* Indicates a DTrace-desired stop */ u_int8_t td_dtrace_sig; /* Signal sent via DTrace's raise() */ + u_int8_t td_dtrace_inprobe; /* Are we in a probe? */ u_int td_predcache; /* DTrace predicate cache */ u_int64_t td_dtrace_vtime; /* DTrace virtual time */ u_int64_t td_dtrace_start; /* DTrace slice start time */ @@ -97,6 +98,7 @@ #define t_dtrace_start td_dtrace->td_dtrace_start #define t_dtrace_stop td_dtrace->td_dtrace_stop #define t_dtrace_sig td_dtrace->td_dtrace_sig +#define t_dtrace_inprobe td_dtrace->td_dtrace_inprobe #define t_predcache td_dtrace->td_predcache #define t_dtrace_ft td_dtrace->td_dtrace_ft #define t_dtrace_on td_dtrace->td_dtrace_on