[Midnightbsd-cvs] src [9156] trunk/sys/cddl/contrib/opensolaris/uts/common: sync with freebsd 9.2
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Thu Oct 13 22:04:52 EDT 2016
Revision: 9156
http://svnweb.midnightbsd.org/src/?rev=9156
Author: laffer1
Date: 2016-10-13 22:04:51 -0400 (Thu, 13 Oct 2016)
Log Message:
-----------
sync with freebsd 9.2
Modified Paths:
--------------
trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_mod.c
trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_subr.c
trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
Modified: trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_mod.c
===================================================================
--- trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_mod.c 2016-10-14 02:04:39 UTC (rev 9155)
+++ trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_mod.c 2016-10-14 02:04:51 UTC (rev 9156)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
/*
* CDDL HEADER START
*
Modified: trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_subr.c
===================================================================
--- trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_subr.c 2016-10-14 02:04:39 UTC (rev 9155)
+++ trunk/sys/cddl/contrib/opensolaris/uts/common/ctf/ctf_subr.c 2016-10-14 02:04:51 UTC (rev 9156)
@@ -1,4 +1,3 @@
-/* $MidnightBSD$ */
/*
* CDDL HEADER START
*
Modified: trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
===================================================================
--- trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 2016-10-14 02:04:39 UTC (rev 9155)
+++ trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 2016-10-14 02:04:51 UTC (rev 9156)
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * $MidnightBSD$
+ * $FreeBSD: release/9.2.0/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 250484 2013-05-10 21:12:55Z pfg $
*/
/*
@@ -182,6 +182,7 @@
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 @@
#if defined(sun)
static vmem_t *dtrace_arena; /* probe ID arena */
static vmem_t *dtrace_minor; /* minor number arena */
+#else
static taskq_t *dtrace_taskq; /* task queue */
-#else
static struct unrhdr *dtrace_arena; /* Probe ID number. */
#endif
static dtrace_probe_t **dtrace_probes; /* array of all probes */
@@ -443,7 +444,7 @@
#define DTRACE_STORE(type, tomax, offset, what) \
*((type *)((uintptr_t)(tomax) + (uintptr_t)offset)) = (type)(what);
-#ifndef __i386
+#ifndef __x86
#define DTRACE_ALIGNCHECK(addr, size, flags) \
if (addr & (size - 1)) { \
*flags |= CPU_DTRACE_BADALIGN; \
@@ -550,11 +551,13 @@
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,
@@ -4019,6 +4022,53 @@
break;
}
+ case DIF_SUBR_TOUPPER:
+ case DIF_SUBR_TOLOWER: {
+ uintptr_t s = tupregs[0].dttk_value;
+ uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
+ char *dest = (char *)mstate->dtms_scratch_ptr, c;
+ size_t len = dtrace_strlen((char *)s, size);
+ char lower, upper, convert;
+ int64_t i;
+
+ if (subr == DIF_SUBR_TOUPPER) {
+ lower = 'a';
+ upper = 'z';
+ convert = 'A';
+ } else {
+ lower = 'A';
+ upper = 'Z';
+ convert = 'a';
+ }
+
+ if (!dtrace_canload(s, len + 1, mstate, vstate)) {
+ regs[rd] = 0;
+ break;
+ }
+
+ if (!DTRACE_INSCRATCH(mstate, size)) {
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
+ regs[rd] = 0;
+ break;
+ }
+
+ for (i = 0; i < size - 1; i++) {
+ if ((c = dtrace_load8(s + i)) == '\0')
+ break;
+
+ if (c >= lower && c <= upper)
+ c = convert + (c - lower);
+
+ dest[i] = c;
+ }
+
+ ASSERT(i < size);
+ dest[i] = '\0';
+ regs[rd] = (uintptr_t)dest;
+ mstate->dtms_scratch_ptr += size;
+ break;
+ }
+
#if defined(sun)
case DIF_SUBR_GETMAJOR:
#ifdef _LP64
@@ -4283,10 +4333,21 @@
case DIF_SUBR_LLTOSTR: {
int64_t i = (int64_t)tupregs[0].dttk_value;
- int64_t val = i < 0 ? i * -1 : i;
- uint64_t size = 22; /* enough room for 2^64 in decimal */
+ uint64_t val, digit;
+ uint64_t size = 65; /* enough room for 2^64 in binary */
char *end = (char *)mstate->dtms_scratch_ptr + size - 1;
+ int base = 10;
+ if (nargs > 1) {
+ if ((base = tupregs[1].dttk_value) <= 1 ||
+ base > ('z' - 'a' + 1) + ('9' - '0' + 1)) {
+ *flags |= CPU_DTRACE_ILLOP;
+ break;
+ }
+ }
+
+ val = (base == 10 && i < 0) ? i * -1 : i;
+
if (!DTRACE_INSCRATCH(mstate, size)) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
regs[rd] = 0;
@@ -4293,13 +4354,24 @@
break;
}
- for (*end-- = '\0'; val; val /= 10)
- *end-- = '0' + (val % 10);
+ for (*end-- = '\0'; val; val /= base) {
+ if ((digit = val % base) <= '9' - '0') {
+ *end-- = '0' + digit;
+ } else {
+ *end-- = 'a' + (digit - ('9' - '0') - 1);
+ }
+ }
- if (i == 0)
+ if (i == 0 && base == 16)
*end-- = '0';
- if (i < 0)
+ if (base == 16)
+ *end-- = 'x';
+
+ if (i == 0 || base == 8 || base == 16)
+ *end-- = '0';
+
+ if (i < 0 && base == 10)
*end-- = '-';
regs[rd] = (uintptr_t)end + 1;
@@ -6015,6 +6087,7 @@
dtrace_buffer_t *aggbuf = &state->dts_aggbuffer[cpuid];
dtrace_vstate_t *vstate = &state->dts_vstate;
dtrace_provider_t *prov = probe->dtpr_provider;
+ uint64_t tracememsize = 0;
int committed = 0;
caddr_t tomax;
@@ -6466,8 +6539,13 @@
case DTRACEACT_PRINTA:
case DTRACEACT_SYSTEM:
case DTRACEACT_FREOPEN:
+ case DTRACEACT_TRACEMEM:
break;
+ case DTRACEACT_TRACEMEM_DYNSIZE:
+ tracememsize = val;
+ break;
+
case DTRACEACT_SYM:
case DTRACEACT_MOD:
if (!dtrace_priv_kernel(state))
@@ -6537,6 +6615,12 @@
if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF) {
uintptr_t end = valoffs + size;
+ if (tracememsize != 0 &&
+ valoffs + tracememsize < end) {
+ end = valoffs + tracememsize;
+ tracememsize = 0;
+ }
+
if (!dtrace_vcanload((void *)(uintptr_t)val,
&dp->dtdo_rtype, &mstate, vstate))
continue;
@@ -7512,7 +7596,7 @@
{
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 ==
@@ -7571,14 +7655,31 @@
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);
}
/*
@@ -7675,7 +7776,7 @@
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);
@@ -10128,12 +10229,14 @@
case DTRACEACT_PRINTA:
case DTRACEACT_SYSTEM:
case DTRACEACT_FREOPEN:
+ case DTRACEACT_DIFEXPR:
/*
* We know that our arg is a string -- turn it into a
* format.
*/
if (arg == 0) {
- ASSERT(desc->dtad_kind == DTRACEACT_PRINTA);
+ ASSERT(desc->dtad_kind == DTRACEACT_PRINTA ||
+ desc->dtad_kind == DTRACEACT_DIFEXPR);
format = 0;
} else {
ASSERT(arg != 0);
@@ -10146,7 +10249,8 @@
/*FALLTHROUGH*/
case DTRACEACT_LIBACT:
- case DTRACEACT_DIFEXPR:
+ case DTRACEACT_TRACEMEM:
+ case DTRACEACT_TRACEMEM_DYNSIZE:
if (dp == NULL)
return (EINVAL);
@@ -10635,6 +10739,7 @@
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));
@@ -10650,6 +10755,8 @@
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);
}
@@ -11138,6 +11245,36 @@
}
}
+/*
+ * 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)
{
@@ -11609,6 +11746,85 @@
}
/*
+ * 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*/
@@ -12189,8 +12405,10 @@
(uintptr_t)sec->dofs_offset + offs);
kind = (dtrace_actkind_t)desc->dofa_kind;
- if (DTRACEACT_ISPRINTFLIKE(kind) &&
+ if ((DTRACEACT_ISPRINTFLIKE(kind) &&
(kind != DTRACEACT_PRINTA ||
+ desc->dofa_strtab != DOF_SECIDX_NONE)) ||
+ (kind == DTRACEACT_DIFEXPR &&
desc->dofa_strtab != DOF_SECIDX_NONE)) {
dof_sec_t *strtab;
char *str, *fmt;
@@ -12197,7 +12415,10 @@
uint64_t i;
/*
- * printf()-like actions must have a format string.
+ * The argument to these actions is an index into the
+ * DOF string table. For printf()-like actions, this
+ * is the format string. For print(), this is the
+ * CTF type of the expression result.
*/
if ((strtab = dtrace_dof_sect(dof,
DOF_SECT_STRTAB, desc->dofa_strtab)) == NULL)
@@ -15443,6 +15664,10 @@
#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);
@@ -15527,6 +15752,11 @@
(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: trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
===================================================================
--- trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c 2016-10-14 02:04:39 UTC (rev 9155)
+++ trunk/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c 2016-10-14 02:04:51 UTC (rev 9156)
@@ -20,7 +20,7 @@
*
* Portions Copyright 2010 The FreeBSD Foundation
*
- * $MidnightBSD$
+ * $FreeBSD: release/9.2.0/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c 253394 2013-07-16 15:51:32Z avg $
*/
/*
@@ -175,6 +175,9 @@
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_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 @@
* 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 @@
* 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
@@ -2273,13 +2283,6 @@
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 = &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);
@@ -2356,6 +2359,13 @@
}
#endif
+ /*
+ * Install our hooks into fork(2), exec(2), and exit(2).
+ */
+ dtrace_fasttrap_fork = &fasttrap_fork;
+ dtrace_fasttrap_exit = &fasttrap_exec_exit;
+ dtrace_fasttrap_exec = &fasttrap_exec_exit;
+
(void) dtrace_meta_register("fasttrap", &fasttrap_mops, NULL,
&fasttrap_meta_id);
More information about the Midnightbsd-cvs
mailing list