diff options
Diffstat (limited to 'freebsd/sys/vm/uma_dbg.c')
-rw-r--r-- | freebsd/sys/vm/uma_dbg.c | 166 |
1 files changed, 39 insertions, 127 deletions
diff --git a/freebsd/sys/vm/uma_dbg.c b/freebsd/sys/vm/uma_dbg.c index 1506674f..0c6be82d 100644 --- a/freebsd/sys/vm/uma_dbg.c +++ b/freebsd/sys/vm/uma_dbg.c @@ -35,8 +35,11 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <rtems/bsd/local/opt_vm.h> + #include <rtems/bsd/sys/param.h> #include <sys/systm.h> +#include <sys/bitset.h> #include <sys/kernel.h> #include <sys/types.h> #include <sys/queue.h> @@ -50,28 +53,38 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> #include <vm/uma_int.h> #include <vm/uma_dbg.h> +#include <vm/memguard.h> -static const u_int32_t uma_junk = 0xdeadc0de; +static const uint32_t uma_junk = 0xdeadc0de; /* * Checks an item to make sure it hasn't been overwritten since it was freed, * prior to subsequent reallocation. * * Complies with standard ctor arg/return - * */ int trash_ctor(void *mem, int size, void *arg, int flags) { int cnt; - u_int32_t *p; + uint32_t *p; + +#ifdef DEBUG_MEMGUARD + if (is_memguard_addr(mem)) + return (0); +#endif cnt = size / sizeof(uma_junk); for (p = mem; cnt > 0; cnt--, p++) if (*p != uma_junk) { +#ifdef INVARIANTS + panic("Memory modified after free %p(%d) val=%x @ %p\n", + mem, size, *p, p); +#else printf("Memory modified after free %p(%d) val=%x @ %p\n", mem, size, *p, p); +#endif return (0); } return (0); @@ -87,7 +100,12 @@ void trash_dtor(void *mem, int size, void *arg) { int cnt; - u_int32_t *p; + uint32_t *p; + +#ifdef DEBUG_MEMGUARD + if (is_memguard_addr(mem)) + return; +#endif cnt = size / sizeof(uma_junk); @@ -124,9 +142,14 @@ int mtrash_ctor(void *mem, int size, void *arg, int flags) { struct malloc_type **ksp; - u_int32_t *p = mem; + uint32_t *p = mem; int cnt; +#ifdef DEBUG_MEMGUARD + if (is_memguard_addr(mem)) + return (0); +#endif + size -= sizeof(struct malloc_type *); ksp = (struct malloc_type **)mem; ksp += size / sizeof(struct malloc_type *); @@ -152,7 +175,12 @@ void mtrash_dtor(void *mem, int size, void *arg) { int cnt; - u_int32_t *p; + uint32_t *p; + +#ifdef DEBUG_MEMGUARD + if (is_memguard_addr(mem)) + return; +#endif size -= sizeof(struct malloc_type *); cnt = size / sizeof(uma_junk); @@ -172,6 +200,11 @@ mtrash_init(void *mem, int size, int flags) { struct malloc_type **ksp; +#ifdef DEBUG_MEMGUARD + if (is_memguard_addr(mem)) + return (0); +#endif + mtrash_dtor(mem, size, NULL); ksp = (struct malloc_type **)mem; @@ -192,124 +225,3 @@ mtrash_fini(void *mem, int size) { (void)mtrash_ctor(mem, size, NULL, 0); } - -static uma_slab_t -uma_dbg_getslab(uma_zone_t zone, void *item) -{ - uma_slab_t slab; - uma_keg_t keg; - u_int8_t *mem; - - mem = (u_int8_t *)((unsigned long)item & (~UMA_SLAB_MASK)); - if (zone->uz_flags & UMA_ZONE_VTOSLAB) { - slab = vtoslab((vm_offset_t)mem); - } else { - keg = LIST_FIRST(&zone->uz_kegs)->kl_keg; - if (keg->uk_flags & UMA_ZONE_HASH) - slab = hash_sfind(&keg->uk_hash, mem); - else - slab = (uma_slab_t)(mem + keg->uk_pgoff); - } - - return (slab); -} - -/* - * Set up the slab's freei data such that uma_dbg_free can function. - * - */ - -void -uma_dbg_alloc(uma_zone_t zone, uma_slab_t slab, void *item) -{ - uma_keg_t keg; - uma_slabrefcnt_t slabref; - int freei; - - if (slab == NULL) { - slab = uma_dbg_getslab(zone, item); - if (slab == NULL) - panic("uma: item %p did not belong to zone %s\n", - item, zone->uz_name); - } - keg = slab->us_keg; - - freei = ((unsigned long)item - (unsigned long)slab->us_data) - / keg->uk_rsize; - - if (keg->uk_flags & UMA_ZONE_REFCNT) { - slabref = (uma_slabrefcnt_t)slab; - slabref->us_freelist[freei].us_item = 255; - } else { - slab->us_freelist[freei].us_item = 255; - } - - return; -} - -/* - * Verifies freed addresses. Checks for alignment, valid slab membership - * and duplicate frees. - * - */ - -void -uma_dbg_free(uma_zone_t zone, uma_slab_t slab, void *item) -{ - uma_keg_t keg; - uma_slabrefcnt_t slabref; - int freei; - - if (slab == NULL) { - slab = uma_dbg_getslab(zone, item); - if (slab == NULL) - panic("uma: Freed item %p did not belong to zone %s\n", - item, zone->uz_name); - } - keg = slab->us_keg; - - freei = ((unsigned long)item - (unsigned long)slab->us_data) - / keg->uk_rsize; - - if (freei >= keg->uk_ipers) - panic("zone: %s(%p) slab %p freelist %d out of range 0-%d\n", - zone->uz_name, zone, slab, freei, keg->uk_ipers-1); - - if (((freei * keg->uk_rsize) + slab->us_data) != item) { - printf("zone: %s(%p) slab %p freed address %p unaligned.\n", - zone->uz_name, zone, slab, item); - panic("should be %p\n", - (freei * keg->uk_rsize) + slab->us_data); - } - - if (keg->uk_flags & UMA_ZONE_REFCNT) { - slabref = (uma_slabrefcnt_t)slab; - if (slabref->us_freelist[freei].us_item != 255) { - printf("Slab at %p, freei %d = %d.\n", - slab, freei, slabref->us_freelist[freei].us_item); - panic("Duplicate free of item %p from zone %p(%s)\n", - item, zone, zone->uz_name); - } - - /* - * When this is actually linked into the slab this will change. - * Until then the count of valid slabs will make sure we don't - * accidentally follow this and assume it's a valid index. - */ - slabref->us_freelist[freei].us_item = 0; - } else { - if (slab->us_freelist[freei].us_item != 255) { - printf("Slab at %p, freei %d = %d.\n", - slab, freei, slab->us_freelist[freei].us_item); - panic("Duplicate free of item %p from zone %p(%s)\n", - item, zone, zone->uz_name); - } - - /* - * When this is actually linked into the slab this will change. - * Until then the count of valid slabs will make sure we don't - * accidentally follow this and assume it's a valid index. - */ - slab->us_freelist[freei].us_item = 0; - } -} |