--- src/sys/kern/kern_malloc.c@@/main/56 2005-12-28 01:53:13.000000000 -0500 +++ src/sys/kern/kern_malloc.c@@/main/RELENG_6/svos_6_1/1 2010-07-27 19:22:35.000000000 -0400 @@ -65,6 +65,9 @@ __FBSDID("$FreeBSD$"); #ifdef DEBUG_MEMGUARD #include #endif +#ifdef DEBUG_REDZONE +#include +#endif #if defined(INVARIANTS) && defined(__i386__) #include @@ -142,12 +145,6 @@ struct { static uma_zone_t mt_zone; -#ifdef DEBUG_MEMGUARD -u_int vm_memguard_divisor; -SYSCTL_UINT(_vm, OID_AUTO, memguard_divisor, CTLFLAG_RD, &vm_memguard_divisor, - 0, "(kmem_size/memguard_divisor) == memguard submap size"); -#endif - u_int vm_kmem_size; SYSCTL_UINT(_vm, OID_AUTO, kmem_size, CTLFLAG_RD, &vm_kmem_size, 0, "Size of kernel memory"); @@ -265,7 +262,7 @@ malloc(unsigned long size, struct malloc caddr_t va; uma_zone_t zone; uma_keg_t keg; -#ifdef DIAGNOSTIC +#if defined(DIAGNOSTIC) || defined(DEBUG_REDZONE) unsigned long osize = size; #endif @@ -304,11 +301,14 @@ malloc(unsigned long size, struct malloc ("malloc(M_WAITOK) in interrupt context")); #ifdef DEBUG_MEMGUARD - /* XXX CHANGEME! */ - if (mtp == M_SUBPROC) + if (memguard_cmp(mtp)) return memguard_alloc(size, flags); #endif +#ifdef DEBUG_REDZONE + size = redzone_size_ntor(size); +#endif + if (size <= KMEM_ZMAX) { if (size & KMEM_ZMASK) size = (size & ~KMEM_ZMASK) + KMEM_ZBASE; @@ -338,6 +338,10 @@ malloc(unsigned long size, struct malloc memset(va, 0x70, osize); } #endif +#ifdef DEBUG_REDZONE + if (va != NULL) + va = redzone_setup(va, osize); +#endif return ((void *) va); } @@ -359,13 +363,17 @@ free(void *addr, struct malloc_type *mtp return; #ifdef DEBUG_MEMGUARD - /* XXX CHANGEME! */ - if (mtp == M_SUBPROC) { + if (memguard_cmp(mtp)) { memguard_free(addr); return; } #endif +#ifdef DEBUG_REDZONE + redzone_check(addr); + addr = redzone_addr_ntor(addr); +#endif + size = 0; slab = vtoslab((vm_offset_t)addr & (~UMA_SLAB_MASK)); @@ -423,13 +431,16 @@ realloc(void *addr, unsigned long size, */ #ifdef DEBUG_MEMGUARD -/* XXX: CHANGEME! */ -if (mtp == M_SUBPROC) { +if (memguard_cmp(mtp)) { slab = NULL; alloc = size; } else { #endif +#ifdef DEBUG_REDZONE + slab = NULL; + alloc = redzone_get_size(addr); +#else slab = vtoslab((vm_offset_t)addr & ~(UMA_SLAB_MASK)); /* Sanity check */ @@ -446,6 +457,7 @@ if (mtp == M_SUBPROC) { if (size <= alloc && (size > (alloc >> REALLOC_FRACTION) || alloc == MINALLOCSIZE)) return (addr); +#endif /* !DEBUG_REDZONE */ #ifdef DEBUG_MEMGUARD } @@ -549,7 +561,7 @@ kmeminit(void *dummy) * scenarios as they occur. It is only used for debugging. */ vm_memguard_divisor = 10; - TUNABLE_INT_FETCH("vm.memguard_divisor", &vm_memguard_divisor); + TUNABLE_INT_FETCH("vm.memguard.divisor", &vm_memguard_divisor); /* Pick a conservative value if provided value sucks. */ if ((vm_memguard_divisor <= 0) || @@ -610,6 +622,7 @@ malloc_uninit(void *data) struct malloc_type_internal *mtip; struct malloc_type_stats *mtsp; struct malloc_type *mtp, *temp; + uma_slab_t slab; long temp_allocs, temp_bytes; int i; @@ -646,7 +659,21 @@ malloc_uninit(void *data) temp_allocs, temp_bytes); } - uma_zfree(mt_zone, mtip); + slab = vtoslab((vm_offset_t) mtip & (~UMA_SLAB_MASK)); + uma_zfree_arg(mt_zone, mtip, slab); +} + +struct malloc_type * +malloc_desc2type(const char *desc) +{ + struct malloc_type *mtp; + + mtx_assert(&malloc_mtx, MA_OWNED); + for (mtp = kmemstatistics; mtp != NULL; mtp = mtp->ks_next) { + if (strcmp(mtp->ks_shortdesc, desc) == 0) + return (mtp); + } + return (NULL); } static int @@ -834,9 +861,66 @@ SYSCTL_PROC(_kern, OID_AUTO, malloc_stat 0, 0, sysctl_kern_malloc_stats, "s,malloc_type_ustats", "Return malloc types"); +static int +sysctl_kern_total_malloced(SYSCTL_HANDLER_ARGS) +{ + struct malloc_type_stats mts_local, *mtsp; + struct malloc_type_internal *mtip; + struct malloc_type *mtp; + int error; + int i; + unsigned long total_malloced = 0; + + mtx_lock(&malloc_mtx); + for (mtp = kmemstatistics; mtp != NULL; mtp = mtp->ks_next) { + mtip = mtp->ks_handle; + bzero(&mts_local, sizeof(mts_local)); + for (i = 0; i < MAXCPU; i++) { + mtsp = &mtip->mti_stats[i]; + mts_local.mts_memalloced += mtsp->mts_memalloced; + mts_local.mts_memfreed += mtsp->mts_memfreed; + mts_local.mts_numallocs += mtsp->mts_numallocs; + mts_local.mts_numfrees += mtsp->mts_numfrees; + mts_local.mts_size |= mtsp->mts_size; + } + if (mts_local.mts_numallocs == 0) + continue; + + /* + * Due to races in per-CPU statistics gather, it's possible to + * get a slightly negative number here. If we do, skip this + * type. + */ + if (mts_local.mts_memalloced > mts_local.mts_memfreed) + total_malloced += mts_local.mts_memalloced - + mts_local.mts_memfreed; + } + mtx_unlock(&malloc_mtx); + error = sysctl_handle_long(oidp, &total_malloced, 0, req); + return (error); +} + +SYSCTL_PROC(_kern, OID_AUTO, total_malloced, CTLFLAG_RD|CTLTYPE_ULONG, + 0, 0, sysctl_kern_total_malloced, "LU", + "Total memory malloced. Sum of memUsed column of kern.malloc"); + SYSCTL_INT(_kern, OID_AUTO, malloc_count, CTLFLAG_RD, &kmemcount, 0, "Count of kernel malloc types"); +static int +sysctl_kmem_cur_size(SYSCTL_HANDLER_ARGS) +{ + vm_size_t size = 0; + + vm_map_lock(kmem_map); + size = kmem_map->size; + vm_map_unlock(kmem_map); + return (sysctl_handle_long(oidp, &size, 0, req)); +} + +SYSCTL_PROC(_vm, OID_AUTO, kmem_allocated, CTLFLAG_RD|CTLTYPE_ULONG, + 0, 0, sysctl_kmem_cur_size, "LU", "Current kmem_map allocation size"); + #ifdef DDB DB_SHOW_COMMAND(malloc, db_show_malloc) {