--- kernel/kern/zalloc.c 2018/04/24 18:26:07 1.1.1.1 +++ kernel/kern/zalloc.c 2018/04/24 18:32:12 1.1.1.2 @@ -84,9 +84,42 @@ #include #endif +#if DIAGNOSTIC +vm_offset_t zlowest = (vm_offset_t)(-1); +vm_offset_t zhighest = (vm_offset_t)0; +#define WATERMARK_ZONE(zone, element) \ +MACRO_BEGIN \ + if ((element) < (zone)->lowest) \ + (zone)->lowest = (element); \ + if ((element) < zlowest) \ + zlowest = (element); \ + if ((element) > (zone)->highest) \ + (zone)->highest = (element); \ + if ((element) > zhighest) \ + zhighest = (element); \ +MACRO_END +#else +#define WATERMARK_ZONE(zone, element) +#endif + +/* + * 1 - fill freed memory with 0xdeadface + * 2 - check_zone at zfree + * 4 - check_zone at zget + * 8 - check_zone at zalloc + * 10 - duplicate the free list pointer chain + */ +unsigned zone_check = 0; + +void *memset __P((void *, int , size_t)); + #define ADD_TO_ZONE(zone, element) \ MACRO_BEGIN \ vm_offset_t cur, *last; \ + if (zone_check & 1) \ + (void) memset((void *)(element), 0xdeadface, \ + (size_t) (zone)->elem_size); \ + WATERMARK_ZONE((zone), (element)); \ if ( (zone)->last_insert != 0 && \ (element) > (zone)->last_insert ) \ (vm_offset_t)last = (zone)->last_insert; \ @@ -96,6 +129,8 @@ MACRO_BEGIN \ (element) > cur ) \ (vm_offset_t)last = cur; \ *(vm_offset_t *)(element) = cur; \ + if (zone_check & 0x10) \ + *((vm_offset_t *)(element) + 1) = cur; \ *last = (element); \ (zone)->last_insert = (element); \ (zone)->count--; \ @@ -652,6 +687,10 @@ zone_t zinit(size, max, alloc, pageable, z->max_size = max; z->elem_size = size; +#if DIAGNOSTIC + z->lowest = (vm_offset_t)(-1); + z->highest = (vm_offset_t)0; +#endif z->alloc_size = alloc; z->pageable = pageable; z->zone_name = name; @@ -1394,6 +1433,29 @@ void zone_init(void) zone_map_size, FALSE); } +void +check_zone(zone, elem) + zone_t zone; + vm_offset_t elem; +{ + vm_offset_t this; + /* + * check the zone's consistency + */ +#if !DIAGNOSTIC + if (!elem) + return; +#endif + for (this = zone->free_elements; + this != 0; + this = * (vm_offset_t *) this) + if (this == elem) + panic("check_zone: argument already free"); +#if DIAGNOSTIC + else if (this < zone->lowest || this > zone->highest) + panic("check_zone: item out of range"); +#endif +} /* * zalloc returns an element from the specified zone. @@ -1409,6 +1471,8 @@ vm_offset_t zalloc_canblock(zone, canblo panic ("zalloc: null zone"); lock_zone(zone); + if (zone_check & 8) + check_zone(zone, 0); REMOVE_FROM_ZONE(zone, addr, vm_offset_t); while (addr == 0) { /* @@ -1473,6 +1537,8 @@ vm_offset_t zalloc_canblock(zone, canblo /* XXX check before doing this */ thread_wakeup((event_t)&zone->doing_alloc); + if (zone_check & 8) + check_zone(zone, 0); REMOVE_FROM_ZONE(zone, addr, vm_offset_t); } else { addr = zget_space( @@ -1488,6 +1554,7 @@ vm_offset_t zalloc_canblock(zone, canblo lock_zone(zone); zone->count++; zone->cur_size += zone->elem_size; + WATERMARK_ZONE(zone, addr); unlock_zone(zone); return(addr); } @@ -1527,30 +1594,26 @@ vm_offset_t zget(zone) panic ("zalloc: null zone"); lock_zone(zone); + if (zone_check & 4) + check_zone(zone, 0); REMOVE_FROM_ZONE(zone, addr, vm_offset_t); unlock_zone(zone); return(addr); } -boolean_t zone_check = FALSE; - -void zfree(zone, elem) +void +zfree(zone, elem) register zone_t zone; vm_offset_t elem; { lock_zone(zone); - if (zone_check) { - vm_offset_t this; - - /* check the zone's consistency */ - - for (this = zone->free_elements; - this != 0; - this = * (vm_offset_t *) this) - if (this == elem) - panic("zfree"); - } +#if DIAGNOSTIC + if (elem < zone->lowest || elem > zone->highest) + panic("zfree: argument out of range"); +#endif + if (zone_check & 2) + check_zone(zone, elem); ADD_TO_ZONE(zone, elem); unlock_zone(zone); }