Index: sys/kern/kern_kcov.c =================================================================== --- sys/kern/kern_kcov.c +++ sys/kern/kern_kcov.c @@ -59,7 +59,7 @@ #include #include -MALLOC_DEFINE(M_KCOV_INFO, "kcovinfo", "KCOV info type"); +MALLOC_DEFINE(M_KCOV, "kcov", "kcov memory"); #define KCOV_ELEMENT_SIZE sizeof(uint64_t) @@ -122,6 +122,7 @@ struct thread *thread; /* (l) */ vm_object_t bufobj; /* (o) */ vm_offset_t kvaddr; /* (o) */ + vm_page_t *m; /* (o) */ size_t entries; /* (o) */ size_t bufsize; /* (o) */ kcov_state_t state; /* (s) */ @@ -298,7 +299,7 @@ struct kcov_info *info; int error; - info = malloc(sizeof(struct kcov_info), M_KCOV_INFO, M_ZERO | M_WAITOK); + info = malloc(sizeof(struct kcov_info), M_KCOV, M_ZERO | M_WAITOK); info->state = KCOV_STATE_OPEN; info->thread = NULL; info->mode = -1; @@ -357,7 +358,6 @@ kcov_alloc(struct kcov_info *info, size_t entries) { size_t n, pages; - vm_page_t *m; KASSERT(info->kvaddr == 0, ("kcov_alloc: Already have a buffer")); KASSERT(info->state == KCOV_STATE_OPEN, @@ -376,16 +376,15 @@ info->bufobj = vm_pager_allocate(OBJT_PHYS, 0, info->bufsize, PROT_READ | PROT_WRITE, 0, curthread->td_ucred); - m = malloc(sizeof(*m) * pages, M_TEMP, M_WAITOK); + info->m = malloc(sizeof(*info->m) * pages, M_KCOV, M_WAITOK); VM_OBJECT_WLOCK(info->bufobj); for (n = 0; n < pages; n++) { - m[n] = vm_page_grab(info->bufobj, n, + info->m[n] = vm_page_grab(info->bufobj, n, VM_ALLOC_NOBUSY | VM_ALLOC_ZERO | VM_ALLOC_WIRED); - m[n]->valid = VM_PAGE_BITS_ALL; + info->m[n]->valid = VM_PAGE_BITS_ALL; } VM_OBJECT_WUNLOCK(info->bufobj); - pmap_qenter(info->kvaddr, m, pages); - free(m, M_TEMP); + pmap_qenter(info->kvaddr, info->m, pages); info->entries = entries; @@ -395,14 +394,25 @@ static void kcov_free(struct kcov_info *info) { + size_t i; if (info->kvaddr != 0) { pmap_qremove(info->kvaddr, info->bufsize / PAGE_SIZE); kva_free(info->kvaddr, info->bufsize); } - if (info->bufobj != NULL && !info->mmap) - vm_object_deallocate(info->bufobj); - free(info, M_KCOV_INFO); + if (info->bufobj != NULL) { + VM_OBJECT_WLOCK(info->bufobj); + for (i = 0; i < info->bufsize / PAGE_SIZE; i++) { + vm_page_lock(info->m[i]); + vm_page_unwire_noq(info->m[i]); + vm_page_unlock(info->m[i]); + } + VM_OBJECT_WUNLOCK(info->bufobj); + free(info->m, M_KCOV); + if (!info->mmap) + vm_object_deallocate(info->bufobj); + } + free(info, M_KCOV); } static int