Print this page
9525 kmem_dump_size is a corrupting influence
@@ -2209,37 +2209,10 @@
#define KMEM_DUMPCTL(cp, buf) \
((kmem_dumpctl_t *)P2ROUNDUP((uintptr_t)(buf) + (cp)->cache_bufsize, \
sizeof (void *)))
-/* Keep some simple stats. */
-#define KMEM_DUMP_LOGS (100)
-
-typedef struct kmem_dump_log {
- kmem_cache_t *kdl_cache;
- uint_t kdl_allocs; /* # of dump allocations */
- uint_t kdl_frees; /* # of dump frees */
- uint_t kdl_alloc_fails; /* # of allocation failures */
- uint_t kdl_free_nondump; /* # of non-dump frees */
- uint_t kdl_unsafe; /* cache was used, but unsafe */
-} kmem_dump_log_t;
-
-static kmem_dump_log_t *kmem_dump_log;
-static int kmem_dump_log_idx;
-
-#define KDI_LOG(cp, stat) { \
- kmem_dump_log_t *kdl; \
- if ((kdl = (kmem_dump_log_t *)((cp)->cache_dumplog)) != NULL) { \
- kdl->stat++; \
- } else if (kmem_dump_log_idx < KMEM_DUMP_LOGS) { \
- kdl = &kmem_dump_log[kmem_dump_log_idx++]; \
- kdl->stat++; \
- kdl->kdl_cache = (cp); \
- (cp)->cache_dumplog = kdl; \
- } \
-}
-
/* set non zero for full report */
uint_t kmem_dump_verbose = 0;
/* stats for overize heap */
uint_t kmem_dump_oversize_allocs = 0;
@@ -2265,29 +2238,21 @@
* Called when dumpadm(1M) configures dump parameters.
*/
void
kmem_dump_init(size_t size)
{
+ /* Our caller ensures size is always set. */
+ ASSERT3U(size, >, 0);
+
if (kmem_dump_start != NULL)
kmem_free(kmem_dump_start, kmem_dump_size);
- if (kmem_dump_log == NULL)
- kmem_dump_log = (kmem_dump_log_t *)kmem_zalloc(KMEM_DUMP_LOGS *
- sizeof (kmem_dump_log_t), KM_SLEEP);
-
kmem_dump_start = kmem_alloc(size, KM_SLEEP);
-
- if (kmem_dump_start != NULL) {
kmem_dump_size = size;
kmem_dump_curr = kmem_dump_start;
kmem_dump_end = (void *)((char *)kmem_dump_start + size);
copy_pattern(KMEM_UNINITIALIZED_PATTERN, kmem_dump_start, size);
- } else {
- kmem_dump_size = 0;
- kmem_dump_curr = NULL;
- kmem_dump_end = NULL;
- }
}
/*
* Set flag for each kmem_cache_t if is safe to use alternate dump
* memory. Called just before panic crash dump starts. Set the flag
@@ -2294,14 +2259,14 @@
* for the calling CPU.
*/
void
kmem_dump_begin(void)
{
- ASSERT(panicstr != NULL);
- if (kmem_dump_start != NULL) {
kmem_cache_t *cp;
+ ASSERT(panicstr != NULL);
+
for (cp = list_head(&kmem_caches); cp != NULL;
cp = list_next(&kmem_caches, cp)) {
kmem_cpu_cache_t *ccp = KMEM_CPU_CACHE(cp);
if (cp->cache_arena->vm_cflags & VMC_DUMPSAFE) {
@@ -2313,11 +2278,10 @@
} else {
cp->cache_flags |= KMF_DUMPUNSAFE;
ccp->cc_flags |= KMF_DUMPUNSAFE;
}
}
- }
}
/*
* finished dump intercept
* print any warnings on the console
@@ -2324,22 +2288,22 @@
* return verbose information to dumpsys() in the given buffer
*/
size_t
kmem_dump_finish(char *buf, size_t size)
{
- int kdi_idx;
- int kdi_end = kmem_dump_log_idx;
int percent = 0;
- int header = 0;
- int warn = 0;
size_t used;
- kmem_cache_t *cp;
- kmem_dump_log_t *kdl;
char *e = buf + size;
char *p = buf;
- if (kmem_dump_size == 0 || kmem_dump_verbose == 0)
+ if (kmem_dump_curr == kmem_dump_end) {
+ cmn_err(CE_WARN, "exceeded kmem_dump space of %lu "
+ "bytes: kmem state in dump may be inconsistent",
+ kmem_dump_size);
+ }
+
+ if (kmem_dump_verbose == 0)
return (0);
used = (char *)kmem_dump_curr - (char *)kmem_dump_start;
percent = (used * 100) / kmem_dump_size;
@@ -2349,29 +2313,10 @@
kmem_dumppr(&p, e, "Oversize allocs,%d\n",
kmem_dump_oversize_allocs);
kmem_dumppr(&p, e, "Oversize max size,%ld\n",
kmem_dump_oversize_max);
- for (kdi_idx = 0; kdi_idx < kdi_end; kdi_idx++) {
- kdl = &kmem_dump_log[kdi_idx];
- cp = kdl->kdl_cache;
- if (cp == NULL)
- break;
- if (kdl->kdl_alloc_fails)
- ++warn;
- if (header == 0) {
- kmem_dumppr(&p, e,
- "Cache Name,Allocs,Frees,Alloc Fails,"
- "Nondump Frees,Unsafe Allocs/Frees\n");
- header = 1;
- }
- kmem_dumppr(&p, e, "%s,%d,%d,%d,%d,%d\n",
- cp->cache_name, kdl->kdl_allocs, kdl->kdl_frees,
- kdl->kdl_alloc_fails, kdl->kdl_free_nondump,
- kdl->kdl_unsafe);
- }
-
/* return buffer size used */
if (p < e)
bzero(p, e - p);
return (p - buf);
}
@@ -2385,13 +2330,12 @@
void *buf;
void *curr;
char *bufend;
/* return a constructed object */
- if ((buf = cp->cache_dumpfreelist) != NULL) {
- cp->cache_dumpfreelist = KMEM_DUMPCTL(cp, buf)->kdc_next;
- KDI_LOG(cp, kdl_allocs);
+ if ((buf = cp->cache_dump.kd_freelist) != NULL) {
+ cp->cache_dump.kd_freelist = KMEM_DUMPCTL(cp, buf)->kdc_next;
return (buf);
}
/* create a new constructed object */
curr = kmem_dump_curr;
@@ -2408,11 +2352,11 @@
}
/* fall back to normal alloc if reserved area is used up */
if (bufend > (char *)kmem_dump_end) {
kmem_dump_curr = kmem_dump_end;
- KDI_LOG(cp, kdl_alloc_fails);
+ cp->cache_dump.kd_alloc_fails++;
return (NULL);
}
/*
* Must advance curr pointer before calling a constructor that
@@ -2430,16 +2374,15 @@
#endif
/* reset curr pointer iff no allocs were done */
if (kmem_dump_curr == bufend)
kmem_dump_curr = curr;
+ cp->cache_dump.kd_alloc_fails++;
/* fall back to normal alloc if the constructor fails */
- KDI_LOG(cp, kdl_alloc_fails);
return (NULL);
}
- KDI_LOG(cp, kdl_allocs);
return (buf);
}
/*
* Free a constructed object in alternate dump memory.
@@ -2448,19 +2391,15 @@
kmem_cache_free_dump(kmem_cache_t *cp, void *buf)
{
/* save constructed buffers for next time */
if ((char *)buf >= (char *)kmem_dump_start &&
(char *)buf < (char *)kmem_dump_end) {
- KMEM_DUMPCTL(cp, buf)->kdc_next = cp->cache_dumpfreelist;
- cp->cache_dumpfreelist = buf;
- KDI_LOG(cp, kdl_frees);
+ KMEM_DUMPCTL(cp, buf)->kdc_next = cp->cache_dump.kd_freelist;
+ cp->cache_dump.kd_freelist = buf;
return (0);
}
- /* count all non-dump buf frees */
- KDI_LOG(cp, kdl_free_nondump);
-
/* just drop buffers that were allocated before dump started */
if (kmem_dump_curr < kmem_dump_end)
return (0);
/* fall back to normal free if reserved area is used up */
@@ -2489,11 +2428,11 @@
mutex_exit(&ccp->cc_lock);
if (ccp->cc_flags & (KMF_BUFTAG | KMF_DUMPUNSAFE)) {
if (ccp->cc_flags & KMF_DUMPUNSAFE) {
ASSERT(!(ccp->cc_flags &
KMF_DUMPDIVERT));
- KDI_LOG(cp, kdl_unsafe);
+ cp->cache_dump.kd_unsafe++;
}
if ((ccp->cc_flags & KMF_BUFTAG) &&
kmem_cache_alloc_debug(cp, buf, kmflag, 0,
caller()) != 0) {
if (kmflag & KM_NOSLEEP)
@@ -2520,11 +2459,11 @@
*/
if (ccp->cc_flags & (KMF_DUMPDIVERT | KMF_DUMPUNSAFE)) {
if (ccp->cc_flags & KMF_DUMPUNSAFE) {
ASSERT(!(ccp->cc_flags & KMF_DUMPDIVERT));
/* log it so that we can warn about it */
- KDI_LOG(cp, kdl_unsafe);
+ cp->cache_dump.kd_unsafe++;
} else {
if ((buf = kmem_cache_alloc_dump(cp, kmflag)) !=
NULL) {
mutex_exit(&ccp->cc_lock);
return (buf);
@@ -2716,11 +2655,11 @@
if (ccp->cc_flags & (KMF_BUFTAG | KMF_DUMPDIVERT | KMF_DUMPUNSAFE)) {
if (ccp->cc_flags & KMF_DUMPUNSAFE) {
ASSERT(!(ccp->cc_flags & KMF_DUMPDIVERT));
/* log it so that we can warn about it */
- KDI_LOG(cp, kdl_unsafe);
+ cp->cache_dump.kd_unsafe++;
} else if (KMEM_DUMPCC(ccp) && !kmem_cache_free_dump(cp, buf)) {
return;
}
if (ccp->cc_flags & KMF_BUFTAG) {
if (kmem_cache_free_debug(cp, buf, caller()) == -1)