summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authorpfg <pfg@FreeBSD.org>2013-04-17 02:20:17 +0000
committerpfg <pfg@FreeBSD.org>2013-04-17 02:20:17 +0000
commitf9796e10e2b7bb43bf358c337b15bb183a6b1aaf (patch)
treedaa5db7d59bdba8c6f4ebf57f4923612b4fd09b6 /sys/cddl
parent3ab51705b73c481b6bc76e733f494db7fa6f31fd (diff)
downloadFreeBSD-src-f9796e10e2b7bb43bf358c337b15bb183a6b1aaf.zip
FreeBSD-src-f9796e10e2b7bb43bf358c337b15bb183a6b1aaf.tar.gz
DTrace: Revert r249367
The following change from illumos brought caused DTrace to pause in an interactive environment: 3026 libdtrace should set LD_NOLAZYLOAD=1 to help the pid provider This was not detected during testing because it doesn't affect scripts. We shouldn't be changing the environment, especially since the LD_NOLAZYLOAD option doesn't apply to our (GNU) ld. Unfortunately the change from upstream was made in such a way that it is very difficult to separate this change from the others so, at least for now, it's better to just revert everything. Reference: https://www.illumos.org/issues/3026 Reported by: Navdeep Parhar and Mark Johnston
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c224
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h37
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h59
3 files changed, 131 insertions, 189 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 89787e4..c8bb4de 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -23,7 +23,6 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved
* Use is subject to license terms.
*/
@@ -2346,10 +2345,9 @@ dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu,
{
dtrace_speculation_t *spec;
dtrace_buffer_t *src, *dest;
- uintptr_t daddr, saddr, dlimit, slimit;
+ uintptr_t daddr, saddr, dlimit;
dtrace_speculation_state_t current, new = 0;
intptr_t offs;
- uint64_t timestamp;
if (which == 0)
return;
@@ -2425,37 +2423,7 @@ dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu,
}
/*
- * We have sufficient space to copy the speculative buffer into the
- * primary buffer. First, modify the speculative buffer, filling
- * in the timestamp of all entries with the current time. The data
- * must have the commit() time rather than the time it was traced,
- * so that all entries in the primary buffer are in timestamp order.
- */
- timestamp = dtrace_gethrtime();
- saddr = (uintptr_t)src->dtb_tomax;
- slimit = saddr + src->dtb_offset;
- while (saddr < slimit) {
- size_t size;
- dtrace_rechdr_t *dtrh = (dtrace_rechdr_t *)saddr;
-
- if (dtrh->dtrh_epid == DTRACE_EPIDNONE) {
- saddr += sizeof (dtrace_epid_t);
- continue;
- }
- ASSERT3U(dtrh->dtrh_epid, <=, state->dts_necbs);
- size = state->dts_ecbs[dtrh->dtrh_epid - 1]->dte_size;
-
- ASSERT3U(saddr + size, <=, slimit);
- ASSERT3U(size, >=, sizeof (dtrace_rechdr_t));
- ASSERT3U(DTRACE_RECORD_LOAD_TIMESTAMP(dtrh), ==, UINT64_MAX);
-
- DTRACE_RECORD_STORE_TIMESTAMP(dtrh, timestamp);
-
- saddr += size;
- }
-
- /*
- * Copy the buffer across. (Note that this is a
+ * We have the space; copy the buffer across. (Note that this is a
* highly subobtimal bcopy(); in the unlikely event that this becomes
* a serious performance issue, a high-performance DTrace-specific
* bcopy() should obviously be invented.)
@@ -6238,7 +6206,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
if (now - state->dts_alive > dtrace_deadman_timeout) {
/*
* We seem to be dead. Unless we (a) have kernel
- * destructive permissions (b) have explicitly enabled
+ * destructive permissions (b) have expicitly enabled
* destructive actions and (c) destructive actions have
* not been disabled, we're going to transition into
* the KILLED state, from which no further processing
@@ -6266,18 +6234,8 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
tomax = buf->dtb_tomax;
ASSERT(tomax != NULL);
- if (ecb->dte_size != 0) {
- dtrace_rechdr_t dtrh;
- if (!(mstate.dtms_present & DTRACE_MSTATE_TIMESTAMP)) {
- mstate.dtms_timestamp = dtrace_gethrtime();
- mstate.dtms_present |= DTRACE_MSTATE_TIMESTAMP;
- }
- ASSERT3U(ecb->dte_size, >=, sizeof (dtrace_rechdr_t));
- dtrh.dtrh_epid = ecb->dte_epid;
- DTRACE_RECORD_STORE_TIMESTAMP(&dtrh,
- mstate.dtms_timestamp);
- *((dtrace_rechdr_t *)(tomax + offs)) = dtrh;
- }
+ if (ecb->dte_size != 0)
+ DTRACE_STORE(uint32_t, tomax, offs, ecb->dte_epid);
mstate.dtms_epid = ecb->dte_epid;
mstate.dtms_present |= DTRACE_MSTATE_EPID;
@@ -6424,9 +6382,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
continue;
switch (act->dta_kind) {
- case DTRACEACT_SPECULATE: {
- dtrace_rechdr_t *dtrh;
-
+ case DTRACEACT_SPECULATE:
ASSERT(buf == &state->dts_buffer[cpuid]);
buf = dtrace_speculation_buffer(state,
cpuid, val);
@@ -6448,23 +6404,10 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
tomax = buf->dtb_tomax;
ASSERT(tomax != NULL);
- if (ecb->dte_size == 0)
- continue;
-
- ASSERT3U(ecb->dte_size, >=,
- sizeof (dtrace_rechdr_t));
- dtrh = ((void *)(tomax + offs));
- dtrh->dtrh_epid = ecb->dte_epid;
- /*
- * When the speculation is committed, all of
- * the records in the speculative buffer will
- * have their timestamps set to the commit
- * time. Until then, it is set to a sentinel
- * value, for debugability.
- */
- DTRACE_RECORD_STORE_TIMESTAMP(dtrh, UINT64_MAX);
+ if (ecb->dte_size != 0)
+ DTRACE_STORE(uint32_t, tomax, offs,
+ ecb->dte_epid);
continue;
- }
case DTRACEACT_PRINTM: {
/* The DIF returns a 'memref'. */
@@ -9811,9 +9754,9 @@ dtrace_ecb_add(dtrace_state_t *state, dtrace_probe_t *probe)
/*
* The default size is the size of the default action: recording
- * the header.
+ * the epid.
*/
- ecb->dte_size = ecb->dte_needed = sizeof (dtrace_rechdr_t);
+ ecb->dte_size = ecb->dte_needed = sizeof (dtrace_epid_t);
ecb->dte_alignment = sizeof (dtrace_epid_t);
epid = state->dts_epid++;
@@ -9911,89 +9854,122 @@ dtrace_ecb_enable(dtrace_ecb_t *ecb)
static void
dtrace_ecb_resize(dtrace_ecb_t *ecb)
{
+ uint32_t maxalign = sizeof (dtrace_epid_t);
+ uint32_t align = sizeof (uint8_t), offs, diff;
dtrace_action_t *act;
- uint32_t curneeded = UINT32_MAX;
+ int wastuple = 0;
uint32_t aggbase = UINT32_MAX;
+ dtrace_state_t *state = ecb->dte_state;
/*
- * If we record anything, we always record the dtrace_rechdr_t. (And
- * we always record it first.)
+ * If we record anything, we always record the epid. (And we always
+ * record it first.)
*/
- ecb->dte_size = sizeof (dtrace_rechdr_t);
- ecb->dte_alignment = sizeof (dtrace_epid_t);
+ offs = sizeof (dtrace_epid_t);
+ ecb->dte_size = ecb->dte_needed = sizeof (dtrace_epid_t);
for (act = ecb->dte_action; act != NULL; act = act->dta_next) {
dtrace_recdesc_t *rec = &act->dta_rec;
- ASSERT(rec->dtrd_size > 0 || rec->dtrd_alignment == 1);
- ecb->dte_alignment = MAX(ecb->dte_alignment,
- rec->dtrd_alignment);
+ if ((align = rec->dtrd_alignment) > maxalign)
+ maxalign = align;
+
+ if (!wastuple && act->dta_intuple) {
+ /*
+ * This is the first record in a tuple. Align the
+ * offset to be at offset 4 in an 8-byte aligned
+ * block.
+ */
+ diff = offs + sizeof (dtrace_aggid_t);
+
+ if ((diff = (diff & (sizeof (uint64_t) - 1))))
+ offs += sizeof (uint64_t) - diff;
+
+ aggbase = offs - sizeof (dtrace_aggid_t);
+ ASSERT(!(aggbase & (sizeof (uint64_t) - 1)));
+ }
+
+ /*LINTED*/
+ if (rec->dtrd_size != 0 && (diff = (offs & (align - 1)))) {
+ /*
+ * The current offset is not properly aligned; align it.
+ */
+ offs += align - diff;
+ }
+
+ rec->dtrd_offset = offs;
+
+ if (offs + rec->dtrd_size > ecb->dte_needed) {
+ ecb->dte_needed = offs + rec->dtrd_size;
+
+ if (ecb->dte_needed > state->dts_needed)
+ state->dts_needed = ecb->dte_needed;
+ }
if (DTRACEACT_ISAGG(act->dta_kind)) {
dtrace_aggregation_t *agg = (dtrace_aggregation_t *)act;
+ dtrace_action_t *first = agg->dtag_first, *prev;
- ASSERT(rec->dtrd_size != 0);
- ASSERT(agg->dtag_first != NULL);
- ASSERT(act->dta_prev->dta_intuple);
+ ASSERT(rec->dtrd_size != 0 && first != NULL);
+ ASSERT(wastuple);
ASSERT(aggbase != UINT32_MAX);
- ASSERT(curneeded != UINT32_MAX);
agg->dtag_base = aggbase;
- curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
- rec->dtrd_offset = curneeded;
- curneeded += rec->dtrd_size;
- ecb->dte_needed = MAX(ecb->dte_needed, curneeded);
+ while ((prev = first->dta_prev) != NULL &&
+ DTRACEACT_ISAGG(prev->dta_kind)) {
+ agg = (dtrace_aggregation_t *)prev;
+ first = agg->dtag_first;
+ }
- aggbase = UINT32_MAX;
- curneeded = UINT32_MAX;
- } else if (act->dta_intuple) {
- if (curneeded == UINT32_MAX) {
- /*
- * This is the first record in a tuple. Align
- * curneeded to be at offset 4 in an 8-byte
- * aligned block.
- */
- ASSERT(act->dta_prev == NULL ||
- !act->dta_prev->dta_intuple);
- ASSERT3U(aggbase, ==, UINT32_MAX);
- curneeded = P2PHASEUP(ecb->dte_size,
- sizeof (uint64_t), sizeof (dtrace_aggid_t));
-
- aggbase = curneeded - sizeof (dtrace_aggid_t);
- ASSERT(IS_P2ALIGNED(aggbase,
- sizeof (uint64_t)));
+ if (prev != NULL) {
+ offs = prev->dta_rec.dtrd_offset +
+ prev->dta_rec.dtrd_size;
+ } else {
+ offs = sizeof (dtrace_epid_t);
}
- curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
- rec->dtrd_offset = curneeded;
- curneeded += rec->dtrd_size;
+ wastuple = 0;
} else {
- /* tuples must be followed by an aggregation */
- ASSERT(act->dta_prev == NULL ||
- !act->dta_prev->dta_intuple);
+ if (!act->dta_intuple)
+ ecb->dte_size = offs + rec->dtrd_size;
- ecb->dte_size = P2ROUNDUP(ecb->dte_size,
- rec->dtrd_alignment);
- rec->dtrd_offset = ecb->dte_size;
- ecb->dte_size += rec->dtrd_size;
- ecb->dte_needed = MAX(ecb->dte_needed, ecb->dte_size);
+ offs += rec->dtrd_size;
}
+
+ wastuple = act->dta_intuple;
}
if ((act = ecb->dte_action) != NULL &&
!(act->dta_kind == DTRACEACT_SPECULATE && act->dta_next == NULL) &&
- ecb->dte_size == sizeof (dtrace_rechdr_t)) {
+ ecb->dte_size == sizeof (dtrace_epid_t)) {
/*
- * If the size is still sizeof (dtrace_rechdr_t), then all
+ * If the size is still sizeof (dtrace_epid_t), then all
* actions store no data; set the size to 0.
*/
+ ecb->dte_alignment = maxalign;
ecb->dte_size = 0;
+
+ /*
+ * If the needed space is still sizeof (dtrace_epid_t), then
+ * all actions need no additional space; set the needed
+ * size to 0.
+ */
+ if (ecb->dte_needed == sizeof (dtrace_epid_t))
+ ecb->dte_needed = 0;
+
+ return;
}
- ecb->dte_size = P2ROUNDUP(ecb->dte_size, sizeof (dtrace_epid_t));
- ecb->dte_needed = P2ROUNDUP(ecb->dte_needed, (sizeof (dtrace_epid_t)));
- ecb->dte_state->dts_needed = MAX(ecb->dte_state->dts_needed,
- ecb->dte_needed);
+ /*
+ * Set our alignment, and make sure that the dte_size and dte_needed
+ * are aligned to the size of an EPID.
+ */
+ ecb->dte_alignment = maxalign;
+ ecb->dte_size = (ecb->dte_size + (sizeof (dtrace_epid_t) - 1)) &
+ ~(sizeof (dtrace_epid_t) - 1);
+ ecb->dte_needed = (ecb->dte_needed + (sizeof (dtrace_epid_t) - 1)) &
+ ~(sizeof (dtrace_epid_t) - 1);
+ ASSERT(ecb->dte_size <= ecb->dte_needed);
}
static dtrace_action_t *
@@ -10373,7 +10349,7 @@ dtrace_ecb_action_add(dtrace_ecb_t *ecb, dtrace_actdesc_t *desc)
break;
case DTRACEACT_SPECULATE:
- if (ecb->dte_size > sizeof (dtrace_rechdr_t))
+ if (ecb->dte_size > sizeof (dtrace_epid_t))
return (EINVAL);
if (dp == NULL)
@@ -10494,7 +10470,7 @@ dtrace_ecb_action_remove(dtrace_ecb_t *ecb)
ecb->dte_action = NULL;
ecb->dte_action_last = NULL;
- ecb->dte_size = 0;
+ ecb->dte_size = sizeof (dtrace_epid_t);
}
static void
@@ -10763,13 +10739,12 @@ dtrace_buffer_switch(dtrace_buffer_t *buf)
caddr_t tomax = buf->dtb_tomax;
caddr_t xamot = buf->dtb_xamot;
dtrace_icookie_t cookie;
- hrtime_t now;
+ hrtime_t now = dtrace_gethrtime();
ASSERT(!(buf->dtb_flags & DTRACEBUF_NOSWITCH));
ASSERT(!(buf->dtb_flags & DTRACEBUF_RING));
cookie = dtrace_interrupt_disable();
- now = dtrace_gethrtime();
buf->dtb_tomax = xamot;
buf->dtb_xamot = tomax;
buf->dtb_xamot_drops = buf->dtb_drops;
@@ -11135,7 +11110,7 @@ dtrace_buffer_reserve(dtrace_buffer_t *buf, size_t needed, size_t align,
if (epid == DTRACE_EPIDNONE) {
size = sizeof (uint32_t);
} else {
- ASSERT3U(epid, <=, state->dts_necbs);
+ ASSERT(epid <= state->dts_necbs);
ASSERT(state->dts_ecbs[epid - 1] != NULL);
size = state->dts_ecbs[epid - 1]->dte_size;
@@ -16412,7 +16387,6 @@ dtrace_ioctl(dev_t dev, int cmd, intptr_t arg, int md, cred_t *cr, int *rv)
desc.dtbd_drops = buf->dtb_drops;
desc.dtbd_errors = buf->dtb_errors;
desc.dtbd_oldest = buf->dtb_xamot_offset;
- desc.dtbd_timestamp = dtrace_gethrtime();
mutex_exit(&dtrace_lock);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
index 4595c2e..4968352 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h
@@ -26,7 +26,6 @@
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_DTRACE_H
@@ -931,10 +930,10 @@ typedef struct dtrace_ecbdesc {
* DTrace Metadata Description Structures
*
* DTrace separates the trace data stream from the metadata stream. The only
- * metadata tokens placed in the data stream are the dtrace_rechdr_t (EPID +
- * timestamp) or (in the case of aggregations) aggregation identifiers. To
- * determine the structure of the data, DTrace consumers pass the token to the
- * kernel, and receive in return a corresponding description of the enabled
+ * metadata tokens placed in the data stream are enabled probe identifiers
+ * (EPIDs) or (in the case of aggregations) aggregation identifiers. In order
+ * to determine the structure of the data, DTrace consumers pass the token to
+ * the kernel, and receive in return a corresponding description of the enabled
* probe (via the dtrace_eprobedesc structure) or the aggregation (via the
* dtrace_aggdesc structure). Both of these structures are expressed in terms
* of record descriptions (via the dtrace_recdesc structure) that describe the
@@ -1029,8 +1028,7 @@ typedef struct dtrace_fmtdesc {
#define DTRACEOPT_AGGSORTREV 24 /* reverse-sort aggregations */
#define DTRACEOPT_AGGSORTPOS 25 /* agg. position to sort on */
#define DTRACEOPT_AGGSORTKEYPOS 26 /* agg. key position to sort on */
-#define DTRACEOPT_TEMPORAL 27 /* temporally ordered output */
-#define DTRACEOPT_MAX 28 /* number of options */
+#define DTRACEOPT_MAX 27 /* number of options */
#define DTRACEOPT_UNSET (dtrace_optval_t)-2 /* unset option */
@@ -1050,9 +1048,7 @@ typedef struct dtrace_fmtdesc {
* where user-level wishes the kernel to snapshot the buffer to (the
* dtbd_data field). The kernel uses the same structure to pass back some
* information regarding the buffer: the size of data actually copied out, the
- * number of drops, the number of errors, the offset of the oldest record,
- * and the time of the snapshot.
- *
+ * number of drops, the number of errors, and the offset of the oldest record.
* If the buffer policy is a "switch" policy, taking a snapshot of the
* principal buffer has the additional effect of switching the active and
* inactive buffers. Taking a snapshot of the aggregation buffer _always_ has
@@ -1065,30 +1061,9 @@ typedef struct dtrace_bufdesc {
uint64_t dtbd_drops; /* number of drops */
DTRACE_PTR(char, dtbd_data); /* data */
uint64_t dtbd_oldest; /* offset of oldest record */
- uint64_t dtbd_timestamp; /* hrtime of snapshot */
} dtrace_bufdesc_t;
/*
- * Each record in the buffer (dtbd_data) begins with a header that includes
- * the epid and a timestamp. The timestamp is split into two 4-byte parts
- * so that we do not require 8-byte alignment.
- */
-typedef struct dtrace_rechdr {
- dtrace_epid_t dtrh_epid; /* enabled probe id */
- uint32_t dtrh_timestamp_hi; /* high bits of hrtime_t */
- uint32_t dtrh_timestamp_lo; /* low bits of hrtime_t */
-} dtrace_rechdr_t;
-
-#define DTRACE_RECORD_LOAD_TIMESTAMP(dtrh) \
- ((dtrh)->dtrh_timestamp_lo + \
- ((uint64_t)(dtrh)->dtrh_timestamp_hi << 32))
-
-#define DTRACE_RECORD_STORE_TIMESTAMP(dtrh, hrtime) { \
- (dtrh)->dtrh_timestamp_lo = (uint32_t)hrtime; \
- (dtrh)->dtrh_timestamp_hi = hrtime >> 32; \
-}
-
-/*
* DTrace Status
*
* The status of DTrace is relayed via the dtrace_status structure. This
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
index 7355aa8..4d9a4f8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace_impl.h
@@ -23,7 +23,6 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
* Use is subject to license terms.
*/
@@ -210,18 +209,15 @@ typedef struct dtrace_hash {
* predicate is non-NULL, the DIF object is executed. If the result is
* non-zero, the action list is processed, with each action being executed
* accordingly. When the action list has been completely executed, processing
- * advances to the next ECB. The ECB abstraction allows disjoint consumers
- * to multiplex on single probes.
- *
- * Execution of the ECB results in consuming dte_size bytes in the buffer
- * to record data. During execution, dte_needed bytes must be available in
- * the buffer. This space is used for both recorded data and tuple data.
+ * advances to the next ECB. processing advances to the next ECB. If the
+ * result is non-zero; For each ECB, it first determines the The ECB
+ * abstraction allows disjoint consumers to multiplex on single probes.
*/
struct dtrace_ecb {
dtrace_epid_t dte_epid; /* enabled probe ID */
uint32_t dte_alignment; /* required alignment */
- size_t dte_needed; /* space needed for execution */
- size_t dte_size; /* size of recorded payload */
+ size_t dte_needed; /* bytes needed */
+ size_t dte_size; /* total size of payload */
dtrace_predicate_t *dte_predicate; /* predicate, if any */
dtrace_action_t *dte_action; /* actions, if any */
dtrace_ecb_t *dte_next; /* next ECB on probe */
@@ -279,30 +275,27 @@ typedef struct dtrace_aggregation {
* the EPID, the consumer can determine the data layout. (The data buffer
* layout is shown schematically below.) By assuring that one can determine
* data layout from the EPID, the metadata stream can be separated from the
- * data stream -- simplifying the data stream enormously. The ECB always
- * proceeds the recorded data as part of the dtrace_rechdr_t structure that
- * includes the EPID and a high-resolution timestamp used for output ordering
- * consistency.
- *
- * base of data buffer ---> +--------+--------------------+--------+
- * | rechdr | data | rechdr |
- * +--------+------+--------+----+--------+
- * | data | rechdr | data |
- * +---------------+--------+-------------+
- * | data, cont. |
- * +--------+--------------------+--------+
- * | rechdr | data | |
- * +--------+--------------------+ |
- * | || |
- * | || |
- * | \/ |
- * : :
- * . .
- * . .
- * . .
- * : :
- * | |
- * limit of data buffer ---> +--------------------------------------+
+ * data stream -- simplifying the data stream enormously.
+ *
+ * base of data buffer ---> +------+--------------------+------+
+ * | EPID | data | EPID |
+ * +------+--------+------+----+------+
+ * | data | EPID | data |
+ * +---------------+------+-----------+
+ * | data, cont. |
+ * +------+--------------------+------+
+ * | EPID | data | |
+ * +------+--------------------+ |
+ * | || |
+ * | || |
+ * | \/ |
+ * : :
+ * . .
+ * . .
+ * . .
+ * : :
+ * | |
+ * limit of data buffer ---> +----------------------------------+
*
* When evaluating an ECB, dtrace_probe() determines if the ECB's needs of the
* principal buffer (both scratch and payload) exceed the available space. If
OpenPOWER on IntegriCloud