summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkj <markj@FreeBSD.org>2014-02-22 05:18:55 +0000
committermarkj <markj@FreeBSD.org>2014-02-22 05:18:55 +0000
commit428d834b5b357ba3730526cfdafbfad8a5b62485 (patch)
treea083fe7c60a608a89014f48e30f6e24765bbaa44
parent95ac3c80e1d67d3c0fcf4e2d6b54d534042422b2 (diff)
downloadFreeBSD-src-428d834b5b357ba3730526cfdafbfad8a5b62485.zip
FreeBSD-src-428d834b5b357ba3730526cfdafbfad8a5b62485.tar.gz
1452 DTrace buffer autoscaling should be less violent
illumos/illumos-gate@6fb4854bed54ce82bd8610896b64ddebcd4af706 This fixes the tst.resize1.d and tst.resize2.d DTrace tests, which have been failing since r261122 since they were causing dtrace(1) to attempt to allocate and use large amounts of memory, and get killed by the OOM killer as a result. MFC after: 1 month
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d8
-rw-r--r--cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d8
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c27
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c48
4 files changed, 33 insertions, 58 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d
index 396a808..ca8ad44 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize1.d
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* ASSERTION:
* Checks that setting "bufresize" to "auto" will cause buffer
@@ -34,14 +32,8 @@
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
* Options and Tunables/bufsize;
* Options and Tunables/bufresize
- *
- * NOTES:
- * We use the undocumented "preallocate" option to make sure dtrace(1M)
- * has enough space in its heap to allocate a buffer as large as the
- * kernel's trace buffer.
*/
-#pragma D option preallocate=100t
#pragma D option bufresize=auto
#pragma D option bufsize=100t
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d
index 50b814b..ddb97c8 100644
--- a/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d
+++ b/cddl/contrib/opensolaris/cmd/dtrace/test/tst/common/buffering/tst.resize2.d
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* ASSERTION:
* Checks that setting "bufresize" to "auto" will cause buffer
@@ -34,14 +32,8 @@
* SECTION: Buffers and Buffering/Buffer Resizing Policy;
* Options and Tunables/aggsize;
* Options and Tunables/bufresize
- *
- * NOTES:
- * We use the undocumented "preallocate" option to make sure dtrace(1M)
- * has enough space in its heap to allocate a buffer as large as the
- * kernel's trace buffer.
*/
-#pragma D option preallocate=100t
#pragma D option bufresize=auto
#pragma D option aggsize=100t
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
index 020df2f..c20d250 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_options.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
@@ -906,30 +904,6 @@ dt_options_load(dtrace_hdl_t *dtp)
return (0);
}
-/*ARGSUSED*/
-static int
-dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
-{
- dtrace_optval_t size;
- void *p;
-
- if (arg == NULL || dt_optval_parse(arg, &size) != 0)
- return (dt_set_errno(dtp, EDT_BADOPTVAL));
-
- if (size > SIZE_MAX)
- size = SIZE_MAX;
-
- if ((p = dt_zalloc(dtp, size)) == NULL) {
- do {
- size /= 2;
- } while ((p = dt_zalloc(dtp, size)) == NULL);
- }
-
- dt_free(dtp, p);
-
- return (0);
-}
-
typedef struct dt_option {
const char *o_name;
int (*o_func)(dtrace_hdl_t *, const char *, uintptr_t);
@@ -968,7 +942,6 @@ static const dt_option_t _dtrace_ctoptions[] = {
{ "linktype", dt_opt_linktype },
{ "nolibs", dt_opt_cflags, DTRACE_C_NOLIBS },
{ "pgmax", dt_opt_pgmax },
- { "preallocate", dt_opt_preallocate },
{ "pspec", dt_opt_cflags, DTRACE_C_PSPEC },
{ "setenv", dt_opt_setenv, 1 },
{ "stdc", dt_opt_stdc },
diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index f35cf73..e85edd1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -10853,17 +10853,20 @@ dtrace_buffer_activate(dtrace_state_t *state)
static int
dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags,
- processorid_t cpu)
+ processorid_t cpu, int *factor)
{
#if defined(sun)
cpu_t *cp;
#endif
dtrace_buffer_t *buf;
+ int allocated = 0, desired = 0;
#if defined(sun)
ASSERT(MUTEX_HELD(&cpu_lock));
ASSERT(MUTEX_HELD(&dtrace_lock));
+ *factor = 1;
+
if (size > dtrace_nonroot_maxsize &&
!PRIV_POLICY_CHOICE(CRED(), PRIV_ALL, B_FALSE))
return (EFBIG);
@@ -10887,7 +10890,8 @@ dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags,
ASSERT(buf->dtb_xamot == NULL);
- if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+ if ((buf->dtb_tomax = kmem_zalloc(size,
+ KM_NOSLEEP | KM_NORMALPRI)) == NULL)
goto err;
buf->dtb_size = size;
@@ -10898,7 +10902,8 @@ dtrace_buffer_alloc(dtrace_buffer_t *bufs, size_t size, int flags,
if (flags & DTRACEBUF_NOSWITCH)
continue;
- if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+ if ((buf->dtb_xamot = kmem_zalloc(size,
+ KM_NOSLEEP | KM_NORMALPRI)) == NULL)
goto err;
} while ((cp = cp->cpu_next) != cpu_list);
@@ -10912,27 +10917,29 @@ err:
continue;
buf = &bufs[cp->cpu_id];
+ desired += 2;
if (buf->dtb_xamot != NULL) {
ASSERT(buf->dtb_tomax != NULL);
ASSERT(buf->dtb_size == size);
kmem_free(buf->dtb_xamot, size);
+ allocated++;
}
if (buf->dtb_tomax != NULL) {
ASSERT(buf->dtb_size == size);
kmem_free(buf->dtb_tomax, size);
+ allocated++;
}
buf->dtb_tomax = NULL;
buf->dtb_xamot = NULL;
buf->dtb_size = 0;
} while ((cp = cp->cpu_next) != cpu_list);
-
- return (ENOMEM);
#else
int i;
+ *factor = 1;
#if defined(__amd64__) || defined(__mips__) || defined(__powerpc__)
/*
* FreeBSD isn't good at limiting the amount of memory we
@@ -10940,7 +10947,7 @@ err:
* to do something that might well end in tears at bedtime.
*/
if (size > physmem * PAGE_SIZE / (128 * (mp_maxid + 1)))
- return(ENOMEM);
+ return (ENOMEM);
#endif
ASSERT(MUTEX_HELD(&dtrace_lock));
@@ -10962,7 +10969,8 @@ err:
ASSERT(buf->dtb_xamot == NULL);
- if ((buf->dtb_tomax = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+ if ((buf->dtb_tomax = kmem_zalloc(size,
+ KM_NOSLEEP | KM_NORMALPRI)) == NULL)
goto err;
buf->dtb_size = size;
@@ -10973,7 +10981,8 @@ err:
if (flags & DTRACEBUF_NOSWITCH)
continue;
- if ((buf->dtb_xamot = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+ if ((buf->dtb_xamot = kmem_zalloc(size,
+ KM_NOSLEEP | KM_NORMALPRI)) == NULL)
goto err;
}
@@ -10989,16 +10998,19 @@ err:
continue;
buf = &bufs[i];
+ desired += 2;
if (buf->dtb_xamot != NULL) {
ASSERT(buf->dtb_tomax != NULL);
ASSERT(buf->dtb_size == size);
kmem_free(buf->dtb_xamot, size);
+ allocated++;
}
if (buf->dtb_tomax != NULL) {
ASSERT(buf->dtb_size == size);
kmem_free(buf->dtb_tomax, size);
+ allocated++;
}
buf->dtb_tomax = NULL;
@@ -11006,9 +11018,10 @@ err:
buf->dtb_size = 0;
}
+#endif
+ *factor = desired / (allocated > 0 ? allocated : 1);
return (ENOMEM);
-#endif
}
/*
@@ -12961,7 +12974,7 @@ dtrace_dstate_init(dtrace_dstate_t *dstate, size_t size)
if (size < (min = dstate->dtds_chunksize + sizeof (dtrace_dynhash_t)))
size = min;
- if ((base = kmem_zalloc(size, KM_NOSLEEP)) == NULL)
+ if ((base = kmem_zalloc(size, KM_NOSLEEP | KM_NORMALPRI)) == NULL)
return (ENOMEM);
dstate->dtds_size = size;
@@ -13413,7 +13426,7 @@ dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
{
dtrace_optval_t *opt = state->dts_options, size;
processorid_t cpu = 0;;
- int flags = 0, rval;
+ int flags = 0, rval, factor, divisor = 1;
ASSERT(MUTEX_HELD(&dtrace_lock));
ASSERT(MUTEX_HELD(&cpu_lock));
@@ -13443,7 +13456,7 @@ dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
flags |= DTRACEBUF_INACTIVE;
}
- for (size = opt[which]; size >= sizeof (uint64_t); size >>= 1) {
+ for (size = opt[which]; size >= sizeof (uint64_t); size /= divisor) {
/*
* The size must be 8-byte aligned. If the size is not 8-byte
* aligned, drop it down by the difference.
@@ -13461,7 +13474,7 @@ dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
return (E2BIG);
}
- rval = dtrace_buffer_alloc(buf, size, flags, cpu);
+ rval = dtrace_buffer_alloc(buf, size, flags, cpu, &factor);
if (rval != ENOMEM) {
opt[which] = size;
@@ -13470,6 +13483,9 @@ dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf, int which)
if (opt[DTRACEOPT_BUFRESIZE] == DTRACEOPT_BUFRESIZE_MANUAL)
return (rval);
+
+ for (divisor = 2; divisor < factor; divisor <<= 1)
+ continue;
}
return (ENOMEM);
@@ -13571,7 +13587,8 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
goto out;
}
- spec = kmem_zalloc(nspec * sizeof (dtrace_speculation_t), KM_NOSLEEP);
+ spec = kmem_zalloc(nspec * sizeof (dtrace_speculation_t),
+ KM_NOSLEEP | KM_NORMALPRI);
if (spec == NULL) {
rval = ENOMEM;
@@ -13582,7 +13599,8 @@ dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
state->dts_nspeculations = (int)nspec;
for (i = 0; i < nspec; i++) {
- if ((buf = kmem_zalloc(bufsize, KM_NOSLEEP)) == NULL) {
+ if ((buf = kmem_zalloc(bufsize,
+ KM_NOSLEEP | KM_NORMALPRI)) == NULL) {
rval = ENOMEM;
goto err;
}
OpenPOWER on IntegriCloud